#pragma once #include "aecdbentitybase.h" #include "AecDbObjXDataMap.h" #include "aecdbcamera.h" #include #ifdef EARTHWORM_EXPORT #define DLLIMPEXP __declspec(dllexport) #else #define DLLIMPEXP __declspec(dllimport) #endif class DLLIMPEXP AecDbJoggedCamera: public AecDbEntityBase { public: struct Camera { // 剖切线的起始点和终止点 AcGePoint3d m_ptStart; AcGePoint3d m_ptEnd; // 最大最小标高 double m_dMaxElev; double m_dMinElev; // 剖切方向,长度是剖切范围的宽度 AcGeVector3d m_vtDir; // 折线颜色 Adesk::Int16 m_iColor; // 结果对齐点 AcGePoint3d m_ptOutput; // 剖切结果 AcDbObjectIdArray m_arResults; AcGeVector3d getJoggedDir() const { return m_ptEnd - m_ptStart; } double getJoggedLength() const { return m_ptStart.distanceTo(m_ptEnd); } AcGePoint3d getMidPoint() const { return AcGePoint3d((m_ptEnd.x + m_ptStart.x) * .5 , (m_ptEnd.y + m_ptStart.y) * .5 , (m_ptEnd.z + m_ptStart.z) * .5 ); } void setElev(const double &dMax, const double &dMin) { m_dMaxElev = dMax; m_dMinElev = dMin; } void transformBy(const AcGeMatrix3d &mat) { m_ptStart.transformBy(mat); m_ptEnd.transformBy(mat); m_vtDir.transformBy(mat); } // 负责剖切运算,output点计算 AcGeVector3d getXDir() const { return m_vtDir.crossProduct(AcGeVector3d::kZAxis); } Camera(): m_ptStart(AcGePoint3d::kOrigin) , m_ptEnd(AcGePoint3d::kOrigin) , m_vtDir(AcGeVector3d::kIdentity) , m_dMaxElev(3000.0) , m_dMinElev(-3000.0) , m_iColor(-1) , m_ptOutput(AcGePoint3d::kOrigin) {} Camera(const AcGePoint3d &pt1 , const AcGePoint3d &pt2) : m_ptStart(pt1) , m_ptEnd(pt2) , m_vtDir(AcGeVector3d::kIdentity) , m_dMaxElev(3000.0) , m_dMinElev(-3000.0) , m_iColor(-1) , m_ptOutput(AcGePoint3d::kOrigin) { } static Adesk::UInt32 kCurrentVersionNumber; void getGripPoints(AcGePoint3dArray &ar) const; Acad::ErrorStatus dwgOutFields(AcDbDwgFiler *pFiler) const; Acad::ErrorStatus dwgInFields(AcDbDwgFiler *pFiler); void moveGripPointsAt(const int &idx, const AcGeVector3d &offset); AcDbPolyline *getSectionPolygon() const; void collectEntities(AcDbObjectIdArray &ar); void hlrCalc(); void moveOutput(const AcGeVector3d &vOffset); }; typedef std::vector Cameras; typedef AecDbXCamera::GripData GripData; public: ACRX_DECLARE_MEMBERS(AecDbJoggedCamera); public: AecDbJoggedCamera(); AecDbJoggedCamera(AecDbJoggedCamera *pSrc); virtual ~AecDbJoggedCamera(); public: virtual Acad::ErrorStatus copyFrom(const AcRxObject *pSrc); virtual void subList() const; virtual Acad::ErrorStatus subTransformBy(const AcGeMatrix3d &xform); virtual Acad::ErrorStatus subGetGripPoints(AcDbGripDataPtrArray &grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d &curViewDir, const int bitflags) const; virtual Acad::ErrorStatus subMoveGripPointsAt(const AcDbVoidPtrArray &appData, const AcGeVector3d &offset, const int bitflags); virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler *pFiler); virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler *pFiler) const; Acad::ErrorStatus subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d &pickPoint, const AcGePoint3d &lastPoint, const AcGeMatrix3d &viewXform, AcGePoint3dArray &snapPoints, AcDbIntArray &geomIds) const; virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents& extents) const; virtual Acad::ErrorStatus Draw2d(AcGiDraw &dc) const; virtual Acad::ErrorStatus Draw3d(AcGiDraw &dc) const; void DrawElev(AcGiDraw &dc, const Camera &camera, const int &iClr) const; virtual AecDbObjXDataMap* GetSpecialtyData(AcDb::OpenMode bMode = AcDb::kForWrite); virtual const AecDbObjXDataMap* GetSpecialtyData() const; public: bool addCamera(const AcGePoint3d &pt1 , const AcGePoint3d &pt2 , const AcGeVector3d &vt ); void delCamera(const int &idx); AcGePoint3d getLastPoint() const; AcGeVector3d getSectionDir() const; AcGeVector3d getJoggedDir() const; const Camera* getCamera(const int &idx) const; int getCameraCount() const { return static_cast(m_cameras.size()); } // 通过折线外一点,来设置折线的剖切方向和范围 // 如果ptOut在折线上,方向不变,范围按照1000.处理 void setCameraWidth(const int &idx, const AcGePoint3d &ptOut); void setCameraHeight(const int &idx, const double &dMax, const double &dMin); bool judgeSegmentCanInsert(const AcGePoint3d &pt1, const AcGePoint3d &pt2, AcGePoint3d &ptClosed) const; // 设置结果对齐点 void setOutputPoint(const AcGePoint3d &pt); static AcGePoint3d getClosestPoint(const AcGePoint3d &ptOn, const AcGeVector3d &vt, const AcGePoint3d &ptOut); static AcGePoint3d getClosestPoint(const AcGePoint3d &ptOn1, const AcGePoint3d &ptOn2, const AcGePoint3d &ptOut); void refresh(); bool isSameSectionDir() const { assertReadEnabled(); return m_bSameSectionDir; } bool isForcedParallel() const { assertReadEnabled(); return m_bForcedParallel; } private: // 当折线剖切的结果对齐点改变后,每个折线的对齐点刷新 void refreshOutputPoint(); void getGripPoints(const bool &bHori, AcDbGripDataPtrArray &grips) const; bool getResultBox(AcGePoint3dArray &ar) const; // 得到实体选择中时的虚线框 void getVirtualLine(const bool &bHori) const; // 移动剖切结果 void moveOutput(const AcGeVector3d &vtOffset); // 判断第idx个camera是否和其他camera有重合,一般使用在moveGripPointsAt()内部 bool isOverlappingCamera(const int &idx) const; protected: static Adesk::UInt32 kCurrentVersionNumber; public: virtual bool GetProperties(SimpleProperty::PropertySetByIndex &properties) const; virtual bool SetProperties(SimpleProperty::PropertySetByName &properties); private: // 每一个Camera都定义了一个剖切区域,它们们一起组成了一个折线剖切面 // 每一个Camera的起点和终点都构成折线的上一条子折线 // 相邻两条子折线A与B,A的终点与B的起点的连线与这些线段方向垂直 Cameras m_cameras; AecDbObjXDataMap m_mapSpecXData; // 剖切结果对齐点 AcGePoint3d m_ptOutput; // 剖切线是否统一方向? 默认为否,剖切方向可以不一致 bool m_bSameSectionDir; // 剖切线之间是否强制平行? 默认为否,不需要平 bool m_bForcedParallel; mutable AcArray m_GripDatas; }; class DLLIMPEXP CJoggedCameraJig: public AcEdJig { public: CJoggedCameraJig(AecDbJoggedCamera *pJogged) : m_nStep(0) , m_pJogged(pJogged) { if (pJogged) { m_vtEye = pJogged->getSectionDir(); m_numOfSeg = pJogged->getCameraCount(); } } virtual ~CJoggedCameraJig() { DELETE_PTR(m_pPolyline); } AcEdJig::DragStatus DoIt(); public: virtual AcEdJig::DragStatus sampler(); virtual AcDbEntity *entity() const; virtual Adesk::Boolean update(); private: void deleteSupportLine(); public: AcGePoint3d m_ptStart, m_ptEnd; AcGeVector3d m_vtEye; AcDbPolyline *m_pPolyline; int m_nStep; // 0-起点 1-终点 2-范围 int m_numOfSeg; // 辅助直线id AcDbObjectId m_supportLineID; AecDbJoggedCamera *m_pJogged; };