#include "stdafx.h" #include "AecDbTerrain.h" #include "_cgal.h" namespace { double calcAverageZ(const Geometry::GePoint3dArray &pts) { double dElev(.0); for (size_t i(0); i < pts.size(); ++i) dElev += pts[i].z; dElev /= pts.size(); return dElev; } } Adesk::UInt32 AecDbTerrain::kCurrentVersionNumber = 1; ACRX_DXF_DEFINE_MEMBERS (AecDbTerrain, AecDbEntityBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning, AEC_DBTERRAIN, "AecDbTerrain" "|Product Desc: shanghua earthworm app obj" "|Company: shanghua inc" "|WEB Address: www.shanghuasoft.com") AecDbTerrain::AecDbTerrain(void): m_iSmoothLevel(0) , m_points(0) , m_outer(0) , m_holes(0) { m_mapSpecXData.SetAt(KEY_NAME, _T("上华地形")); } AecDbTerrain::~AecDbTerrain(void) { } Acad::ErrorStatus AecDbTerrain::dwgInFields(AcDbDwgFiler* pFiler) { AssertWriteEnabled(); //----- Read parent class information first. Acad::ErrorStatus es = Acad::eOk; 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 > AecDbTerrain::kCurrentVersionNumber) return Acad::eMakeMeProxy; AcGePoint3d pt(AcGePoint3d::kOrigin); Adesk::UInt64 count(0), subCount(0); pFiler->readUInt64(&count); m_points.clear(); for (Adesk::UInt64 i(0); i < count; ++i) { if (pFiler->readPoint3d(&pt) == Acad::eOk) m_points.push_back(pt); } Geometry::GePoint3dArray ar; count = 0; pFiler->readUInt64(&count); m_holes.clear(); for (Adesk::UInt64 i(0); i < count; ++i) { ar.clear(); pFiler->readUInt64(&subCount); for (Adesk::UInt64 j(0); j < subCount; ++j) { if (pFiler->readPoint3d(&pt) == Acad::eOk) ar.push_back(pt); } if (!ar.empty()) m_holes.push_back(ar); } count = 0; m_outer.clear(); pFiler->readUInt64(&count); for (Adesk::UInt64 i(0); i < count; ++i) { if (pFiler->readPoint3d(&pt) == Acad::eOk) m_outer.push_back(pt); } Adesk::Int32 iSm; pFiler->readInt32(&iSm); m_iSmoothLevel = iSm; m_dElev = calcAverageZ(m_points); return Acad::eOk; } Acad::ErrorStatus AecDbTerrain::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); //----- Save parent class information first. Acad::ErrorStatus es = Acad::eOk; es = AecDbEntityBase::dwgOutFields(pFiler); if (es != Acad::eOk) return (es); //----- Object version number needs to be saved first if ((es = pFiler->writeUInt32(AecDbTerrain::kCurrentVersionNumber)) != Acad::eOk) return (es); pFiler->writeUInt64(m_points.size()); for (size_t i(0); i < m_points.size(); ++i) { pFiler->writePoint3d(m_points[i]); } pFiler->writeUInt64(m_holes.size()); for (size_t i(0); i < m_holes.size(); ++i) { pFiler->writeUInt64(m_holes[i].size()); for (size_t j(0); j < m_holes[i].size(); ++j) { pFiler->writePoint3d(m_holes[i][j]); } } pFiler->writeUInt64(m_outer.size()); for (size_t i(0); i < m_outer.size(); ++i) { pFiler->writePoint3d(m_outer[i]); } pFiler->writeInt32(m_iSmoothLevel); return es; } Acad::ErrorStatus AecDbTerrain::dxfInFields(AcDbDxfFiler* pFiler) { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDbTerrain::dxfOutFields(AcDbDxfFiler* pFiler) const { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDbTerrain::subExplode(AcDbVoidPtrArray& entitySet) const { return Acad::eOk; } void AecDbTerrain::subList() const {} Acad::ErrorStatus AecDbTerrain::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); AcDbVoidPtrArray ar = Get3DBuffer(); for (int i(0); i < ar.length(); ++i) { AcDbEntity *pEnt = AcDbEntity::cast((AcDbObject*)ar[i]); if (pEnt) { AcDbSubDMesh *pMesh = AcDbSubDMesh::cast(pEnt); if (pMesh) pMesh->getGripPoints(gripPoints, osnapModes, geomIds); } } return Acad::eOk; } Acad::ErrorStatus AecDbTerrain::subGetGripPoints(AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDbTerrain::subMoveGripPointsAt(const AcDbVoidPtrArray& appData, const AcGeVector3d& offset, const int bitflags) { return Acad::eOk; } void AecDbTerrain::GetGripText(int nPos, CString& sText) { return; } Acad::ErrorStatus AecDbTerrain::subIntersectWith(const AcDbEntity* pEnt, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDbTerrain::subIntersectWith(const AcDbEntity* pEnt, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDbTerrain::Draw2d(AcGiDraw &dc) const { return Draw3d(dc); } Acad::ErrorStatus AecDbTerrain::Draw3d(AcGiDraw &dc) const { assertReadEnabled(); if (Has3DBuffer()) { Draw3DBuffers(dc); return Acad::eOk; } // 没有外轮廓,说明不是区域地形 Geometry::GePolyArray3d holes; if (m_outer.empty()) { if (!m_holes.empty()) { // 先取出外轮廓 Geometry::GePoint3dArray arOuter; Geometry::calcConvexHull2D(m_points, arOuter); holes.assign(m_holes.begin(), m_holes.end()); holes.push_back(arOuter); } } else { holes.assign(m_holes.begin(), m_holes.end()); holes.push_back(m_outer); } AcGePoint3dArray vertexArray; AcArray faceArray; Geometry::delaunayTriangulationMeshWithHolds(m_points, holes, vertexArray, faceArray); AcDbSubDMesh *pMesh = new AcDbSubDMesh(); Acad::ErrorStatus es; if ((es = pMesh->setSubDMesh(vertexArray, faceArray, m_iSmoothLevel)) != Acad::eOk) { acutPrintf(_T("\n设置平滑度%d失败,按照0级平滑度生成。"), m_iSmoothLevel); pMesh->setSubDMesh(vertexArray, faceArray, 0); DELETE_PTR(pMesh); return es; } pMesh->setTransparency(transparency()); dc.DrawEntity(pMesh); Add3DBuffer(pMesh); return Acad::eOk; } SHJson::WValue& AecDbTerrain::ToJson(bool bExprotGeo) const { assertReadEnabled(); return AecDbEntityBase::ToJson(bExprotGeo); } bool AecDbTerrain::ByJson(const SHJson::WValue &v) { AssertWriteEnabled(); return AecDbEntityBase::ByJson(v); } AecDbObjXDataMap* AecDbTerrain::GetSpecialtyData(AcDb::OpenMode bMode) { if (bMode == AcDb::kForWrite) AssertWriteEnabled(); else assertReadEnabled(); return &m_mapSpecXData; } const AecDbObjXDataMap* AecDbTerrain::GetSpecialtyData() const { assertReadEnabled(); return &m_mapSpecXData; } int AecDbTerrain::GetDraw2dables(Adesk::UInt16 nDrawStyle, AcDbVoidPtrArray &arEntPtrs) const { assertReadEnabled(); return GetDraw3dables(arEntPtrs, false); } int AecDbTerrain::GetDraw3dables(AcDbVoidPtrArray &arEntPtrs, bool bWriteBimInfo) const { assertReadEnabled(); AcDbEntity *pEnt = NULL, *pEntClone = NULL; AcDb3dSolid *pSolidAll = NULL; AcDb3dSolid *pSolid = NULL; const AcDbVoidPtrArray &ar3D = Get3DBuffer(); for (int i = 0; i < ar3D.length(); i++) { pEnt = (AcDbEntity *)ar3D.at(i); pEntClone = (AcDbEntity *)pEnt->clone(); if (pEntClone != NULL) { pEntClone->setColorIndex(pEnt->colorIndex()); pEntClone->setLayer(layerId()); pEntClone->setLinetype(linetypeId()); arEntPtrs.append(pEntClone); } } return arEntPtrs.length(); } void AecDbTerrain::setPoints(const AcGePoint3dArray &ar) { AssertWriteEnabled(); m_points.clear(); for (int i(0); i < ar.length(); ++i) { m_points.push_back(ar[i]); } m_dElev = calcAverageZ(m_points); } void AecDbTerrain::setPoints(const Geometry::GePoint3dArray &ar) { AssertWriteEnabled(); m_points.clear(); m_points.assign(ar.begin(), ar.end()); m_dElev = calcAverageZ(m_points); } void AecDbTerrain::setOuter(const Geometry::GePoint3dArray &outer) { AssertWriteEnabled(); m_outer.clear(); m_outer.assign(outer.begin(), outer.end()); } void AecDbTerrain::addHold(std::vector &poly) { AssertWriteEnabled(); if (!poly.empty()) m_holes.push_back(poly); } bool AecDbTerrain::clearHolds() { AssertWriteEnabled(); m_holes.clear(); return m_holes.empty(); } bool AecDbTerrain::deleteHold(const AcGePoint3d &ptInHold) { AssertWriteEnabled(); AcGePoint2d pt(ptInHold.x, ptInHold.y); Geometry::GePwh2d pwh; pwh.inner_holes.clear(); Geometry::GePolyArray3d::iterator it(m_holes.begin()); for (; it != m_holes.end(); ++it) { pwh.outer_boundary.vertexs.clear(); for (size_t j(0); j < it->size(); ++j) { pwh.outer_boundary.vertexs.push_back(AcGePoint2d(it->at(j).x , it->at(j).y)); } if (Geometry::boundary_check(pt, pwh) == Geometry::eInside) { m_holes.erase(it); return true; } } return false; } double AecDbTerrain::getElev() { return m_dElev; } void AecDbTerrain::setSmoothLevel(int i) { AssertWriteEnabled(); m_iSmoothLevel = i; } int AecDbTerrain::getSmoothLevel() { return m_iSmoothLevel; }