#include "stdafx.h" #include "AecDbInsulation.h" #include "CoreTools.h" #include "KTSetting.h" #include "MFCDbDwgFiler.h" #include "dbgrip.h" #include "AecGripCback.h" static const Adesk::UInt16 kRed = 1; static const Adesk::UInt16 kYellow = 2; static const Adesk::UInt16 kGreen = 3; static const Adesk::UInt16 kCyan = 4; static const Adesk::UInt16 kBlue = 5; static const Adesk::UInt16 kMagenta = 6; static const Adesk::UInt16 kWhite = 7; const Adesk::UInt16 kColorByLayer = 256; extern AcDbArc *FormatArc(const AcGePoint3d &ptGe1, const AcGePoint3d &ptGe2, const AcGePoint3d &ptGe3); extern AcGePoint3d GetArcMidPoint(AcDbArc *pArc); static void FreeBuffer(int n, AcDbVoidPtrArray &arEntPtrs) { AcDbEntity *pEnt = NULL; while (arEntPtrs.length() > n) { pEnt = (AcDbEntity *)arEntPtrs.last(); if (pEnt != NULL) { pEnt->erase(); pEnt->close(); arEntPtrs.removeLast(); delete pEnt; } } } Adesk::UInt32 AecDbInsulation::kCurrentVersionNumber = 1; ACRX_DXF_DEFINE_MEMBERS(AecDbInsulation, AecDbEntityBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning, AEC_DBINSUL, "AecDbInsulation" "|Product Desc: shanghua earthworm app obj" "|Company: shanghua inc" "|WEB Address: www.shanghuasoft.com") AecDbInsulation::AecDbInsulation() { m_dwFileLength = 0; m_pszTxt = NULL; m_pGripAppData = new AecGripData[10]; } AecDbInsulation::~AecDbInsulation() { delete[] m_pGripAppData; } static bool GetSurfaceArcMidPt(AcGePoint3d& ptG, AcDbVoidPtrArray& arEntPtrs) { AcDbEntity *pEnt = NULL; for (int i = 0;i < arEntPtrs.length();i++) { pEnt = (AcDbEntity *)arEntPtrs.at(i); AcDbArc *pArc = AcDbArc::cast(pEnt); if (pArc != NULL) { ptG = GetArcMidPoint(pArc); return true; } } return false; } void AecDbInsulation::SetInsulation(const InsulData &data) { AssertWriteEnabled(); bool bUpdate = false; InsulData dataL; if ( (bUpdate = GetInsulation(dataL))) { bUpdate = true; } m_mapSpecXData.SetAt(KEY_THICK, data.dThick); m_mapSpecXData.SetAt(KEY_LTT, data.szLnStyle); m_mapSpecXData.SetAt(KEY_SPEC,data.szInsSpec); //调整2D 偏移 if (bUpdate) { double dOff = data.dThick - dataL.dThick; bool bIsLineWall = false; if (!m_drawable2d.GetRefEdage().isEmpty()) { AecEqui::AecCurveElement el = m_drawable2d.GetRefEdage().at(0); if (el.ptGe[1].distanceTo(el.ptGe[2]) < 1.e-3) { bIsLineWall = true; } } if (bIsLineWall) { AcDbRegion *pReg = GetInsulRegion(); if (pReg != NULL) { double dArea = 0; AcGePlane plan; AcGePoint3d ptCen; CoreTools::getRegionInfo(pReg, ptCen, dArea, plan); AcGeVector3d vtNm = plan.normal(); vtNm.normalize(); AcGePoint3d ptS, ptE, ptE2; ptS = ptCen; ptE = ptS + dataL.dThick * vtNm; //直墙保温层方向校正ptE if (bIsLineWall && !m_drawable2d.GetRefEdage().isEmpty()) { AecEqui::AecCurveElement el = m_drawable2d.GetRefEdage().at(0); AcDbLine ln1(el.ptGe[0], el.ptGe[2]); ln1.getClosestPointTo(ptE, ptE2, Adesk::kTrue); ptE.z = ptE2.z; if (ptE.distanceTo(ptE2) > 1.e-3) { vtNm.negate();//指向 vtNm.normalize(); vtNm *= dOff; AcGeMatrix3d xm; xm.setToTranslation(vtNm); m_drawable2d.transformBy(xm); } } } } else { double dR = 0; for (int i = 0;i < m_drawable2d.GetRefEdage().length();i++) { AecEqui::AecCurveElement &el = m_drawable2d.GetRefEdage().atByRef(i); //合成弧 AcDbArc *pArc = FormatArc(el.ptGe[0], el.ptGe[1], el.ptGe[2]); if (pArc != NULL) { AcDbSurface *pFace = GetInsulSurface(); if (pFace != NULL) { AcDbVoidPtrArray arEntPtrs; pFace->explode(arEntPtrs); if (!arEntPtrs.isEmpty()) { AcGePoint3d ptG; GetSurfaceArcMidPt(ptG, arEntPtrs); AcGePoint3d ptC = pArc->center(); ptG.z = ptC.z; AcGePoint3d ptOn; pArc->getClosestPointTo(ptG, ptOn, Adesk::kFalse); AcGeVector3d vt = ptG - ptOn; AcGeVector3d vt2 = ptOn - ptC; vt.normalize(); vt2.normalize(); if (vt.dotProduct(vt2) > 1.e-6) //向内 { dR = pArc->radius() - dOff; pArc->setRadius(dR); pArc->getStartPoint(el.ptGe[0]); pArc->getEndPoint(el.ptGe[2]); el.ptGe[1] = GetArcMidPoint(pArc); } else //向外 { dR = pArc->radius() + dOff; pArc->setRadius(dR); pArc->getStartPoint(el.ptGe[0]); pArc->getEndPoint(el.ptGe[2]); el.ptGe[1] = GetArcMidPoint(pArc); } FreeBuffer(0,arEntPtrs); } delete pFace; //pFace->setColorIndex(1); //CoreTools::AddToModelSpace(pFace); } } } } } } bool AecDbInsulation::GetInsulation(InsulData &data) const { assertReadEnabled(); if (!m_mapSpecXData.GetAt(KEY_THICK, data.dThick)) return false; m_mapSpecXData.GetAt(KEY_LTT, data.szLnStyle); m_mapSpecXData.GetAt(KEY_SPEC, data.szInsSpec); return true; } double AecDbInsulation::GetInsulArea() const { assertReadEnabled(); double dA = 0.0; m_mapSpecXData.GetAt(KEY_A, dA); return dA; } void AecDbInsulation::SetInsulRegion(AcDbEntity *pRegnOrSurface) { AssertWriteEnabled(); //if (m_pszTxt != NULL) // delete[] m_pszTxt; //m_pszTxt = NULL; AcDbRegion *pRegion = AcDbRegion::cast(pRegnOrSurface); if (pRegion != NULL) { AcGePoint3d ptC; double dA = 0.0; AcGePlane pLan; CoreTools::getRegionInfo(pRegion, ptC, dA, pLan); //折算为平方 struct resbuf rb; acedGetVar(_T("INSUNITS"), &rb); if (rb.resval.rint == AcDb::kUnitsMeters)//米单位 { } else if (rb.resval.rint == AcDb::kUnitsMillimeters)//毫米单位 { dA *= 1.e-6; } m_mapSpecXData.SetAt(KEY_A, dA); m_dwFileLength = CoreTools::RegionToString(pRegion, m_pszTxt); } AcDbSurface *pFace = AcDbSurface::cast(pRegnOrSurface); if (pFace != NULL) { double dA = 0.0; pFace->getArea(dA); //折算为平方 struct resbuf rb; acedGetVar(_T("INSUNITS"), &rb); if (rb.resval.rint == AcDb::kUnitsMeters)//米单位 { } else if (rb.resval.rint == AcDb::kUnitsMillimeters)//毫米单位 { dA *= 1.e-6; } m_mapSpecXData.SetAt(KEY_A, dA); AcDbBody *pBody = new AcDbBody; Acad::ErrorStatus es; #if ARX > 18 es = pBody->setASMBody(pFace->getLockedASMBody()); #else es = pBody->setBody(pFace->body()); #endif m_dwFileLength = CoreTools::BodyToString(pBody, m_pszTxt); } } AcDbRegion * AecDbInsulation::GetInsulRegion() const { assertReadEnabled(); if (m_dwFileLength == 0 || m_pszTxt == NULL) return NULL; AcDbRegion *pRegion = CoreTools::StringToRegion(m_dwFileLength,m_pszTxt); return pRegion; } AcDbSurface *AecDbInsulation::GetInsulSurface() const { assertReadEnabled(); if (m_dwFileLength == 0 || m_pszTxt == NULL) return NULL; AcDbSurface *pFace = CoreTools::StringToFace(m_dwFileLength, m_pszTxt); return pFace; } //2D工艺视图 void AecDbInsulation::GetDraw2dables(AecComplexCurve &draw2d) const { assertReadEnabled(); if (m_drawable2d.HasEdage()) draw2d.append(m_drawable2d.GetRefEdage()); } void AecDbInsulation::SetDraw2dables(const AecComplexCurve &draw2d) { AssertWriteEnabled(); m_drawable2d.RemoveEdage(); m_drawable2d.SetEdage(draw2d); } bool AecDbInsulation::GetStartPoint(AcGePoint3d &pt) const { assertReadEnabled(); if (m_drawable2d.HasEdage()) { pt = m_drawable2d.GetRefEdage().first().ptGe[0]; return true; } return false; } void AecDbInsulation::SetStartPointO(const AcGePoint3d &pt) { AssertWriteEnabled(); if (m_drawable2d.HasEdage()) { AcGePoint3d &_pt = m_drawable2d.GetRefEdage().atByRef(0).ptGe[0]; _pt = pt; } } bool AecDbInsulation::GetEndPoint(AcGePoint3d &pt) const { assertReadEnabled(); if (m_drawable2d.HasEdage()) { pt = m_drawable2d.GetRefEdage().last().ptGe[2]; return true; } return false; } void AecDbInsulation::SetEndPoint(const AcGePoint3d &pt) { AssertWriteEnabled(); if (m_drawable2d.HasEdage()) { AcGePoint3d &_pt = m_drawable2d.GetRefEdage().atByRef(m_drawable2d.GetRefEdage().length() - 1).ptGe[2]; _pt = pt; } } Acad::ErrorStatus AecDbInsulation::subGetGripPoints(AcDbGripDataPtrArray &grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d &curViewDir, const int bitflags) const { assertReadEnabled(); if (m_drawable2d.HasEdage()) { const AecComplexCurve &cmpl = m_drawable2d.GetRefEdage(); if (!cmpl.isEmpty()) { const AecEqui::AecCurveElement &el0 = cmpl.first(); const AecEqui::AecCurveElement &el1 = cmpl.last(); AcGePoint3dArray arPts; arPts.append(el0.ptGe[0]); arPts.append(el1.ptGe[2]); AcDbGripData *pGripData = NULL; for (int i = 0;i < 2;i++) { memset(&m_pGripAppData[i], 0, sizeof(AecGripData)); m_pGripAppData[i].nIndex = i; m_pGripAppData[i].ePos = i > 0 ? eEnd : eStart; m_pGripAppData[i].nColor = kGreen + i; m_pGripAppData[i].ptGrip = arPts.at(i); m_pGripAppData[i].pOwner = (AcDbEntity *)this; AcDbGripData *pGripData = NULL; pGripData = new AcDbGripData; pGripData->setGripPoint(arPts.at(i)); pGripData->setAppData((void *)&m_pGripAppData[i]); pGripData->setWorldDraw(AecGripCback::WorldDrawfunc); pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc); _tcscpy(m_pGripAppData[i].szTip, _T("")); _tcscpy(m_pGripAppData[i].szID, _T("")); grips.append(pGripData); } return Acad::eOk; } } return Acad::eOk; } Acad::ErrorStatus AecDbInsulation::copyFrom(const AcRxObject *pSrc) { AssertWriteEnabled(); AecDbEntityBase::copyFrom(pSrc); AecDbInsulation *pInsulSrc = AecDbInsulation::cast(pSrc); if (pInsulSrc != NULL) { if (m_pszTxt != NULL) delete[] m_pszTxt; m_dwFileLength = pInsulSrc->m_dwFileLength; m_pszTxt = new char[m_dwFileLength]; strcpy(m_pszTxt, pInsulSrc->m_pszTxt); m_mapSpecXData.CopyFrom(&pInsulSrc->m_mapSpecXData); m_drawable2d.RemoveEdage(); m_drawable2d.copyFrom(pInsulSrc->m_drawable2d); } return Acad::eOk; } Acad::ErrorStatus AecDbInsulation::subMoveGripPointsAt(const AcDbVoidPtrArray &appData, const AcGeVector3d &offset, const int bitflags) { AssertWriteEnabled(); AecGripData *pAppData = NULL; if (appData.isEmpty()) { return Acad::eOk; } if (!m_drawable2d.HasEdage()) { return Acad::eOk; } AcGeMatrix3d xform; xform.setToTranslation(offset); subTransformBy(xform); return Acad::eOk; } Acad::ErrorStatus AecDbInsulation::subTransformBy(const AcGeMatrix3d &xform) { AssertWriteEnabled(); AcDbRegion *pReg = GetInsulRegion(); if (pReg != NULL) { pReg->transformBy(xform); SetInsulRegion(pReg); delete pReg; } AcDbSurface *pFace = GetInsulSurface(); if (pFace != NULL) { pFace->transformBy(xform); SetInsulRegion(pFace); delete pFace; } m_drawable2d.transformBy(xform); return Acad::eOk; } Acad::ErrorStatus AecDbInsulation::dwgInFields(AcDbDwgFiler *pFiler) { AssertWriteEnabled(); //----- Read parent class information first. Acad::ErrorStatus es = Acad::eOk; if (!pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbEntityBase::dwgInFields(pFiler); if (es != Acad::eOk) return (es); } //----- Object version number needs to be read first Adesk::UInt32 version = 0; if ((es = pFiler->readUInt32(&version)) != Acad::eOk) return (es); if (version > AecDbInsulation::kCurrentVersionNumber) return (Acad::eMakeMeProxy); m_dwFileLength = 0; if (m_pszTxt != NULL) delete[] m_pszTxt; m_pszTxt = NULL; pFiler->readUInt64(&m_dwFileLength); if (m_dwFileLength > 0) { m_pszTxt = new char[m_dwFileLength]; pFiler->readBytes(m_pszTxt, m_dwFileLength); } //2D m_drawable2d.dwgInFields(pFiler); m_mapSpecXData.dwgInFields(pFiler); return (pFiler->filerStatus()); } Acad::ErrorStatus AecDbInsulation::dwgOutFields(AcDbDwgFiler *pFiler) const { assertReadEnabled(); //----- Save parent class information first. Acad::ErrorStatus es = Acad::eOk; if (!pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbEntityBase::dwgOutFields(pFiler); if (es != Acad::eOk) return (es); } //----- Object version number needs to be saved first if ((es = pFiler->writeUInt32(AecDbInsulation::kCurrentVersionNumber)) != Acad::eOk) return (es); pFiler->writeUInt64(m_dwFileLength); if (m_dwFileLength > 0) pFiler->writeBytes(m_pszTxt, m_dwFileLength); //2D m_drawable2d.dwgOutFields(pFiler); m_mapSpecXData.dwgOutFields(pFiler); return (pFiler->filerStatus()); } Acad::ErrorStatus AecDbInsulation::dxfInFields(AcDbDxfFiler *pFiler) { return Acad::eOk; } Acad::ErrorStatus AecDbInsulation::dxfOutFields(AcDbDxfFiler *pFiler) const { return Acad::eOk; } void AecDbInsulation::subList() const { AecDbEntityBase::subList(); InsulData data; memset(&data, 0, sizeof(InsulData)); GetInsulation(data); acutPrintf(_T("\n保温层")); acutPrintf(_T("\n保温层厚:%.1f 毫米"),data.dThick); acutPrintf(_T("\n保温面积(平方):%.1f"), GetInsulArea()); acutPrintf(_T("\n保温层描述:%s"),data.szInsSpec); } bool AecDbInsulation::GetBimInfoTip(CString &sInfoTip) const { assertReadEnabled(); InsulData data; memset(&data, 0, sizeof(InsulData)); GetInsulation(data); CString sField, sFmt; sField = _T("保温层:\n"); sInfoTip += sField; MAKEFIELD(_T("保温层厚"), _T("%.1f 毫米"), data.dThick, sInfoTip); MAKEFIELD(_T("保温面积(平方)"), _T("%.1f 毫米"), GetInsulArea(), sInfoTip); MAKEFIELD(_T("保温层描述"), _T("%s"), data.szInsSpec, sInfoTip); return true; } Acad::ErrorStatus AecDbInsulation::Draw2d(AcGiDraw &dc) const { assertReadEnabled(); //管线系统屏蔽掉 if (dc.IsDragging()) { //return Acad::eOk; } AcDbObjectId idCurLay = dc.GetLayerId(); AcDbObjectId idCurLty = dc.GetLineTypeId(); Adesk::UInt16 nCrBk = dc.GetColor(); dc.SetLayer(layerId()); int nColor = 6;// kColorByLayer; GetAt(_T("COLOR"), nColor); dc.SetColor(nColor); AcDbObjectId idLt = linetypeId(); //二维缓存,未知出错! if (Has2DBuffer()) { AcDbEntity *pEnt = NULL; const AcDbVoidPtrArray &ar2D = Get2DBuffer(); for (int i = 0; i < ar2D.length(); i++) { pEnt = (AcDbEntity *)ar2D.at(i); pEnt->setLayer(layerId()); pEnt->setColorIndex(nColor); dc.DrawEntity(*pEnt); } dc.SetColor(nCrBk); dc.SetLayer(idLt); dc.SetLineType(idCurLty); return Acad::eOk; } dc.SetLineType(idLt); AecComplexCurveDraw draw2d; draw2d.copyFrom(m_drawable2d); draw2d.SetColor(nColor); draw2d.Draw2d(dc, layerId(), layerId(), layerId(), NULL, TRUE); AcDbVoidPtrArray arPtrs; draw2d.explode(arPtrs, layerId(), layerId(), layerId(), NULL, TRUE); Add2DBuffer(arPtrs); dc.SetColor(nCrBk); dc.SetLayer(idCurLay); dc.SetLineType(idCurLty); return Acad::eOk; } Acad::ErrorStatus AecDbInsulation::Draw3d(AcGiDraw &dc) const { assertReadEnabled(); //管线系统屏蔽掉 if (dc.IsDragging()) { return Acad::eOk; } //图层 AcDbObjectId idLay = dc.GetLayerId(); dc.SetLayer(layerId()); Adesk::UInt16 nCrBk = dc.GetColor(); int nColor = 256; GetAt(_T("COLOR"), nColor); dc.SetColor(nColor); if (Has3DBuffer()) { AcDbEntity *pEnt = NULL; const AcDbVoidPtrArray &ar3D = Get3DBuffer(); for (int i = 0; i < ar3D.length(); i++) { pEnt = (AcDbEntity *)ar3D.at(i); dc.DrawEntity(*pEnt); } dc.SetLayer(idLay); dc.SetColor(nCrBk); return Acad::eOk; } AcCmTransparency tr = transparency(); AcDb3dSolid *pSolidDraw = GetDraw3dSolid(); if (pSolidDraw != NULL) { pSolidDraw->setTransparency(tr); pSolidDraw->setLayer(layerId()); pSolidDraw->setColorIndex(colorIndex()); dc.DrawEntity(pSolidDraw); Add3DBuffer(pSolidDraw); } dc.SetLayer(idLay); dc.SetColor(nCrBk); return Acad::eOk; } const AecDbObjXDataMap *AecDbInsulation::GetSpecialtyData() const { assertReadEnabled(); return &m_mapSpecXData; } AecDbObjXDataMap *AecDbInsulation::GetSpecialtyData(AcDb::OpenMode bMode /*= AcDb::kForWrite*/) { switch (bMode) { case AcDb::kForRead: { assertReadEnabled(); break; } case AcDb::kForWrite: { if (!isWriteEnabled()) { upgradeOpen(); } assertWriteEnabled(); break; } case AcDb::kForNotify: { if (!isWriteEnabled()) { upgradeOpen(); } } default: break; } return &m_mapSpecXData; } AcDb3dSolid * AecDbInsulation::GetInsulThickSolid(double dThick,AcDbRegion * pReg,bool bIsLineWall) const { double dArea = 0; AcGePlane plan; AcGePoint3d ptCen; CoreTools::getRegionInfo(pReg, ptCen, dArea, plan); AcGeVector3d vtNm = plan.normal(); vtNm.normalize(); AcGePoint3d ptS, ptE,ptE2; ptS = ptCen; ptE = ptS + dThick * vtNm; //直墙保温层方向校正ptE if (bIsLineWall && !m_drawable2d.GetRefEdage().isEmpty() ) { AecEqui::AecCurveElement el = m_drawable2d.GetRefEdage().at(0); AcDbLine ln1(el.ptGe[0],el.ptGe[2]); ln1.getClosestPointTo(ptE, ptE2, Adesk::kTrue); ptE.z = ptE2.z; if (ptE.distanceTo(ptE2) > 1.e-3) { vtNm.negate(); ptE = ptS + dThick * vtNm; } } AcDbLine ln(ptS, ptE); AcDb3dSolid * pSolid = new AcDb3dSolid; Acad::ErrorStatus es = pSolid->extrudeAlongPath(pReg, &ln); DELETE_PTR(pReg); if (es != Acad::eOk) { acutPrintf(_T("\nextrude error:%d"), es); DELETE_PTR(pSolid); return NULL; } return pSolid; } AcDb3dSolid * AecDbInsulation::GetDraw3dSolid() const { InsulData data; memset(&data, 0, sizeof(InsulData)); if (!GetInsulation(data)) return NULL; bool bIsLineWall = false; if (!m_drawable2d.GetRefEdage().isEmpty()) { AecEqui::AecCurveElement el = m_drawable2d.GetRefEdage().at(0); if (el.ptGe[1].distanceTo(el.ptGe[2]) < 1.e-3) { bIsLineWall = true; } } AcDb3dSolid *pSolidAll = NULL; AcDbRegion *pReg = GetInsulRegion(); if (pReg != NULL) { pSolidAll = GetInsulThickSolid(data.dThick,pReg, bIsLineWall); if (pSolidAll != NULL) return pSolidAll; } AcDbSurface *pFace = GetInsulSurface(); if (pFace != NULL) { AcArray arRegs; Acad::ErrorStatus es = pFace->convertToRegion(arRegs); if (arRegs.isEmpty()) { pFace->thicken(data.dThick, false, pSolidAll); } AcDb3dSolid *pSolid = NULL; for (int i = 0; i < arRegs.length(); i++) { pReg = AcDbRegion::cast(arRegs.at(i)); if (pReg != NULL) { pSolid = GetInsulThickSolid(data.dThick,pReg, bIsLineWall); } if (pSolidAll == NULL) { pSolidAll = pSolid; } else { pSolidAll->booleanOper(AcDb::kBoolUnite, pSolid); } } DELETE_PTR(pFace); } return pSolidAll; }