#include "stdafx.h" #include "AecDbLandForm.h" #include "MFCDbDwgFiler.h" #include "dbgrip.h" #include "AecGripCback.h" #include "_cgal.h" #include "EarThwormDef.h" static const Adesk::UInt16 kColorByBlock = 0; 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; static const Adesk::UInt16 kColorByLayer = 256; static const Adesk::UInt16 kGold = 30; static const Adesk::UInt16 kPurple = 200; static const Adesk::UInt16 kMagenta2 = 210; extern bool DLLIMPEXP FaceIntersectWithLine(AcDbFace* pFace, AcDbLine* pLine,AcGePoint3d& resultPoint,bool bExtLine/* = false*/); 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_PTR(pEnt); } } } Adesk::UInt32 AecDbLandForm::kCurrentVersionNumber = 1; ACRX_DXF_DEFINE_MEMBERS(AecDbLandForm, AecDbEntityBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning, AEC_LANDFORM, "AecDbLandForm" "|Product Desc: shanghua earthworm app obj" "|Company: shanghua inc" "|WEB Address: www.shanghuasoft.com") AecDbLandForm::AecDbLandForm(void) { m_pGripAppData = new AecGripData[GRIP_MAXNUM]; m_mapSpecXData.SetAt(KEY_NAME,_T("地形")); } AecDbLandForm::~AecDbLandForm(void) { } void AecDbLandForm::SetPoints(const AcGePoint3dArray& arPts) { AssertWriteEnabled(); m_arPts.append(arPts); } bool AecDbLandForm::GetPoints(AcGePoint3dArray& arPts) const { assertReadEnabled(); arPts.append(m_arPts); return true; } bool AecDbLandForm::IsPointInSide(const AcGePoint3d& ptHit,AcGePoint3d& ptOn) { assertReadEnabled(); const AcDbVoidPtrArray& arFaces = Get2DBuffer(); AcGePoint3d ptE = ptHit + AcGeVector3d::kZAxis * 100.0; AcDbLine ln(ptHit,ptE); AcDbEntity* pEnt = NULL; for (int i = 0;i < arFaces.length();i++) { pEnt = (AcDbEntity*)arFaces.at(i); AcDbFace* pFace = AcDbFace::cast(pEnt); if (pFace != NULL) { if (FaceIntersectWithLine(pFace,&ln,ptOn,true)) { return true; } } } return false; } void AecDbLandForm::subList() const { assertReadEnabled(); acutPrintf(_T("\n地形")); AcGePoint3d ptGe; for (int i = 0;i < m_arPts.length();i++) { ptGe = m_arPts.at(i); acutPrintf(_T("\n地形界点:(%g,%g,%g)"),ptGe.x,ptGe.y,ptGe.z); } m_mapSpecXData.List(); } Acad::ErrorStatus AecDbLandForm::subGetGripPoints(AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const { assertReadEnabled(); for (int i = 0;i < m_arPts.length();i++) { AcDbGripData* pGripData = new AcDbGripData; memset(&m_pGripAppData[i],0,sizeof(AecGripData)); m_pGripAppData[i].nIndex = i; m_pGripAppData[i].ePos = eStart; m_pGripAppData[i].nColor = kBlue; m_pGripAppData[i].ptGrip = m_arPts.at(i); _tcscpy(m_pGripAppData[i].szTip,_T("地形界点")); m_pGripAppData[i].pOwner = (AcDbEntity*)this; m_pGripAppData[i].idHost = objectId(); pGripData->setGripPoint(m_arPts.at(i)); pGripData->setAppData((void*)&m_pGripAppData[i]); pGripData->setWorldDraw(AecGripCback::WorldDrawfunc); pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc); grips.append(pGripData); } return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::copyFrom(const AcRxObject* pSrc) { AssertWriteEnabled(); AecDbLandForm* pFit = AecDbLandForm::cast(pSrc); if (pFit != NULL) { m_mapSpecXData.Empty(); m_mapSpecXData.CopyFrom(&pFit->m_mapSpecXData); m_arPts.removeAll(); m_arPts.append(pFit->m_arPts); } return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::subMoveGripPointsAt(const AcDbVoidPtrArray& appData,const AcGeVector3d& offset,const int bitflags) { AssertWriteEnabled(); AecGripData* pAppData = NULL; AcDbIntArray arIndex; if ( !appData.isEmpty() ) { pAppData = (AecGripData*)appData.first(); arIndex.append(pAppData->nIndex); } else { return Acad::eOk; } int nGripIndex = arIndex.first(); if (nGripIndex > -1 && nGripIndex < m_arPts.length()) { AcGePoint3d ptGe = m_arPts.at(nGripIndex); ptGe += offset; m_arPts.setAt(nGripIndex,ptGe); } return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::subTransformBy(const AcGeMatrix3d& xform) { AssertWriteEnabled(); AcGePoint3d ptGe; for(int i = 0;i < m_arPts.length();i++) { ptGe = m_arPts.at(i); ptGe.transformBy(xform); m_arPts.setAt(i,ptGe); } return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { assertReadEnabled(); AcDbEntity* pSubEnt = NULL; if (Has2DBuffer()) { const AcDbVoidPtrArray &ar2D = Get2DBuffer(); for (int i = 0;i < ar2D.length();i++) { pSubEnt = (AcDbEntity*)ar2D.at(i); pSubEnt->getOsnapPoints(osnapMode,gsSelectionMark,pickPoint,lastPoint,viewXform,snapPoints,geomIds); } } AcDbLine ln; AcGePoint3d ptGe; for (int i = 0;i < m_arPts.length() - 1;i++) { ln.setStartPoint(m_arPts.at(i)); ln.setEndPoint(m_arPts.at(i+1)); ln.getOsnapPoints(osnapMode,gsSelectionMark,pickPoint,lastPoint,viewXform,snapPoints,geomIds); } return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::subGetGeomExtents(AcDbExtents& extents) const { assertReadEnabled(); for (int i = 0;i < m_arPts.length();i++) { extents.addPoint(m_arPts.at(i)); } return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::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 > AecDbLandForm::kCurrentVersionNumber ) return (Acad::eMakeMeProxy); AcGePoint3d ptGe; Adesk::Int32 nLen = 0; pFiler->readInt32(&nLen); m_arPts.removeAll(); for (int i = 0;i < nLen;i++) { pFiler->readPoint3d(&ptGe); m_arPts.append(ptGe); } m_mapSpecXData.dwgInFields(pFiler); return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::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 (AecDbLandForm::kCurrentVersionNumber)) != Acad::eOk ) return (es) ; Adesk::Int32 nLen = m_arPts.length(); pFiler->writeInt32(nLen); AcGePoint3d ptGe; for (int i = 0;i < m_arPts.length();i++) { ptGe = m_arPts.at(i); pFiler->writePoint3d(ptGe); } m_mapSpecXData.dwgOutFields(pFiler); return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::dxfInFields(AcDbDxfFiler* pFiler) { return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::dxfOutFields(AcDbDxfFiler* pFiler) const { return Acad::eOk; } static CString getTrait(const double &x, const double &y) { CString str(_T("")); str.Format(_T("%.4f-%.4f"), x, y); return str; } static double getZ(const std::map &traits , const double &x , const double &y) { std::map::const_iterator it = traits.find(getTrait(x, y)); if (it != traits.end()) return it->second; return .0; } Acad::ErrorStatus AecDbLandForm::Draw2d(AcGiDraw &dc) const { assertReadEnabled(); //管线系统屏蔽掉 if ( dc.IsDragging() ) { //return Acad::eOk; } //图层 AcDbObjectId idLay = dc.GetLayerId(); dc.SetLayer(layerId()); int nCrBk = dc.GetColor(); int nColor = nCrBk; if ( m_mapSpecXData.GetAt(_T("COLOR"),nColor) ) { dc.SetColor(nColor); } if (Has2DBuffer()) { AcDbEntity* pEnt = NULL; const AcDbVoidPtrArray &ar2D = Get2DBuffer(); for (int i = 0;i < ar2D.length();i++) { pEnt = (AcDbEntity*)ar2D.at(i); dc.DrawEntity(*pEnt); } dc.SetLayer(idLay); dc.SetColor(nCrBk); return Acad::eOk; } AcGeLineSeg3d ln; for(int i = 0;i < m_arPts.length()-1;i++) { ln.set(m_arPts.at(i),m_arPts.at(i+1)); dc.DrawLine(ln); } ln.set(m_arPts.first(),m_arPts.last()); dc.DrawLine(ln); return Acad::eOk; } Acad::ErrorStatus AecDbLandForm::Draw3d(AcGiDraw &dc) const { assertReadEnabled(); //管线系统屏蔽掉 if ( dc.IsDragging() ) { //return Acad::eOk; } //图层 AcDbObjectId idLay = dc.GetLayerId(); dc.SetLayer(layerId()); int nCrBk = dc.GetColor(); int nColor = nCrBk; if ( m_mapSpecXData.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; } AcDbLine* pLn = NULL; AcDbVoidPtrArray arLnPtrs,arRegPtrs; for (int i = 0;i < m_arPts.length() - 1;i++) { pLn = new AcDbLine(m_arPts.at(i),m_arPts.at(i+1)); arLnPtrs.append(pLn); } pLn = new AcDbLine(m_arPts.first(),m_arPts.last()); arLnPtrs.append(pLn); AcDbRegion::createFromCurves(arLnPtrs,arRegPtrs); FreeBuffer(0,arLnPtrs); if (!arRegPtrs.isEmpty()) { AcDbRegion* pReg = (AcDbRegion*)arRegPtrs.first(); if (pReg != NULL) { //贴图草地 pReg->setColorIndex(kGreen); pReg->setTransparency(transparency()); dc.DrawEntity(pReg); Add3DBuffer(pReg); } } else { //三角化 Geometry::GePoint3dArray arPt3Ds(0); Geometry::GePoint2dArray arPt2Ds(0); for (int i = 0;i < m_arPts.length();i++) { arPt3Ds.push_back(m_arPts.at(i)); } std::map zCache; for (size_t i = 0; i < arPt3Ds.size(); ++i) { AcGePoint3d &pt(arPt3Ds[i]); zCache.insert(std::make_pair(getTrait(pt.x, pt.y), pt.z)); arPt2Ds.push_back(AcGePoint2d(pt.x, pt.y)); } AcGePoint3dArray vertexArray; AcArray faceArray; Geometry::delaunayTriangulationMesh(arPt3Ds, vertexArray, faceArray); AcDbSubDMesh *pSubDMesh = new AcDbSubDMesh; pSubDMesh->setLayer(layerId()); pSubDMesh->setSubDMesh(vertexArray, faceArray, 0); //贴图草地 pSubDMesh->setColorIndex(kGreen); pSubDMesh->setTransparency(transparency()); dc.DrawEntity(pSubDMesh); Add3DBuffer(pSubDMesh); } return Acad::eOk; } const AecDbObjXDataMap* AecDbLandForm::GetSpecialtyData() const { assertReadEnabled(); return &m_mapSpecXData; } AecDbObjXDataMap* AecDbLandForm::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; }