// DbFloorRect.cpp: implementation of the TDbFloorRect class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" extern TARCH_IMPEXP int g_nProductId; #define STRU_FLOORRECT 0x01 // 结构专业的楼层框 ACRX_DXF_DEFINE_MEMBERS(ATSFloorRect, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_FLOORRECT, "ATS_FLOORRECT图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbFloorRect); const Adesk::UInt8 TDbFloorRect::g_nVersion = 1; TDbFloorRect::TDbFloorRect() { m_dLength = 0; // 长 m_dWidth = 0; // 宽 m_dFloorHeight = 3000; // 楼层高度 m_sFloorName = _T("1层");// 楼层名词 m_nFloorFrom = 1; // 楼层起始层 m_nFloorTo = 1; // 楼层终止层 // sg add 120106,默认不是结构专业的楼层框 SetStruFloorRect(FALSE); } void TDbFloorRect::CopyPropertiesFrom(AcDbEntity *pSrc,unsigned gMatchFlag) { assertWriteEnabled(); TDbEntity::CopyPropertiesFrom(pSrc, gMatchFlag); } Acad::ErrorStatus TDbFloorRect::subGetClassID(CLSID* pClsid) const { return Acad::eOk; } // 从DWG读入数据: Acad::ErrorStatus TDbFloorRect::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbEntity::dwgInFields(pFiler); if (es != Acad::eOk) { return es; } Adesk::UInt8 nVer; pFiler->readItem(&nVer); ReadString(pFiler, m_sFloorName); ReadString(pFiler, m_sSpare); pFiler->readItem(&m_nFloorFrom); pFiler->readItem(&m_nFloorTo); pFiler->readItem(&m_dLength); pFiler->readItem(&m_dWidth); pFiler->readItem(&m_dFloorHeight); pFiler->readItem(&m_bShow); pFiler->readItem(&m_nSpare); pFiler->readItem((AcGePoint3d *)&m_ptBase); pFiler->readItem((AcGePoint3d *)&m_ptCenter); return pFiler->filerStatus(); } Acad::ErrorStatus TDbFloorRect::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler); if (es != Acad::eOk) { return es; } pFiler->writeItem(g_nVersion); pFiler->writeItem((const TCHAR *)m_sFloorName); pFiler->writeItem((const TCHAR *)m_sSpare); pFiler->writeItem(m_nFloorFrom); pFiler->writeItem(m_nFloorTo); pFiler->writeItem(m_dLength); pFiler->writeItem(m_dWidth); pFiler->writeItem(m_dFloorHeight); pFiler->writeItem(m_bShow); pFiler->writeItem(m_nSpare); pFiler->writeItem((const AcGePoint3d &)m_ptBase); pFiler->writeItem((const AcGePoint3d &)m_ptCenter); return pFiler->filerStatus(); } Acad::ErrorStatus TDbFloorRect::dxfInFields(AcDbDxfFiler* pFiler) { // change by hh 2012-12-24 // assertWriteEnabled(); // Acad::ErrorStatus es = Acad::eOk; // es = TDbEntity::dxfInFields(pFiler); // return es; assertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; if(Acad::eOk != (es = AcDbObject::dxfInFields(pFiler))) { return pFiler->filerStatus(); } if(!pFiler->atSubclassData(this->desc()->name())) { return Acad::eMakeMeProxy; } struct resbuf rb; // version pFiler->readItem(&rb); if(AcDb::kDxfInt16 != rb.restype) { return Acad::eBadDxfSequence; } Adesk::Int16 nVer = rb.resval.rint; // Floor name pFiler->readItem(&rb); if(1 != rb.restype) { return Acad::eBadDxfSequence; } CString sFloorName = rb.resval.rstring; // center point pFiler->readItem(&rb); if(1 != rb.restype) { return Acad::eBadDxfSequence; } CString sPtCent = rb.resval.rstring; // base point pFiler->readItem(&rb); if(1 != rb.restype) { return Acad::eBadDxfSequence; } CString sPtBase = rb.resval.rstring; return pFiler->filerStatus(); } Acad::ErrorStatus TDbFloorRect::dxfOutFields(AcDbDxfFiler* pFiler) const { // change by hh 2012-12-24 // Acad::ErrorStatus es = Acad::eOk; // es = TDbEntity::dxfOutFields(pFiler); // return es; assertReadEnabled(); Acad::ErrorStatus es = Acad::eOk; if(Acad::eOk != (es = TDbEntity::dxfOutFields(pFiler))) { return es; } // class name pFiler->writeItem(AcDb::kDxfSubclass, this->desc()->name()); // version pFiler->writeInt16(AcDb::kDxfInt16, g_nVersion); // Floor name pFiler->writeItem(1, m_sFloorName); // Key points CString sPtCent, sPtBase; sPtCent.Format(_T("%.f,%.f,%.f"), m_ptCenter.x, m_ptCenter.y, m_ptCenter.z); sPtBase.Format(_T("%.f,%.f,%.f"), m_ptBase.x, m_ptBase.y, m_ptBase.z); pFiler->writeItem(1, (LPCTSTR)sPtCent); pFiler->writeItem(1, (LPCTSTR)sPtBase); return pFiler->filerStatus(); } // sg delete 100211,增加了数据库反映器,可处理楼层号重复的问题,因此可支持deepclone // 禁止拷贝 /* Acad::ErrorStatus TDbFloorRect::subDeepClone(AcDbObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary) const { pClonedObject = NULL; return Acad::eOk; } */ Acad::ErrorStatus TDbFloorRect::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; snapPoints.append(m_ptBase); return es; } Acad::ErrorStatus TDbFloorRect::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { gripPoints.append(m_ptBase); gripPoints.append(m_ptCenter); gripPoints.append(GetLowLeft()); gripPoints.append(GetLowRight()); gripPoints.append(GetUpRight()); gripPoints.append(GetUpLeft()); // sg add 100119,增加文字位置点为夹点 gripPoints.append(CalTextPt()); return Acad::eOk; } // sg add 100119,增加夹点说明 Acad::ErrorStatus TDbFloorRect::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; case 3: cs = _T("对角拉伸"); break; case 4: cs = _T("对角拉伸"); break; case 5: cs = _T("对角拉伸"); break; case 6: cs = _T("移动文字位置"); break; default: break; } return es; } // 功能: 夹点操作 Acad::ErrorStatus TDbFloorRect::subMoveStretchPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); if (indices.length()) { XPoint &vtOffset = *(XPoint *)&offset; // XVector3D vtEcs = Wcs2Ecs(vtOffset, m_vtNormal, TRUE); m_ptCenter += vtOffset; } return Acad::eOk; } // 功能: 夹点操作 Acad::ErrorStatus TDbFloorRect::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); XPoint &vtOffset = *(XPoint *)&offset; AcGeMatrix3d mat; mat.setToTranslation(offset); int idx = 0; for (int i = 0; i < indices.length(); i++) { idx = indices[i]; switch(idx) { case 0: // 移动楼层基点 { m_ptBase.TransformBy(mat); } break; // stretch begin point case 1: // 移动楼层框位置 { m_ptCenter.TransformBy(mat); } break; // stretch begin point case 2: // Move LowLeft { XPoint ptLowLeft = GetLowLeft(); XPoint ptUpRight = GetUpRight(); ptLowLeft += vtOffset; ptLowLeft.z = ptUpRight.z; XLine ln(ptUpRight, m_nLayoutRotation); XPoint ptPrj; ptLowLeft.Project(&ln, ptPrj); m_dLength = ptPrj.Distance2d(ptUpRight); m_dWidth = ptPrj.Distance2d(ptLowLeft); Midpoint(ptUpRight, ptLowLeft, m_ptCenter); } break; case 3: // Move LowRight { XPoint ptLowRight = GetLowRight(); XPoint ptUpLeft = GetUpLeft(); ptLowRight += vtOffset; ptLowRight.z = ptUpLeft.z; XLine ln(ptUpLeft, m_nLayoutRotation); XPoint ptPrj; ptLowRight.Project(&ln, ptPrj); m_dLength = ptPrj.Distance2d(ptUpLeft); m_dWidth = ptPrj.Distance2d(ptLowRight); Midpoint(ptLowRight, ptUpLeft, m_ptCenter); } break; case 4: // Move UpRight { XPoint ptUpRight = GetUpRight(); XPoint ptLowLeft = GetLowLeft(); ptUpRight += vtOffset; ptUpRight.z = ptLowLeft.z; XLine ln(ptLowLeft, m_nLayoutRotation); XPoint ptPrj; ptUpRight.Project(&ln, ptPrj); m_dLength = ptPrj.Distance2d(ptLowLeft); m_dWidth = ptPrj.Distance2d(ptUpRight); Midpoint(ptUpRight, ptLowLeft, m_ptCenter); } break; case 5: // Move UpLeft { XPoint ptUpLeft = GetUpLeft(); XPoint ptLowRight = GetLowRight(); ptUpLeft += vtOffset; ptUpLeft.z = ptUpLeft.z; XLine ln(ptLowRight, m_nLayoutRotation); XPoint ptPrj; ptUpLeft.Project(&ln, ptPrj); m_dLength = ptPrj.Distance2d(ptLowRight); m_dWidth = ptPrj.Distance2d(ptUpLeft); Midpoint(ptLowRight, ptUpLeft, m_ptCenter); } break; // sg add 100119,增加文字位置点 case 6: { XPoint ptText = CalTextPt(); // 获取真实文字位置点 ptText.TransformBy(mat); XPoint ptLowLeft = GetLowLeft(), // 左下角点 ptLowRight = GetLowRight(), // 右下角点 ptUpLeft = GetUpLeft(); // 左上角点 AcDbLine xAxisLine(ptLowLeft.AsAcGePoint3d(), ptLowRight.AsAcGePoint3d()), yAxisLine(ptLowLeft.AsAcGePoint3d(), ptUpLeft.AsAcGePoint3d()); AcGePoint3d ptPrj1, ptPrj2; // 投影点 xAxisLine.getClosestPointTo(ptText.AsAcGePoint3d(), ptPrj1, Adesk::kTrue); yAxisLine.getClosestPointTo(ptText.AsAcGePoint3d(), ptPrj2, Adesk::kTrue); double dX(0.0), dY(0.0); // 新文字位置点距离左下角点距离 xAxisLine.getDistAtPoint(ptPrj1, dX); yAxisLine.getDistAtPoint(ptPrj2, dY); SetTextPt(XPoint(dX, dY, 0), false); } break; default: break; } } return Acad::eOk; } Acad::ErrorStatus TDbFloorRect::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); TDbEntity::subTransformBy(xform); m_ptBase.TransformBy(xform); m_ptCenter.TransformBy(xform); return Acad::eOk; } // 取得四个角点 XPoint TDbFloorRect::GetLowLeft() const { double nAng = atan(m_dWidth/m_dLength); double nLen = sqrt(m_dWidth*m_dWidth + m_dLength*m_dLength); XPoint ptLowLeft; ads_polar(m_ptCenter, m_nLayoutRotation+PI+nAng, nLen/2.0, ptLowLeft); return ptLowLeft; } XPoint TDbFloorRect::GetLowRight() const { double nAng = atan(m_dWidth/m_dLength); double nLen = sqrt(m_dWidth*m_dWidth + m_dLength*m_dLength); XPoint ptLowRight; ads_polar(m_ptCenter, m_nLayoutRotation-nAng, nLen/2.0, ptLowRight); return ptLowRight; } XPoint TDbFloorRect::GetUpRight() const { double nAng = atan(m_dWidth/m_dLength); double nLen = sqrt(m_dWidth*m_dWidth + m_dLength*m_dLength); XPoint ptUpRight; ads_polar(m_ptCenter, m_nLayoutRotation+nAng, nLen/2.0, ptUpRight); return ptUpRight; } XPoint TDbFloorRect::GetUpLeft() const { double nAng = atan(m_dWidth/m_dLength); double nLen = sqrt(m_dWidth*m_dWidth + m_dLength*m_dLength); XPoint ptUpLeft; ads_polar(m_ptCenter, m_nLayoutRotation+PI-nAng, nLen/2.0, ptUpLeft); return ptUpLeft; } // sg add 100119,根据传入的左下角点、以及文字位置点相对坐标,计算文字位置实际坐标 XPoint TDbFloorRect::CalTextPt() const { XPoint ptText = GetTextPt(false), // 获得考虑出图比例后的相对坐标 ptLowLeft = GetLowLeft(); // 获得左下角点坐标 double dAng = PI/2; // ptText相对ptLowLeft方向 if (fabs(ptText.x) < 1.0E-3) // X坐标为0 { if (ptText.y < -1.0E-3) // Y坐标小于0 { dAng = -PI/2; } } else // X坐标不为0 { dAng = atan(ptText.y/ptText.x); // 角度范围在(-PI/2, PI/2)之内 if (ptText.x < -1.0E-3) // 解决角度在(PI/2, 3*PI/2)之内的问题 { dAng += PI; } } double dLen = sqrt(ptText.x*ptText.x + ptText.y*ptText.y); ads_polar(ptLowLeft, m_nLayoutRotation+dAng, dLen, ptText); ptText.z = 0; return ptText; } void TDbFloorRect::GetPolyline(AcDbPolyline &pline) const { pline.reset(Adesk::kFalse, 0); pline.setElevation(0.0); pline.addVertexAt(0, GetLowLeft().AsAcGePoint2d()); pline.addVertexAt(1, GetLowRight().AsAcGePoint2d()); pline.addVertexAt(2, GetUpRight().AsAcGePoint2d()); pline.addVertexAt(3, GetUpLeft().AsAcGePoint2d()); pline.setClosed(Adesk::kTrue); } Acad::ErrorStatus TDbFloorRect::ExplodeOrDraw2d(XExplodeDraw &dc) const { // 获得矩形框4个角点坐标 XPoint ptLowLeft = GetLowLeft(); // 左下 XPoint ptLowRight = GetLowRight(); XPoint ptUpRight = GetUpRight(); XPoint ptUpLeft = GetUpLeft(); // sg modify 100125,根据8.5需求,建筑专业:增加全局控制是否显示楼层框;水、电专业:根据对象内的变量控制 BOOL bShow = g_bShowFloorRect; //LH 2013-3-25 根据2014年加密需要水关键字8--14 暖6--15 电3--16 //if (g_nProductId==8 || g_nProductId==3) if (g_nProductId==kTWT || g_nProductId==kTELEC) { bShow = m_bShow; } // if (m_bShow) if (bShow) { ptLowLeft.z = ptLowRight.z = ptUpRight.z = ptUpLeft.z = 0; // 楼层框 XPoly2D poly2d(1); poly2d.AppendNode(ptLowLeft); poly2d.AppendNode(ptLowRight); poly2d.AppendNode(ptUpRight); poly2d.AppendNode(ptUpLeft); dc << poly2d; // 标注文字 TDbText text; text.setPropertiesFrom(this); // sg modify 100119,根据8.5新需求修改 /* text.SetStyleId(InitTextStyle(TS_STANDARD)); text.SetText(m_sFloorName); text.SetLocation(m_ptCenter); text.SetHeight(20); text.SetAlignment(XExplodeDraw::kMiddleCenter); */ text.SetStyleId(GetTextStyleId()); // 文字样式 text.SetHeight(GetTextHeight()); // 字高 text.SetLocation(CalTextPt()); // 文字位置点 text.setColorIndex(GetTextColor()); // 文字颜色 text.SetAlignment(XExplodeDraw::kBottomLeft); // 对齐方式:左下角点 CString csText; // 文字内容 if (IsStruFloorRect()) // 结构专业的楼层框,根据需求,希望显示的是标准层 { csText.Format(_T("标准层号:%s"), m_sFloorName); } else // 其他专业显示层号和层高 { if (fabs(m_dFloorHeight) <= 1e-15 ) { csText.Format(_T("层号:%s"), m_sFloorName); } else { csText.Format(_T("层号:%s 层高:%.0f"), m_sFloorName, m_dFloorHeight); } } text.SetText(csText); TPushProperty vProp(&text, dc); if (dc.IsFullExplode()) { text.ExplodeOrDraw2d(dc); } else { dc.DrawEntity(text); } } // sg add 100119,获取楼层基点表示方式 int nType = GetBaseType(); switch(nType) { case 1: // X型 { // sg modify 100125,根据8.5需求,建筑专业:增加全局控制是否显示楼层框;TWT专业:根据对象内的变量控制 // if (m_bShow) // 受控显示 if (bShow) { XPoint pt1, pt2; double dLen = GetCrossLen() * 0.5; // 叉线长度一半 ads_polar(m_ptBase, m_nLayoutRotation+PI/4, dLen, pt1); ads_polar(m_ptBase, m_nLayoutRotation+PI*1.25, dLen, pt2); dc << XLine(pt1, pt2); ads_polar(m_ptBase, m_nLayoutRotation-PI/4, dLen, pt1); ads_polar(m_ptBase, m_nLayoutRotation+PI*0.75, dLen, pt2); dc << XLine(pt1, pt2); } } break; case 2: // 点,始终绘制,受点样式控制 { AcDbPoint ptEnt; ptEnt.setPosition(m_ptBase); dc.DrawEntity(ptEnt); } break; default: break; } return Acad::eOk; } Acad::ErrorStatus TDbFloorRect::ExplodeOrDraw3d(XExplodeDraw &dc) const { return Acad::eOk; } void TDbFloorRect::GetTips(DList &info) const { info.Append(new TObjInfoUnit(_T("对象类型"), _T("楼层框"))); // sg modify 100119,根据8.5新需求修改 // info.Append(new TObjInfoUnit(_T("楼层名称"), m_sFloorName)); info.Append(new TObjInfoUnit(_T("工程名称"), m_sSpare)); info.Append(new TObjInfoUnit(_T("层号"), m_sFloorName)); info.Append(new TObjInfoUnit(_T("层高"), Dist2Str(m_dFloorHeight))); } // sg add 100118,增加8.5新需求需要的动态数据 // 文字位置 XPoint TDbFloorRect::GetTextPt(bool bAsPaperUnit) const { assertReadEnabled(); AcGePoint3d ptText(5, 5, 0); const TEntityFields &fd = GetFields(); fd.GFD(_T("文字相对位置"), ptText); if (!bAsPaperUnit) { ptText *= GetPScale(); } return XPoint(ptText); } void TDbFloorRect::SetTextPt(const XPoint &pt, bool bAsPaperUnit) { assertWriteEnabled(); AcGePoint3d ptText = pt.AsAcGePoint3d(); if (!bAsPaperUnit) { ptText /= GetPScale(); } TEntityFields &fd = Fields(); fd.SFD(_T("文字相对位置"), ptText); } // 文字字高,修改备用数据m_nSpare double TDbFloorRect::GetTextHeight(bool bAsPaperUnit) const { assertReadEnabled(); double dTextHeight = m_nSpare; if (!bAsPaperUnit) { dTextHeight *= GetPScale(); } return dTextHeight; } void TDbFloorRect::SetTextHeight(double dHeight, bool bAsPaperUnit) { assertWriteEnabled(); m_nSpare = dHeight; if (!bAsPaperUnit) { m_nSpare /= GetPScale(); } } // 文字样式 AcDbObjectId TDbFloorRect::GetTextStyleId() const { assertReadEnabled(); AcDbSoftPointerId idTextStyle; const TEntityFields &fd = GetFields(); fd.GFD(_T("文字样式"), idTextStyle); return idTextStyle; } void TDbFloorRect::SetTextStyleId(AcDbObjectId id) { assertWriteEnabled(); AcDbSoftPointerId idTextStyle = id; TEntityFields &fd = Fields(); fd.SFD(_T("文字样式"), idTextStyle); } // 基点显示样式,1为X,2为点 int TDbFloorRect::GetBaseType() const { assertReadEnabled(); int nVal = 1; // 其他专业默认为X //LH 2013-3-25 根据2014年加密需要水关键字8--14 暖6--15 电3--16 //if (g_nProductId == 8) if (g_nProductId == kTWT) { nVal = 2; // TWT专业默认为点 } const TEntityFields &fd = GetFields(); fd.GFD(_T("基点显示样式"), nVal); return nVal; } void TDbFloorRect::SetBaseType(int nType) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("基点显示样式"), nType); } // X型中,叉线的长度,固定值,与出图比例无关 double TDbFloorRect::GetCrossLen() const { assertReadEnabled(); double dVal = 1000; // 默认值为1000 const TEntityFields &fd = GetFields(); fd.GFD(_T("叉线长度"), dVal); return dVal; } void TDbFloorRect::SetCrossLen(double dCrossLen) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("叉线长度"), dCrossLen); } // sg add 100119,增加文字颜色的动态数据 Adesk::UInt16 TDbFloorRect::GetTextColor() const { assertReadEnabled(); Adesk::UInt16 color = 7; // 默认值为7,白色 const TEntityFields &fd = GetFields(); fd.GFD(_T("文字颜色"), color); return color; } void TDbFloorRect::SetTextColor(Adesk::UInt16 color) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("文字颜色"), color); } // sg add 100401,增加楼层框对象对应楼层表中的行号 short TDbFloorRect::GetTableIndex() const { assertReadEnabled(); short nIndex = 0; const TEntityFields &fd = GetFields(); fd.GFD(_T("楼层表行号"), nIndex); return nIndex; } void TDbFloorRect::SetTableIndex(short nIndex) { assertWriteEnabled(false, false); TEntityFields &fd = Fields(); fd.SFD(_T("楼层表行号"), nIndex); } // sg add 120106,为结构专业的楼层框对象使用,显示不同的样式 void TDbFloorRect::SetStruFloorRect(BOOL bStru) { int nVal = 0; const TEntityFields &fd1 = GetFields(); fd1.GFD(_T("专业楼层框"), nVal); if (bStru) nVal |= STRU_FLOORRECT; else nVal &= ~STRU_FLOORRECT; assertWriteEnabled(); TEntityFields &fd2 = Fields(); fd2.SFD(_T("专业楼层框"), nVal); } BOOL TDbFloorRect::IsStruFloorRect() const { assertReadEnabled(); int nVal = 0; const TEntityFields &fd = GetFields(); fd.GFD(_T("专业楼层框"), nVal); return ((nVal&STRU_FLOORRECT) != 0); } // sg add 100121,不支持在位编辑 TSubText* TDbFloorRect::HitTestText(XPoint pt) const { return NULL; } void IniTDbFloorRect(BOOL bTrue) { if (bTrue) { TDbFloorRect::rxInit(); TDbFloorRect::InitMatchProtocol(TRUE); } else { TDbFloorRect::InitMatchProtocol(FALSE); deleteAcRxClass(TDbFloorRect::desc()); } }