#include "stdafx.h" #include "CoreTools.h" #include "encryption.h" #include "AecDbWall.h" #include "simpleproperty.h" #include "KTCADUtilityEx.h" #include "dbgrip.h" #include "AecGripCback.h" #include "KTSetting.h" #include "AecDbX3dPartEntity.h" #include "AecDbColumn.h" #include "AecCoverBooleanOper.h" #include "AecDbOpening.h" #include "AecDbColumn.h" #include "AecDbX3dPart.h" #include "geometry2json.h" #include "HlrCutOption.h" #include "AecDbZLineXOpening.h" extern CString IDCreate(); extern double PixelToWcs(int nPixel); extern BOOL Is2DView(); extern AcGeVector3d GetUcsZvt(); extern void PushGripMessage(GripMessage&); extern AcDbArc* FormatArc(const AcGePoint3d& ptGe1,const AcGePoint3d& ptGe2,const AcGePoint3d& ptGe3); extern void transfromRegion(AcDbRegion *pRegion, const AcGePoint3d &ptOnRegion, const AcGeVector3d &vtNormal, const AcGePoint3d &ptOnPlan); extern Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt,AcDbDatabase* pDb = NULL,bool bClose = true); extern AcGePoint3d MidPoint(const AcGePoint3d& pt1,const AcGePoint3d& pt2); BOOL DLLIMPEXP GetDocScale(double& dPScale); extern void DLLIMPEXP OrthoProjected3DSolid(AcDb3dSolid* pSolidClone,const AcGePlane& plan,AcGeMatrix3d& xformPlanToWorld,AcDbVoidPtrArray& arEntPtrs); extern BOOL DLLIMPEXP GetDimGripOff(); 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; Adesk::UInt32 AecDbXWall::kCurrentVersionNumber = 1; static AcGePoint3d Mid(AcGePoint3d& ptGe1,AcGePoint3d& ptGe2) { return AcGePoint3d( (ptGe1.x + ptGe2.x) / 2.0, (ptGe1.y + ptGe2.y) / 2.0, (ptGe1.z + ptGe2.z) / 2.0); } 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; } } } extern AcGePoint3d GetArcMidPoint(AcDbArc* pArc); AcDbRegion* CreateRetangeRegion(AcGePoint3d* pPoints,int nSize) { AcDbVoidPtrArray arCurPtrs; for (int i = 0;i < nSize-1;i++)//5 { AcDbLine* pLine = new AcDbLine(pPoints[i],pPoints[i+1]); arCurPtrs.append(pLine); } AcDbVoidPtrArray arRegPtrs; AcDbRegion* pReg = NULL; if ( Acad::eOk == AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs) ) { //FREE AcDbEntity* pEnt = NULL; for (int i = 0;i < arCurPtrs.length();i++) { pEnt = (AcDbEntity*)arCurPtrs.at(i); DELETE_PTR(pEnt); } return (AcDbRegion*)arRegPtrs.first(); } //error FREE FreeBuffer(0,arCurPtrs); return NULL; } ACRX_DXF_DEFINE_MEMBERS (AecDbXWall, AecDbBDPipeBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning, AEC_DBWALL, "AecDbXWall" "|Product Desc: shanghua earthworm app obj" "|Company: shanghua inc" "|WEB Address: www.shanghuasoft.com") AecDbXWall::AecDbXWall(void) { m_mapSpecXData.SetAt(KEY_2DSTYLE,2); m_mapSpecXData.SetAt(KEY_CENNODRAW,1); m_mapSpecXData.SetAt(KEY_NAME,_T("墙体")); } AecDbXWall::~AecDbXWall(void) { } bool AecDbXWall::SetGradient(double dGradient) { assertWriteEnabled(); m_mapSpecXData.SetAt(KEY_GRAD,dGradient); return true; } double AecDbXWall::GetGradient() const { assertReadEnabled(); double dGradient = 0.0; m_mapSpecXData.GetAt(KEY_GRAD,dGradient); return dGradient; } bool AecDbXWall::SetAlign(int nAlgin) { AssertWriteEnabled(); m_mapSpecXData.SetAt(KEY_ALIGN,nAlgin); return true; } int AecDbXWall::GetAlign() const { assertReadEnabled(); int nAlgn = 0; m_mapSpecXData.GetAt(KEY_ALIGN,nAlgn); return nAlgn; } AcGePoint3d AecDbXWall::StartPoint() const { assertReadEnabled(); AcGePoint3d ptSta; getStartPoint(ptSta); return ptSta; } AcGePoint3d AecDbXWall::EndPoint() const { assertReadEnabled(); AcGePoint3d ptSta; getEndPoint(ptSta); return ptSta; } Acad::ErrorStatus AecDbXWall::subDeepClone(AcDbObject *pOwnerObject , AcDbObject *&pClonedObject , AcDbIdMapping &idMap , Adesk::Boolean isPrimary) const { Acad::ErrorStatus es = AecDbBDPipeBase::subDeepClone(pOwnerObject, pClonedObject, idMap, isPrimary); if (es != Acad::eOk) return es; AcDb::DeepCloneType dt = idMap.deepCloneContext(); if (dt == AcDb::kDcCopy || dt == AcDb::kDcObjects || dt == AcDb::kDcExplode || dt == AcDb::kDcInsertCopy ) { AecDbXWall* pClnWall = AecDbXWall::cast(pClonedObject); AcDbObjectId idVal; for (int i = 0; i < m_arAssocPartEntIds.length(); i++) { const AcDbSoftPointerId &idOpening = m_arAssocPartEntIds[i]; if (!idOpening) continue; AcDbIdPair idPairOpening(idOpening, AcDbObjectId::kNull, false, isPrimary ? true : false); if (idMap.compute(idPairOpening)) { if (pClnWall != NULL) { idVal = idPairOpening.value(); if (!idVal.isNull()) { pClnWall->m_arAssocPartEntIds.remove(idOpening); pClnWall->m_arAssocPartEntIds.append(idPairOpening.value()); // 不管 clone 出的 opening 的id是否在pClnWall的m_arAssocPartEntIds内,都要把pClnWall的id放到 opening的KEY_IDCNT1里 // ,保证co复制时关联关系不断 AcDbObjectPointer pClnOpening(idPairOpening.value(), AcDb::kForWrite); if (pClnOpening.openStatus() == Acad::eOk) { if (pClnWall->id().isValid()) pClnOpening->SetAt(KEY_IDCNT1, pClnWall->id()); } AcDbObjectPointer pClnXPart(idPairOpening.value(), AcDb::kForWrite); if (pClnXPart.openStatus() == Acad::eOk) { if (pClnWall->id().isValid()) pClnXPart->SetAt(KEY_ASSOIC, pClnWall->id()); } } } continue; } AcDbObject *pSubObject = NULL; es = acdbOpenAcDbObject(pSubObject, idOpening, AcDb::kForRead); if (pSubObject != NULL) { AcDbObject *pClonedSubObject = NULL; pSubObject->deepClone(pOwnerObject, pClonedSubObject, idMap, isPrimary); if (pSubObject != pClonedSubObject) { pSubObject->close(); } if (pClonedSubObject != NULL) { idVal = pClonedSubObject->objectId(); if (!idVal.isNull() && pClnWall != NULL) { pClnWall->m_arAssocPartEntIds.remove(idOpening); pClnWall->m_arAssocPartEntIds.append(idVal); AecDbXOpening *pClnOpening = AecDbXOpening::cast(pClonedSubObject); if (pClnOpening) { pClnOpening->setOwnerId(pOwnerObject->id()); if (pClnWall->id().isValid()) pClnOpening->SetAt(KEY_IDCNT1, pClnWall->id()); } AecDbX3dPartEntity *pClnXPart = AecDbX3dPartEntity::cast(pClonedSubObject); if (pClnXPart) { if (pClnWall->id().isValid()) pClnXPart->SetAt(KEY_ASSOIC, pClnWall->id()); } } pClonedSubObject->close(); } } } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::subWblockClone(AcRxObject* pOwnerObject, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary/* = true*/) const { Acad::ErrorStatus es = AecDbBDPipeBase::subWblockClone(pOwnerObject, pClonedObject, idMap, isPrimary); if (es != Acad::eOk) return es; AcDb::DeepCloneType dt = idMap.deepCloneContext(); if (dt == AcDb::kDcCopy || dt == AcDb::kDcObjects || dt == AcDb::kDcWblock || dt == AcDb::kDcWblkObjects) { AecDbXWall* pClnWall = AecDbXWall::cast(pClonedObject); AcDbObjectId idVal; for (int i = 0; i < m_arAssocPartEntIds.length(); i++) { const AcDbSoftPointerId &idOpening = m_arAssocPartEntIds[i]; if (!idOpening) continue; AcDbIdPair idPairOpening(idOpening, AcDbObjectId::kNull, false, isPrimary ? true : false); if (idMap.compute(idPairOpening)) { if (pClnWall != NULL) { idVal = idPairOpening.value(); if (!idVal.isNull()) { int nFt = -1; if (!pClnWall->m_arAssocPartEntIds.find(idVal,nFt)) { pClnWall->m_arAssocPartEntIds.append(idPairOpening.value()); } // 不管 clone 出的 opening 的id是否在pClnWall的m_arAssocPartEntIds内,都要把pClnWall的id放到 opening的KEY_IDCNT1里 // ,保证co复制时关联关系不断 AcDbObjectPointer pClnOpening(idPairOpening.value(), AcDb::kForWrite); if (pClnOpening.openStatus() == Acad::eOk) { if (pClnWall->id().isValid()) pClnOpening->SetAt(KEY_IDCNT1, pClnWall->id()); } } } continue; } AcDbObject *pSubObject = NULL; acdbOpenAcDbObject(pSubObject, idOpening, AcDb::kForRead); if (pSubObject != NULL) { AcDbObject *pClonedSubObject = NULL; pSubObject->wblockClone(pOwnerObject, pClonedSubObject, idMap, isPrimary); if (pSubObject != pClonedSubObject) { pSubObject->close(); } if (pClonedSubObject != NULL) { idVal = pClonedSubObject->objectId(); if (!idVal.isNull() && pClnWall != NULL) { int nFt = -1; if (!pClnWall->m_arAssocPartEntIds.find(idVal, nFt)) { pClnWall->m_arAssocPartEntIds.append(idVal); } AecDbXOpening *pClnOpening = AecDbXOpening::cast(pClonedSubObject); if (pClnOpening) { if (pClnWall->id().isValid()) pClnOpening->SetAt(KEY_IDCNT1, pClnWall->id()); } } pClonedSubObject->close(); } } } } return Acad::eOk; } bool AecDbXWall::SetWallData(double dBomEl,EAlign kAlign/* = kMid*/) { AssertWriteEnabled(); //重新生成2D m_drawable2d.RemoveEdage(); AcDbLine* pLn = AcDbLine::cast(m_pBaseCurve); if (pLn != NULL) { AcGePoint3d pt0 = pLn->startPoint(); AcGePoint3d pt1 = pLn->endPoint(); pt0.z = dBomEl;pt1.z = dBomEl; pLn->setStartPoint(pt0); pLn->setEndPoint(pt1); } AcDbArc* pArc = AcDbArc::cast(m_pBaseCurve); if (pArc != NULL) { AcGePoint3d ptCen = pArc->center(); ptCen.z = dBomEl; pArc->setCenter(ptCen); } AcDbCircle *pCir = AcDbCircle::cast(m_pBaseCurve); if (pCir != NULL) { AcGePoint3d ptCen = pCir->center(); ptCen.z = dBomEl; pCir->setCenter(ptCen); } AcDbPolyline* pPl = AcDbPolyline::cast(m_pBaseCurve); if (pPl != NULL) { pPl->setElevation(dBomEl); } m_mapSpecXData.SetAt(PIPE_EL,dBomEl); return true; } bool AecDbXWall::SetWallData(double dThick,double dH,double dBomEl,EAlign kAlign) { if (dThick < 1.e-3 || dH < 1.e-3 ) return false; AssertWriteEnabled(); //重新生成2D m_drawable2d.RemoveEdage(); /* 0/4 1 +-----+ | | | | | | +-----+ 3 2 */ SetSection(dThick,dH,dBomEl,kAlign); return true; } int AecDbXWall::ImpMakeWwSectionPoints(const WallData& data,AcGePoint3d* ptGe,int nPts) const { /* 0/6 +--+ 1 | | | | 4 +---+5 | | | | | +------+ 2 3 0/8 +--+ 1 | | | | 6__|7 |2__. | | 3 | | +--------+ 4 5 0/6 +--+ 1 | | | | | |2__. | | 3 | | +------+ 4 5 */ if (ptGe == NULL) return 0; int nPoints = 0; switch(data.nW2Pos) { case 0://左侧外延 { ptGe[0].set(0,0,0); ptGe[0].y += data.dBomEl;//底中心 ptGe[3] = ptGe[0]; ptGe[3].x -= 0.5 * data.dThick2; ptGe[2] = ptGe[3]; ptGe[2].x += data.dThick2; ptGe[1] = ptGe[2]; ptGe[1].y += data.dH; ptGe[0] = ptGe[1]; ptGe[0].x -= data.dThick; ptGe[6] = ptGe[0]; ptGe[5] = ptGe[0]; ptGe[5].y -= (data.dH - data.dH2); ptGe[4] = ptGe[3]; ptGe[4].y += data.dH2; nPoints = 7; break; } case 1://居中对称 { ptGe[0].set(0,0,0); ptGe[0].y += data.dBomEl;//底中心 ptGe[5] = ptGe[0]; ptGe[5].x -= 0.5 * data.dThick2; ptGe[4] = ptGe[5]; ptGe[4].x += data.dThick2; ptGe[3] = ptGe[4]; ptGe[3].y += data.dH2; ptGe[6] = ptGe[5]; ptGe[6].y += data.dH2; ptGe[7] = ptGe[6]; ptGe[7].x += 0.5 * ( data.dThick2 - data.dThick ); ptGe[2] = ptGe[7]; ptGe[2].x += data.dThick; ptGe[1] = ptGe[2]; ptGe[1].y += (data.dH - data.dH2); ptGe[0] = ptGe[1]; ptGe[0].x -= data.dThick; ptGe[8] = ptGe[0]; nPoints = 9; break; } case 2://右侧外延 { ptGe[0].set(0,0,0); ptGe[0].y += data.dBomEl;//底中心 ptGe[5] = ptGe[0]; ptGe[5].x -= 0.5 * data.dThick2; ptGe[4] = ptGe[5]; ptGe[4].x += data.dThick2; ptGe[3] = ptGe[4]; ptGe[3].y += data.dH2; ptGe[2] = ptGe[3]; ptGe[2].x -= (data.dThick2 - data.dThick); ptGe[1] = ptGe[2]; ptGe[1].y += (data.dH - data.dH2); ptGe[0] = ptGe[1]; ptGe[0].x -= data.dThick; ptGe[6] = ptGe[0]; nPoints = 7; break; } default: break; } switch(data.kAlign) { case kMid://居中 { break; } case kLeft://左侧 { for (int i = 0;i < 5;i++) { ptGe[i].x -= 0.5 * data.dThick2; } break; } case kRight: { for (int i = 0;i < 5;i++) { ptGe[i].x += 0.5 * data.dThick2; } break; } default: break; } return nPoints; } bool AecDbXWall::SetWallData(double dThick,double dH,double dThick2,double dH2,int nW2Pos,double dBomEl,EAlign kAlign/* = kMid*/) { AssertWriteEnabled(); if ( ( dThick2 - dThick ) < 1.e-6 || dH2 < 1.e-6 || dThick2 < 1.e-6) { return SetWallData(dThick,dH,dBomEl,kAlign); } //重新生成2D m_drawable2d.RemoveEdage(); if (dThick < 1.e-3 || dH < 1.e-3 ) return false; int nPoints = 0; AcGePoint3d ptGe[10]; WallData wData; wData.dBomEl = dBomEl; wData.dH = dH; wData.dH2 = dH2; wData.dThick = dThick; wData.dThick2 = dThick2; wData.kAlign = kAlign; wData.nSecShape = eWw; wData.nW2Pos = nW2Pos; nPoints = ImpMakeWwSectionPoints(wData,ptGe,10); //底标高基准点 AcGePoint3d ptCen; ptCen.set(0,0,0); AcDbRegion* pReg = CreateRetangeRegion(ptGe,nPoints); SetSection(pReg,ptCen); //TEST //AddToModelSpace(pReg); delete pReg; //记录底部标高数值 m_mapSpecXData.SetAt(KEY_SIZE1,dThick); m_mapSpecXData.SetAt(KEY_SIZE2,dH); m_mapSpecXData.SetAt(KEY_SIZE3,dThick2); m_mapSpecXData.SetAt(KEY_SIZE4,dH2); m_mapSpecXData.SetAt(PIPE_EL,dBomEl); m_mapSpecXData.SetAt(KEY_SECSHAPE,eWw);//不等宽墙体 m_mapSpecXData.SetAt(KEY_ALIGN,kAlign); m_mapSpecXData.SetAt(KEY_W2POS,nW2Pos); return true; } bool AecDbXWall::GetWallData(WallData& data) const { assertReadEnabled(); memset(&data,0,sizeof(WallData)); m_mapSpecXData.GetAt(KEY_SIZE1,data.dThick); m_mapSpecXData.GetAt(KEY_SIZE2,data.dH); m_mapSpecXData.GetAt(KEY_SIZE3,data.dThick2); m_mapSpecXData.GetAt(KEY_SIZE4,data.dH2); m_mapSpecXData.GetAt(PIPE_EL,data.dBomEl); int nAlign = 0; m_mapSpecXData.GetAt(KEY_ALIGN,nAlign); data.kAlign = (EAlign)nAlign; m_mapSpecXData.GetAt(KEY_SECSHAPE,data.nSecShape);//标准 m_mapSpecXData.GetAt(KEY_W2POS,data.nW2Pos); m_mapSpecXData.GetAt(KEY_NO,data.szNO); CString sTemp; m_mapSpecXData.GetAt(KEY_MATERIAL,sTemp); _tcscpy(data.szMat,(LPCTSTR)sTemp); return true; } Acad::ErrorStatus AecDbXWall::AdjustHoleAndPipe(double dThickAdd) { AcDbObjectId id; AcDbEntity* pEnt = NULL; Acad::ErrorStatus es; if (objectId().isValid()) { AcDbCurve* pLeft = GetLeftCurve(); AcDbCurve* pRight = GetRightCurve(); AcGeVector3d vtAdd; AcGePoint3d ptOrgOld,ptOrgNew,pt1,pt2; if (pLeft != NULL && pRight != NULL) { for (int i = 0;i < m_arAssocPartEntIds.length();i++) { id = m_arAssocPartEntIds.at(i); if ( Acad::eOk == (es = acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite))) { AecDbX3dPartEntity* pPart = AecDbX3dPartEntity::cast(pEnt); if (pPart != NULL) { ptOrgOld = pPart->GetOrgPoint(true); pLeft->getClosestPointTo(ptOrgOld,pt1); pRight->getClosestPointTo(ptOrgOld,pt2); ptOrgNew = MidPoint(pt1,pt2); ptOrgNew.z = ptOrgOld.z; vtAdd = ptOrgNew - ptOrgOld; pPart->HoleAndPipeExtend(dThickAdd,vtAdd); } pEnt->close(); } } delete pLeft; delete pRight; } } return Acad::eOk; } void AecDbXWall::AddHoleDimPoints(AcDbGripDataPtrArray& grips,const AcGeVector3d& curViewDir) const { AcDbObjectId id; AcDbEntity* pEnt = NULL; Acad::ErrorStatus es; if (objectId().isValid()) { AcGeVector3d vtAdd; AcGePoint3d ptOrgOld,ptOrgNew,pt1,pt2; for (int i = 0;i < m_arAssocPartEntIds.length();i++) { id = m_arAssocPartEntIds.at(i); if ( Acad::eOk == (es = acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead))) { AecDbX3dPartEntity* pPart = AecDbX3dPartEntity::cast(pEnt); if (pPart != NULL) { CString sName = pPart->GetName(); if (sName.CompareNoCase(_T("开洞")) == 0) { pPart->SubAddDimPoints(grips,curViewDir); } } pEnt->close(); } } } } void GetMidPoint(AcDbCurve* pNaCurve,AcGePoint3d& ptMid) { AcDbLine* pLn = AcDbLine::cast(pNaCurve); if (pLn != NULL) { ptMid = MidPoint(pLn->startPoint(),pLn->endPoint()); } AcDbArc* pArc = AcDbArc::cast(pNaCurve); if (pArc != NULL) { ptMid = GetArcMidPoint(pArc); } } bool IsOnCurve(AcDbCurve* pCurve,AecEqui::AecCurveElement& el) { AcDbLine* pLn = AcDbLine::cast(pCurve); if (pLn != NULL) { AcGePoint3d ptOn; pLn->getClosestPointTo(el.ptGe[0],ptOn,Adesk::kTrue); if (ptOn.distanceTo(el.ptGe[0]) < 1.e-1) { pLn->getClosestPointTo(el.ptGe[2],ptOn,Adesk::kTrue); if (ptOn.distanceTo(el.ptGe[2]) < 1.e-1) { return true; } } } AcDbArc* pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { AcGePoint3d ptCen = pArc->center(); double dR = pArc->radius(); double dr1 = el.ptGe[0].distanceTo(ptCen); double dr2 = el.ptGe[2].distanceTo(ptCen); if ( fabs(dr1 - dR) < 1.e-1 && fabs(dr2 - dR) < 1.e-1) { return true; } } return false; } //只针对直线的情况 bool AecDbXWall::GetDrawable2dLeft(AecComplexCurve& cmplL) const { assertReadEnabled(); AecEqui::AecCurveElement el = GetLeftElement(); AcDbCurve* pCurve = NULL; AecComplexCurve::MakeCurve(el,pCurve); if (pCurve == NULL) return false; AecComplexCurve cmpl; m_drawable2d.GetEdage(cmpl); AcGeVector3d vt1,vt2; for (int j = 0;j < cmpl.length();j++) { AecEqui::AecCurveElement& eT = cmpl.atByRef(j); //判断共线 if (IsOnCurve(pCurve,eT) && !eT.bHided) { cmplL.append(eT); } } delete pCurve; return !cmplL.isEmpty(); } //只针对直线的情况 bool AecDbXWall::GetDrawable2dRight(AecComplexCurve& cmplR) const { assertReadEnabled(); AecEqui::AecCurveElement el = GetRightElement(); AcDbCurve* pCurve = NULL; AecComplexCurve::MakeCurve(el,pCurve); if (pCurve == NULL) return false; AecComplexCurve cmpl; m_drawable2d.GetEdage(cmpl); AcGeVector3d vt1,vt2; for (int j = 0;j < cmpl.length();j++) { AecEqui::AecCurveElement& eT = cmpl.atByRef(j); //判断共线 //判断共线 if (IsOnCurve(pCurve,eT) && !eT.bHided) { cmplR.append(eT); } } delete pCurve; return !cmplR.isEmpty(); } bool AecDbXWall::GetTailLineElement(AcGePoint3d* pptLSE,AecComplexCurve& cmplL) const { int nFat = -1; AcGePoint3dArray arPts; for (int j = 0;j < cmplL.length();j++) { AecEqui::AecCurveElement& eT = cmplL.atByRef(j); if (!arPts.find(eT.ptGe[0],nFat)) arPts.append(eT.ptGe[0]); if (!arPts.find(eT.ptGe[2],nFat)) arPts.append(eT.ptGe[2]); } if (!arPts.isEmpty()) { if (arPts.length() > 1) { AcDbCurve* pCurve = GetNativeCurve(); AecCoverBooleanOper::SortPoints(arPts,pCurve,false); pptLSE[0] = arPts.first(); pptLSE[1] = arPts.last(); return true; } } return false; } BOOL AecDbXWall::IsVViewWall() const { assertReadEnabled(); BOOL bIsVView = FALSE; m_mapSpecXData.GetAt(KEY_VVIEW,bIsVView); return bIsVView; } AcDbCurve* AecDbXWall::GetAsNativeCurveOfVView() const { assertReadEnabled(); AcDbCurve* pLeft = GetLeftCurve(); AcDbCurve* pRight = GetRightCurve(); if (pLeft != NULL && pRight != NULL) { //默认为同向 AcGePoint3d ptL[2]; pLeft->getStartPoint(ptL[0]); pLeft->getEndPoint(ptL[1]); AcGePoint3d ptR[2]; pRight->getStartPoint(ptR[0]); pRight->getEndPoint(ptR[1]); AcGePoint3d ptS,ptE; ptS = MidPoint(ptL[0],ptR[0]); ptE = MidPoint(ptL[1],ptR[1]); AcDbLine* pLn = new AcDbLine; pLn->setStartPoint(ptS); pLn->setEndPoint(ptE); return pLn; } return NULL; } int AecDbXWall::GetNearPosition(const AcGePoint3d& ptOn) const { AcDbCurve* pCurve = GetAsNativeCurveOfVView(); if (pCurve != NULL) { AcGePoint3d ptS,ptE; pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); delete pCurve; ptS.z = ptOn.z; ptE.z = ptOn.z; if (ptOn.distanceTo(ptS) < ptOn.distanceTo(ptE)) { return 0; } return 1; } return -1; } //创建开始末尾位置连接solid AcDb3dSolid* AecDbXWall::CreateJoin3dSolid(AcDb3dSolid* pSolidAll,int nPos) const { //里面拉墙体暂时不参与融合 BOOL bIsVView = FALSE; m_mapSpecXData.GetAt(KEY_VVIEW,bIsVView); if (bIsVView)//立面墙体 { return pSolidAll; } //先特殊处理acdbline int nSecShape = 0; m_mapSpecXData.GetAt(KEY_SECSHAPE, nSecShape); bool bOnXY = (nSecShape == eUserDef) ? false : true; AcDbCurve* pBaseCr = GetBaseCurve(bOnXY); if (pBaseCr != NULL) { AcDbLine* pLn = AcDbLine::cast(pBaseCr); if (pLn != NULL) { Acad::ErrorStatus es; AcGePoint3d ptSta = pLn->startPoint(); AcGePoint3d ptEnd = pLn->endPoint(); AcGeVector3d vtL = ptEnd - ptSta; WallData data; GetWallData(data); //获取左右延申的长度 //确定端头 bool bStaAdd = false; bool bEndAdd = false; vtL.normalize(); AcGePoint3d pt2; double dL = data.dThick * 3.0;//ptSta.distanceTo(ptEnd) / 4.0; if (dL > 1.e-3)//STA { AcDbLine lnS; lnS.setEndPoint(ptSta); pt2 = ptSta - dL * vtL; lnS.setStartPoint( pt2 ); AcDbRegion* pRegionWall = GetSection(); AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); transfromRegion(pRegionWall,ptOnRegion,vtL,pt2); AcDb3dSolid* pSolidS = new AcDb3dSolid; es = pSolidS->extrudeAlongPath(pRegionWall,&lnS); if (es != Acad::eOk) { delete pSolidS; acutPrintf(_T("\nextrudeAlongPath error %d"),es); } else { es = pSolidAll->booleanOper(AcDb::kBoolUnite,pSolidS); if (es == Acad::eOk) { bStaAdd = true; } else { acutPrintf(_T("\nkBoolUnite error %d"),es); } } delete pRegionWall; } if (dL > 1.e-3) //END { AcDbLine lnE; lnE.setStartPoint(ptEnd); pt2 = ptEnd + dL * vtL; lnE.setEndPoint( pt2 ); AcDbRegion* pRegionWall = GetSection(); AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); transfromRegion(pRegionWall,ptOnRegion,vtL,ptEnd); AcDb3dSolid* pSolidE = new AcDb3dSolid; es = pSolidE->extrudeAlongPath(pRegionWall,&lnE); if (es != Acad::eOk) { delete pSolidE; acutPrintf(_T("\nextrudeAlongPath error %d"),es); } else { es = pSolidAll->booleanOper(AcDb::kBoolUnite,pSolidE); if (es == Acad::eOk) { bEndAdd = true; } else { acutPrintf(_T("\nkBoolUnite error %d"),es); } } delete pRegionWall; } //取外围的闭合曲线,裁剪 if (bStaAdd || bEndAdd) { AcDbLine lnH; ptSta.z = data.dBomEl; lnH.setStartPoint(ptSta); ptEnd = ptSta; ptEnd.z += data.dH; lnH.setEndPoint(ptEnd); AcDbPolyline* pPl = GetWall2dBoundary(); if (pPl != NULL) { pPl->setElevation(data.dBomEl); AcDbVoidPtrArray arCurPtrs,arRegPtrs; arCurPtrs.append(pPl); AcDbRegion* pReg = NULL; if ( Acad::eOk == AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs) ) { if (!arRegPtrs.isEmpty()) { pReg = (AcDbRegion*)arRegPtrs.first(); } } delete pPl; AcDb3dSolid* pSolidB = new AcDb3dSolid; es = pSolidB->extrudeAlongPath(pReg,&lnH); if (es != Acad::eOk) { delete pSolidB; } else { es = pSolidAll->booleanOper(AcDb::kBoolIntersect,pSolidB); } delete pReg; } } } else { //...圆弧 } delete pBaseCr; } return pSolidAll; } AcDb3dSolid* AecDbXWall::SliceJoinPart3d(AcDb3dSolid* pSolidAll) const { //首先和具有 KEY_FORSLICE 标记的Part并 Acad::ErrorStatus es = Acad::eOk; int nBoolOper = 0,bSlice = 0,nPos = 0; AcDb3dSolid* pSolidPart = NULL; AecDbX3dPart* pPart = NULL; bool bHasSlice = false; BOOL bEndAdd = FALSE; BOOL bStaAdd = FALSE; for (int i = 0;i < m_arX3DPartPtrs.length();i++) { pPart = (AecDbX3dPart*)m_arX3DPartPtrs.at(i); bSlice = 0; if ( pPart->GetSpecialtyData()->GetAt(KEY_FORSLICE,bSlice) ) { if (bSlice == 0) { continue; } } pPart->GetSpecialtyData()->GetAt(KEY_POS,nPos); if (nPos == 0) bStaAdd = TRUE; if (nPos == 1) bEndAdd = TRUE; bHasSlice = true; nBoolOper = pPart->GetBoolOperFor(); if (nBoolOper == AcDb::kBoolUnite) { pSolidPart = pPart->CreateDraw3dSolid(); if (pSolidPart == NULL) { pPart->Create(); pSolidPart = pPart->CreateDraw3dSolid(); } if (pSolidPart != NULL) { if ( Acad::eOk == (es = pSolidAll->booleanOper(AcDb::kBoolUnite,pSolidPart) ) ) { } else { acutPrintf(_T("\nUnite Oper error:%d"),es); } } } } AcDbCurve *pBaseCr = GetNativeCurve(); AcDbArc *pArc = AcDbArc::cast(pBaseCr); if (pArc != NULL) { AcGePoint3d ptSta, ptEnd; pArc->getStartPoint(ptSta); pArc->getEndPoint(ptEnd); WallData data; GetWallData(data); AcDbLine lnH; ptSta.z = data.dBomEl; lnH.setStartPoint(ptSta); ptEnd = ptSta; ptEnd.z += data.dH; lnH.setEndPoint(ptEnd); AcDbPolyline *pPl = GetWall2dBoundary(); if (pPl != NULL) { pPl->setElevation(data.dBomEl); AcDbVoidPtrArray arCurPtrs, arRegPtrs; arCurPtrs.append(pPl); AcDbRegion *pReg = NULL; if (Acad::eOk == AcDbRegion::createFromCurves(arCurPtrs, arRegPtrs)) { if (!arRegPtrs.isEmpty()) { pReg = (AcDbRegion *)arRegPtrs.first(); } } //pPl->setColorIndex(2); //AddToModelSpace(pPl); delete pPl; AcDb3dSolid *pSolidB = new AcDb3dSolid; es = pSolidB->extrudeAlongPath(pReg, &lnH); if (es != Acad::eOk) { delete pSolidB; } else { //delete pSolidB; //pSolidB->setColorIndex(1); //AddToModelSpace(pSolidB); es = pSolidAll->booleanOper(AcDb::kBoolIntersect, pSolidB); } delete pReg; } } if (!bHasSlice) { return pSolidAll; } //取出左面线 AecComplexCurve cmplL; GetDrawable2dLeft(cmplL); //获取两头的点 AcGePoint3d ptLSE[2]; bool bL = GetTailLineElement(ptLSE,cmplL); //取出右面线 AecComplexCurve cmplR; GetDrawable2dRight(cmplR); AcGePoint3d ptRSE[2]; bool bR = GetTailLineElement(ptRSE,cmplR); AcGePoint3d ptMs = MidPoint(ptLSE[0],ptRSE[0]); AcGePoint3d ptMe = MidPoint(ptLSE[1],ptRSE[1]); AcGePoint3d ptSta,ptEnd; pBaseCr->getStartPoint(ptSta); pBaseCr->getEndPoint(ptEnd); //获取左右延申的长度 //确定端头 double dL1 = ptMs.distanceTo(ptSta); double dL2 = ptMe.distanceTo(ptSta); AcGePoint3d ptT; if (dL1 > dL2)//互换 { ptT = ptMs; ptMs = ptMe; ptMe = ptT; AcGePoint3d ptGT[2]; memcpy(ptGT,ptLSE,sizeof(AcGePoint3d) * 2); memcpy(ptLSE,ptRSE,sizeof(AcGePoint3d) * 2); memcpy(ptRSE,ptGT,sizeof(AcGePoint3d) * 2); } ptMs = MidPoint(ptLSE[0],ptRSE[0]); ptMe = MidPoint(ptLSE[1],ptRSE[1]); AcGeVector3d vtSHalf = ptRSE[0] - ptLSE[0]; AcGeVector3d vtEHalf = ptRSE[1] - ptLSE[1]; //TEST /*AcDbLine *pLn1 = new AcDbLine(ptRSE[0], ptLSE[0]); pLn1->setColorIndex(1); AddToModelSpace(pLn1); AcDbLine *pLn2 = new AcDbLine(ptRSE[1], ptLSE[1]); pLn2->setColorIndex(1); AddToModelSpace(pLn2);*/ double dA1 = 0.0; double dA2 = 0.0; AcDb3dSolid* pNegSolid = NULL; if (bStaAdd) { //TEST AcGePlane planS; vtSHalf.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); planS.set(ptMs,vtSHalf); pSolidAll->getSlice(planS,Adesk::kTrue,pNegSolid); if (pNegSolid != NULL) { pSolidAll->getArea(dA1); pNegSolid->getArea(dA2); if (dA1 < dA2) { delete pSolidAll; pSolidAll = pNegSolid; } else { //pNegSolid->setColorIndex(2); //AddToModelSpace(pNegSolid); delete pNegSolid; } } } if (bEndAdd) { AcGePlane planE; vtEHalf.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); planE.set(ptMe,vtEHalf); pNegSolid = NULL; pSolidAll->getSlice(planE,Adesk::kTrue,pNegSolid); if (pNegSolid != NULL) { pSolidAll->getArea(dA1); pNegSolid->getArea(dA2); if (dA1 < dA2) { delete pSolidAll; pSolidAll = pNegSolid; } } } return pSolidAll; } void AecDbXWall::ExtClosesttoDraw2d(AcDbCurve* pCurve) const { AecComplexCurve draw2d; GetDraw2dables(draw2d); AcGePoint3d ptOn; AcGePoint3dArray arPts; for (int i = 0; i < draw2d.length(); i++) { AecEqui::AecCurveElement &el = draw2d.atByRef(i); pCurve->getClosestPointTo(el.ptGe[0], ptOn,Adesk::kTrue); if (arPts.find(ptOn) == -1) arPts.append(ptOn); pCurve->getClosestPointTo(el.ptGe[2], ptOn, Adesk::kTrue); if (arPts.find(ptOn) == -1) arPts.append(ptOn); } if (arPts.isEmpty()) return; AcDbRay ln; AcDbCircle cir; AcDbCurve *pCrvTmp = NULL; AcDbLine *pLn = AcDbLine::cast(pCurve); if (pLn != NULL) { AcGeVector3d vtLn = pLn->endPoint() - pLn->startPoint(); ln.setBasePoint(pLn->startPoint()); ln.setUnitDir(vtLn); pCrvTmp = &ln; } AcDbArc *pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { cir.setCenter(pArc->center()); cir.setRadius(pArc->radius()); cir.setNormal(pArc->normal()); pCrvTmp = ○ } if (!pCrvTmp) return; AecCoverBooleanOper::SortPoints(arPts, pCrvTmp, false); if (pLn != NULL) { pLn->setStartPoint(arPts.first()); pLn->setEndPoint(arPts.last()); } if (pArc != NULL && arPts.length() > 2) { AcDbArc* pArcT = FormatArc(arPts.first(), arPts.at(1), arPts.last()); double dSta = pArcT->startAngle(); double dEnd = pArcT->endAngle(); pArc->setStartAngle(dSta); pArc->setEndAngle(dEnd); delete pArcT; } } AcDb3dSolid* AecDbXWall::GetDraw3dSolid(bool bAttachBimInf,int nColor,bool bSubtractHole/* = true*/) const { assertReadEnabled(); int nSecShape = 0; m_mapSpecXData.GetAt(KEY_SECSHAPE,nSecShape); bool bOnXY = (nSecShape == eUserDef) ? false : true; AcDbCurve* pCurve = GetBaseCurve(bOnXY); if (pCurve == NULL) return NULL; //根据工艺视图,再两端延长 ExtClosesttoDraw2d(pCurve); int nShow3d = 0; m_mapSpecXData.GetAt(KEY_3DSHOW,nShow3d); AcDb3dSolid* pSolid = NULL; AcDbRegion* pRegionWall = GetSection(); if (pRegionWall != NULL) { //1.创建整体Solid AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); double dSta = 0.0; pCurve->getStartParam(dSta); AcGeVector3d vtDir; pCurve->getFirstDeriv(dSta,vtDir); AcGePoint3d ptOnPlan; pCurve->getStartPoint(ptOnPlan); AcGePoint3d ptEnd; pCurve->getEndPoint(ptEnd); AcDbExtents ext; pRegionWall->getGeomExtents(ext); AcGePoint3d ptOrg = ext.minPoint(); //墙体被变换立面了特殊情况处理 if (vtDir.isParallelTo(AcGeVector3d::kZAxis)) { AcGeVector3d vtM = ptOnPlan - ptOrg; AcGeMatrix3d xM; xM.setToTranslation(vtM); pRegionWall->transformBy(xM); } else { transfromRegion(pRegionWall,ptOnRegion,vtDir,ptOnPlan); } Acad::ErrorStatus es = Acad::eOk; // 处理 CAD 3D 实体体量不能大于 120000问题 // 拉伸 扫掠 实体,路径长不能大于 120000 ,圆,弧 除外 AcDbVoidPtrArray arCuvs; if (AcDbCircle::cast(pCurve) || AcDbArc::cast(pCurve) || !CoreTools::spliteCurve(pCurve, 100000., arCuvs)) { pSolid = new AcDb3dSolid; es = pSolid->extrudeAlongPath(pRegionWall, pCurve); DELETE_PTR(pRegionWall); if (es != Acad::eOk) { acutPrintf(_T("\nextrude error:%d"), es); DELETE_PTR(pSolid); DELETE_PTR(pCurve); return NULL; } } else { #ifndef ZWCAD DELETE_PTR(pRegionWall); AcGePoint3d ptStart(AcGePoint3d::kOrigin); AcDbVoidPtrArray arSolids; for (int i = 0; i < arCuvs.length(); ++i) { AcDbCurve *p((AcDbCurve*)arCuvs[i]); if (!p) continue; p->getStartPoint(ptStart); AcDbRegion *pReg = GetSection(); transfromRegion(pReg, ptOnRegion, vtDir, ptStart); AcDb3dSolid *pSo = new AcDb3dSolid(); es = pSo->extrudeAlongPath(pReg, p); DELETE_PTR(pReg); if (es != Acad::eOk) { // 一个失败,全部离开 acutPrintf(_T("\nextrude error:%d"), es); DELETE_PTR(pSo); DELETE_PTR(pCurve); deleteArrayVoidPtrs< AcDbEntity>(arCuvs); return NULL; } arSolids.append(pSo); } deleteArrayVoidPtrs< AcDbEntity>(arCuvs); if (arSolids.length() < 2) { deleteArrayVoidPtrs< AcDbEntity>(arSolids); DELETE_PTR(pCurve); return NULL; } pSolid = (AcDb3dSolid*)((AcDb3dSolid*)arSolids[0])->clone(); for (int i = 1; i < arSolids.length(); ++i) { es = pSolid->booleanOper(AcDb::kBoolUnite, (AcDb3dSolid*)arSolids[i]); } deleteArrayVoidPtrs< AcDbEntity>(arSolids); #else deleteArrayVoidPtrs< AcDbEntity>(arCuvs); pSolid = new AcDb3dSolid; AcDbSweepOptions sweepOp; es = pSolid->createSweptSolid((AcDbEntity *)pRegionWall, (AcDbEntity *)pCurve, sweepOp); DELETE_PTR(pRegionWall); if (es != Acad::eOk) { acutPrintf(_T("\nextrude error:%d"), es); DELETE_PTR(pSolid); DELETE_PTR(pCurve); return NULL; } #endif } //先补后切方法 if (nShow3d == 1) { pSolid = CreateJoin3dSolid(pSolid,-1); } //和PArt 先布尔处理一下 GetBooleanPart3D(pSolid); //然后根据二维线切割增加的融合PART if (nShow3d == 1) { pSolid = SliceJoinPart3d(pSolid); } //开洞 //2.在开除关联的part的对象 if (bSubtractHole) { BoolSubtractAssoc(pSolid); } } //3.按照墙体底部坡度切割 if (pSolid != NULL && pCurve != NULL && nShow3d == 0) { double dGradient = GetGradient(); if (fabs(dGradient) > 1.e-6)//必须大于fab(1.e-6)的坡度 { double dSta = 0.0,dEnd = 0.0; pCurve->getStartParam(dSta); pCurve->getEndParam(dEnd); AcGePoint3d ptSta,ptEnd; pCurve->getStartPoint(ptSta); pCurve->getEndPoint(ptEnd); double dLxy = ptEnd.distanceTo(ptSta); AcGePoint3d ptMid; pCurve->getPointAtParam((dSta + dEnd) / 2.0,ptMid); double dElDt = 0.5 * dLxy * dGradient * 0.01; ptEnd.z = ptMid.z + dElDt;//终点标高 AcGeVector3d vtL = ptEnd - ptSta; AcGeVector3d vtZ = AcGeVector3d::kZAxis; AcGeVector3d vtAx = vtL.crossProduct(vtZ); AcGeVector3d vtNorm = vtAx.crossProduct(vtL); //必须向上 if (vtNorm.dotProduct(vtZ) < -1.e-10) vtNorm.negate(); AcGePlane plan(ptMid,vtNorm); AcDb3dSolid* pNegHalfSolid = NULL; pSolid->getSlice(plan,Adesk::kFalse,pNegHalfSolid); } } if (pCurve != NULL) { delete pCurve; } if (bAttachBimInf != NULL) { m_mapSpecXData.Write(pSolid,_T("BIMDATA")); } return pSolid; } Acad::ErrorStatus AecDbXWall::BoolSubtractAssoc(AcDb3dSolid* pSolid) const { assertReadEnabled(); AcDb3dSolid* pSolidPart = NULL; AcDbObjectId id; AcDbEntity* pEnt = NULL; Acad::ErrorStatus es; for (int i = 0;i < m_arAssocPartEntIds.length();i++) { id = m_arAssocPartEntIds.at(i); if ( Acad::eOk == (es = acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead))) { AecDbX3dPartEntity* pPartEnt = AecDbX3dPartEntity::cast(pEnt); if (pPartEnt != NULL) { AcDbVoidPtrArray arSolidPtrs; pPartEnt->GetForHouseSubtract(arSolidPtrs); for(int ii = 0;ii < arSolidPtrs.length();ii++) { pSolidPart = (AcDb3dSolid*)arSolidPtrs.at(ii) ; if (pSolidPart != NULL) { //TEST //AddToModelSpace((AcDbEntity*)pSolidPart->clone()); if ( Acad::eOk == (es = pSolid->booleanOper(AcDb::kBoolSubtract,pSolidPart) ) ) { //TEST //AddToModelSpace((AcDbEntity*)pSolidBasin->clone()); } else { acutPrintf(_T("\nSubtract Oper error:%d"),es); } } } } AecDbXOpening* pOpen = AecDbXOpening::cast(pEnt); if (pOpen != NULL) { AcDbVoidPtrArray arSolidPtrs; pOpen->GetForHouseSubtract(arSolidPtrs); for(int ii = 0;ii < arSolidPtrs.length();ii++) { pSolidPart = (AcDb3dSolid*)arSolidPtrs.at(ii) ; if (pSolidPart != NULL) { //TEST //AddToModelSpace((AcDbEntity*)pSolidPart->clone()); if ( Acad::eOk == (es = pSolid->booleanOper(AcDb::kBoolSubtract,pSolidPart) ) ) { //TEST //AddToModelSpace((AcDbEntity*)pSolidBasin->clone()); } else { acutPrintf(_T("\nSubtract Oper error:%d"),es); } } } } AecDbColumn* pCol = AecDbColumn::cast(pEnt); if (pCol != NULL) { AcDb3dSolid* pSolidDraw = pCol->GetDraw3dSolid(false); if (pSolidDraw != NULL) { if ( Acad::eOk == (es = pSolid->booleanOper(AcDb::kBoolSubtract,pSolidDraw) ) ) { //TEST //AddToModelSpace((AcDbEntity*)pSolidBasin->clone()); } else { acutPrintf(_T("\nSubtract Oper error:%d"),es); } } } pEnt->close(); } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::dwgInFields(AcDbDwgFiler* pFiler) { AssertWriteEnabled(); //----- Read parent class information first. Acad::ErrorStatus es = Acad::eOk; es = AecDbBDPipeBase::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 > AecDbXWall::kCurrentVersionNumber ) return (Acad::eMakeMeProxy) ; //2D m_drawable2d.dwgInFields(pFiler); m_drawable2d.OrthoProject2XY(); m_2dHideTail.dwgInFields(pFiler); return (pFiler->filerStatus ()); } Acad::ErrorStatus AecDbXWall::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); //----- Save parent class information first. Acad::ErrorStatus es = Acad::eOk; es = AecDbBDPipeBase::dwgOutFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; //----- Object version number needs to be saved first if ( (es =pFiler->writeUInt32 (AecDbXWall::kCurrentVersionNumber)) != Acad::eOk ) return (es) ; //2D m_drawable2d.dwgOutFields(pFiler); m_2dHideTail.dwgOutFields(pFiler); return (pFiler->filerStatus ()); } Acad::ErrorStatus AecDbXWall::dxfInFields(AcDbDxfFiler* pFiler) { AssertWriteEnabled(); return Acad::eOk; } Acad::ErrorStatus AecDbXWall::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); return Acad::eOk; } void AecDbXWall::subList() const { assertReadEnabled(); AecDbBDPipeBase::subList(); acutPrintf(_T("\n墙体:")); acutPrintf(_T("\n体积:%g 立方"),GetVolume() / 1.e9); } Acad::ErrorStatus AecDbXWall::subTransformBy(const AcGeMatrix3d& xform) { AssertWriteEnabled(); AecDbBDPipeBase::subTransformBy(xform); m_drawable2d.transformBy(xform); m_drawable2d.OrthoProject2XY(); m_2dHideTail.transformBy(xform); m_2dHideTail.OrthoProject2XY(); int nSecShape = 0; m_mapSpecXData.GetAt(KEY_SECSHAPE,nSecShape); //非VV墙体 放样线必须XY面 AcDbLine *pLn = AcDbLine::cast(m_pBaseCurve); if (pLn != NULL) { //XY AcGePoint3d ptS = pLn->startPoint(); AcGePoint3d ptE = pLn->endPoint(); AcGeVector3d vtDir = ptE - ptS; AcGeLine3d ln(AcGePoint3d::kOrigin, vtDir); if (ln.isParallelTo(AcGePlane::kXYPlane)) { if (nSecShape != eUserDef) { ptS.z = 0.0; ptE.z = 0.0; } pLn->setStartPoint(ptS); pLn->setEndPoint(ptE); } } AcDbArc *pArc = AcDbArc::cast(m_pBaseCurve); if (pArc != NULL) { AcGeVector3d vtN = pArc->normal(); if (vtN.isParallelTo(AcGeVector3d::kZAxis)) { AcGePoint3d ptC = pArc->center(); if (nSecShape != eUserDef) ptC.z = 0; pArc->setCenter(ptC); } } //底部标高的变换 double dZ = 0.0; m_mapSpecXData.GetAt(PIPE_EL,dZ); AcGePoint3d ptGe(0,0,dZ); ptGe.transformBy(xform); if ( nSecShape != eUserDef) { WallData data; GetWallData(data); // 基类的transformby函数已经变换了 PIPE_EL 的值,这里用 SetWallData 刷新就好。 // data.dBomEl = ptGe.z; SetWallData(data.dThick,data.dH,data.dThick2,data.dH2,data.nW2Pos,data.dBomEl,data.kAlign); } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::copyFrom(const AcRxObject* pSrc) { AecDbBDPipeBase::copyFrom(pSrc); //?????需要测试 --- 通过dwgin/out复制了??? /*AecDbXWall *pSrcWall = AecDbXWall::cast(pSrc); if (pSrcWall != NULL) { m_drawable2d.RemoveEdage(); m_drawable2d.copyFrom(pSrcWall->m_drawable2d); m_2dHideTail.RemoveEdage(); m_2dHideTail.copyFrom(pSrcWall->m_2dHideTail); }*/ return Acad::eOk; } //只比较结构信息 int AecDbXWall::ComparedTo(AecDbCurveBase* pCurOther) const { assertReadEnabled(); AecDbXWall* pOther = AecDbXWall::cast(pCurOther); if (pOther != NULL) { WallData data1; GetWallData(data1); WallData data2; pOther->GetWallData(data2); CString sNo1 = data1.szNO; CString sNo2 = data2.szNO; //长宽高,标高 if ( fabs(data1.dThick - data2.dThick) > 1.e-3) return 1; if ( fabs(data1.dH - data2.dH) > 1.e-3) return 1; if (data1.nSecShape == eWw && data2.nSecShape == eWw) { if (fabs(data1.dH2 - data2.dH2) > 1.e-3) return 1; if (fabs(data1.dThick2 - data2.dThick2) > 1.e-3) return 1; } if (fabs(data1.dBomEl - data2.dBomEl) > 1.e-3) return 1; double dLen1 = GetLength(); double dLen2 = pOther->GetLength(); if ( fabs(dLen1 - dLen2) > 5.0 )//5个毫米误差 return 1; //位置变化 AcGePoint3d ptS = StartPoint(); AcGePoint3d ptE = EndPoint(); AcGePoint3d ptS2 = pOther->StartPoint(); AcGePoint3d ptE2 = pOther->EndPoint(); if (ptS.distanceTo(ptS2) > 1.e-1) return 1; if (ptE.distanceTo(ptE2) > 1.e-1) return 1; //如果体积不同 //double dVol1 = GetVolume(); //double dVol2 = pOther->GetVolume(); //if ( fabs(dVol1 - dVol2) > 1.0) // return 1; //结构上相同 return 0; } return -1; } void AecDbXWall::merge() { AssertWriteEnabled(); m_drawable2d.merge(); } void AecDbXWall::boolSubtract() { AssertWriteEnabled(); m_drawable2d.boolSubtract(); } AcDbCurve* AecDbXWall::GetWall2dBound() const { assertReadEnabled(); //绘制主双线,融合 AcDbVoidPtrArray ar2D; GetStandardDraw2d(ar2D); AcDbVoidPtrArray arRes; AcDbCurve* pCurve = KTCADUtilityEx::ConvertBoundCurve(ar2D,arRes); return pCurve; } typedef float coord_t; // coordinate type typedef double coord2_t; // must be big enough to hold 2*max(|coordinate|)^2 struct Point2d { coord_t x, y; bool operator <(const Point2d &p) const { return x < p.x || (x == p.x && y < p.y); } }; extern std::vector convex_hull(std::vector P); AecEqui::AecCurveElement AecDbXWall::GetLeftDrawElement() const { assertReadEnabled(); AecComplexCurve draw2d; GetDraw2dables(draw2d); AcDbCurve *pLeft = GetLeftCurve(); AcGePoint3d ptOn; AcGePoint3dArray arPts; for (int i = 0; i < draw2d.length(); i++) { AecEqui::AecCurveElement &el = draw2d.atByRef(i); for (int j = 0;j < 3;j++) { pLeft->getClosestPointTo(el.ptGe[j], ptOn, Adesk::kTrue); if (ptOn.distanceTo(el.ptGe[j]) < 1.e-2) { if (arPts.find(el.ptGe[j]) == -1) arPts.append(el.ptGe[j]); } } } AcDbRay ln; AcDbCircle cir; AcDbCurve *pCrvTmp = NULL; AcDbLine *pLn = AcDbLine::cast(pLeft); if (pLn != NULL) { AcGeVector3d vtLn = pLn->endPoint() - pLn->startPoint(); ln.setBasePoint(pLn->startPoint()); ln.setUnitDir(vtLn); pCrvTmp = &ln; } AcDbArc *pArc = AcDbArc::cast(pLeft); if (pArc != NULL) { cir.setCenter(pArc->center()); cir.setRadius(pArc->radius()); cir.setNormal(pArc->normal()); pCrvTmp = ○ } AecEqui::AecCurveElement el; memset(&el, 0, sizeof(AecEqui::AecCurveElement)); if (arPts.isEmpty()) return el; AecCoverBooleanOper::SortPoints(arPts, pCrvTmp, false); if (pLn != NULL && arPts.length() >= 2) { pLn->setStartPoint(arPts.first()); pLn->setEndPoint(arPts.last()); el.ptGe[0] = pLn->startPoint(); el.ptGe[1] = pLn->endPoint(); el.ptGe[2] = pLn->endPoint(); } if (pArc != NULL && arPts.length() > 2) { AcDbArc *pArcT = FormatArc(arPts.first(), arPts.at(1), arPts.last()); double dSta = pArcT->startAngle(); double dEnd = pArcT->endAngle(); pArc->setStartAngle(dSta); pArc->setEndAngle(dEnd); delete pArcT; pArc->getStartPoint(el.ptGe[0]); pArc->getEndPoint(el.ptGe[2]); el.ptGe[1] = GetArcMidPoint(pArc); } delete pLeft; return el; } AecEqui::AecCurveElement AecDbXWall::GetRightDrawElement() const { assertReadEnabled(); AecComplexCurve draw2d; GetDraw2dables(draw2d); AcDbCurve *pRight = GetRightCurve(); AcGePoint3d ptOn; AcGePoint3dArray arPts; for (int i = 0; i < draw2d.length(); i++) { AecEqui::AecCurveElement &el = draw2d.atByRef(i); for (int j = 0; j < 3; j++) { pRight->getClosestPointTo(el.ptGe[j], ptOn, Adesk::kTrue); if (ptOn.distanceTo(el.ptGe[j]) < 1.e-2) { if (arPts.find(el.ptGe[j]) == -1) arPts.append(el.ptGe[j]); } } } AcDbRay ln; AcDbCircle cir; AcDbCurve *pCrvTmp = NULL; AcDbLine *pLn = AcDbLine::cast(pRight); if (pLn != NULL) { AcGeVector3d vtLn = pLn->endPoint() - pLn->startPoint(); ln.setBasePoint(pLn->startPoint()); ln.setUnitDir(vtLn); pCrvTmp = &ln; } AcDbArc *pArc = AcDbArc::cast(pRight); if (pArc != NULL) { cir.setCenter(pArc->center()); cir.setRadius(pArc->radius()); cir.setNormal(pArc->normal()); pCrvTmp = ○ } AecEqui::AecCurveElement el; memset(&el, 0, sizeof(AecEqui::AecCurveElement)); if (arPts.isEmpty()) return el; AecCoverBooleanOper::SortPoints(arPts, pCrvTmp, false); if (pLn != NULL && arPts.length() >= 2) { pLn->setStartPoint(arPts.first()); pLn->setEndPoint(arPts.last()); el.ptGe[0] = pLn->startPoint(); el.ptGe[1] = pLn->endPoint(); el.ptGe[2] = pLn->endPoint(); } if (pArc != NULL && arPts.length() > 2) { AcDbArc *pArcT = FormatArc(arPts.first(), arPts.at(1), arPts.last()); double dSta = pArcT->startAngle(); double dEnd = pArcT->endAngle(); pArc->setStartAngle(dSta); pArc->setEndAngle(dEnd); delete pArcT; pArc->getStartPoint(el.ptGe[0]); pArc->getEndPoint(el.ptGe[2]); el.ptGe[1] = GetArcMidPoint(pArc); } delete pRight; return el; } AcDbPolyline* AecDbXWall::GetWall2dBoundary() const { assertReadEnabled(); AecEqui::AecCurveElement elL = GetLeftDrawElement(); AecEqui::AecCurveElement elR = GetRightDrawElement(); if (elL.ptGe[0].distanceTo(elL.ptGe[1]) < 1.e-3 || elR.ptGe[0].distanceTo(elR.ptGe[1]) < 1.e-3) { AcDbPolyline *pPlB = AcDbPolyline::cast(GetWall2dBound()); return pPlB; } AcDbCurve *pCurve = GetNativeCurve(); AcDbArc *pArc = AcDbArc::cast(pCurve); AcGePoint3dArray arPts; arPts.append(elL.ptGe[0]); arPts.append(elL.ptGe[2]); if (pArc != NULL) { arPts.append(elL.ptGe[1]); } AecCoverBooleanOper::SortPoints(arPts, pCurve, false); AcGePoint3d ptLSE[2]; ptLSE[0] = arPts.first(); ptLSE[1] = arPts.last(); arPts.removeAll(); arPts.append(elR.ptGe[0]); arPts.append(elR.ptGe[2]); if (pArc != NULL) { arPts.append(elR.ptGe[1]); } AecCoverBooleanOper::SortPoints(arPts, pCurve, false); AcGePoint3d ptRSE[2]; ptRSE[0] = arPts.first(); ptRSE[1] = arPts.last(); AcDbVoidPtrArray arCurPtrs, arRes; AcDbLine *pLn1 = new AcDbLine(ptLSE[0], ptRSE[0]); pLn1->setNormal(AcGeVector3d::kZAxis); arCurPtrs.append(pLn1); AcDbCurve *pCrv = NULL; AecComplexCurve::MakeCurve(elL, pCrv); if (pCrv != NULL) { arCurPtrs.append(pCrv); } pLn1 = new AcDbLine(ptLSE[1], ptRSE[1]); pLn1->setNormal(AcGeVector3d::kZAxis); arCurPtrs.append(pLn1); pCrv = NULL; AecComplexCurve::MakeCurve(elR, pCrv); if (pCrv != NULL) { arCurPtrs.append(pCrv); } pCrv = KTCADUtilityEx::ConvertBoundCurve(arCurPtrs, arRes); AcDbPolyline *pPlt = AcDbPolyline::cast(pCrv); return pPlt; //OLD CODE AecComplexCurve draw2d; GetDraw2dables(draw2d); Point2d pt2d; std::vector pt2ds; for (int ii = 0;ii < draw2d.length();ii++) { AecEqui::AecCurveElement& el = draw2d.atByRef(ii); pt2d.x = el.ptGe[0].x;pt2d.y = el.ptGe[0].y; pt2ds.push_back(pt2d); pt2d.x = el.ptGe[2].x;pt2d.y = el.ptGe[2].y; pt2ds.push_back(pt2d); } AcDbPolyline* pPl = new AcDbPolyline; pPl->setColorIndex(3); std::vector pt2ds2 = convex_hull(pt2ds); for (int i = 0;i < pt2ds2.size();i++) { Point2d pt = pt2ds2.at(i); pPl->addVertexAt(i,AcGePoint2d(pt.x,pt.y)); } return pPl; } AcDbCurve* AecDbXWall::GetLeftCurve() const { assertReadEnabled(); BOOL bIsVView = FALSE; m_mapSpecXData.GetAt(KEY_VVIEW,bIsVView); if (bIsVView)//立面拉出的墙体 { AcDbCurve* pLeft = NULL; if (m_pRegion != NULL && m_pBaseCurve != NULL) { AcDbCurve* pCurve = m_pBaseCurve; //1.创建整体Solid AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); AcGePoint3d ptStart(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptStart); AcGePoint3d ptEnd; pCurve->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pCurve->getFirstDeriv(ptStart, vtNormal); AcDbRegion* pCloneRegion = (AcDbRegion*)m_pRegion->clone(); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd); AcDbLine* pLn1 = GetOrthoProjectOnXY(pCloneRegion); delete pCloneRegion; pLeft = pLn1; } return pLeft; } AcDbCurve* pBase = GetBaseCurve(); //异形截面墙体 int nShape = 0; m_mapSpecXData.GetAt(KEY_SECSHAPE,nShape); if (nShape == eUserDef) { AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); AcGePoint3d ptStart(AcGePoint3d::kOrigin); pBase->getStartPoint(ptStart); AcGePoint3d ptEnd; pBase->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pBase->getFirstDeriv(ptStart, vtNormal); AcDbRegion *pCloneRegion = (AcDbRegion*)m_pRegion->clone(); if (pCloneRegion != NULL) { transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptStart); AcDbLine* pLn1 = GetOrthoProjectOnXY(pCloneRegion); delete pCloneRegion; pCloneRegion = (AcDbRegion*)m_pRegion->clone(); pBase->getFirstDeriv(ptEnd, vtNormal); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd); AcDbLine* pLn2 = GetOrthoProjectOnXY(pCloneRegion); delete pCloneRegion; if (pBase != NULL && pLn1 != NULL && pLn2 != NULL) { AcGeVector3d vtL;//左线方向 AcGeVector3d vtT; AcDbLine* pLine = AcDbLine::cast(pBase); if (pLine != NULL) { vtL = pLine->endPoint() - pLine->startPoint(); vtL.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtL.normalize(); AcGePoint3d ptT; vtT = pLn1->endPoint() - pLn1->startPoint(); if (vtT.dotProduct(vtL) > 1.e-10) { } else { ptT = pLn1->startPoint(); pLn1->setStartPoint(pLn1->endPoint()); pLn1->setEndPoint(ptT); } vtT = pLn2->endPoint() - pLn2->startPoint(); if (vtT.dotProduct(vtL) > 1.e-10) { } else { ptT = pLn2->startPoint(); pLn2->setStartPoint(pLn2->endPoint()); pLn2->setEndPoint(ptT); } pLine->setStartPoint(pLn1->endPoint()); pLine->setEndPoint(pLn2->endPoint()); delete pLn1; delete pLn2; return pLine; } AcDbArc* pArc = AcDbArc::cast(pBase); if (pArc != NULL) { pArc->getStartPoint(ptStart); vtL = ptStart - pArc->center(); AcGePoint3d ptT; vtT = pLn1->endPoint() - pLn1->startPoint(); if (vtT.dotProduct(vtL) > 1.e-10) { } else { ptT = pLn1->startPoint(); pLn1->setStartPoint(pLn1->endPoint()); pLn1->setEndPoint(ptT); } ptT = pArc->center(); ptT.z = 0.0;//orth to xy double dR = pLn1->endPoint().distanceTo(ptT); pArc->setRadius(dR); delete pLn1; delete pLn2; return pArc; } AcDbCircle* pCir = AcDbCircle::cast(pBase); if (pCir != NULL) { pCir->getStartPoint(ptStart); vtL = ptStart - pCir->center(); AcGePoint3d ptT; vtT = pLn1->endPoint() - pLn1->startPoint(); if (vtT.dotProduct(vtL) > 1.e-10) { } else { ptT = pLn1->startPoint(); pLn1->setStartPoint(pLn1->endPoint()); pLn1->setEndPoint(ptT); } ptT = pCir->center(); ptT.z = 0.0;//orth on xy double dR = pLn1->endPoint().distanceTo(ptT); pCir->setRadius(dR); delete pLn1; delete pLn2; return pCir; } //... } } return NULL; } //标准墙体 if (pBase != NULL) { AcGeVector3d vtLine; WallData data; GetWallData(data); AcDbLine* pLine = AcDbLine::cast(pBase); if (pLine != NULL) { vtLine = pLine->endPoint() - pLine->startPoint(); vtLine.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtLine.normalize(); switch(data.kAlign) { case kLeft: { break; } case kMid: { vtLine *= -0.5 * data.dThick; break; } case kRight: { vtLine *= -data.dThick; break; } default: break; } AcGeMatrix3d xform; xform.setToTranslation(vtLine); pLine->setNormal(AcGeVector3d::kZAxis); pLine->transformBy(xform); return pLine; } AcDbArc* pArc = AcDbArc::cast(pBase); if (pArc != NULL) { double dR = pArc->radius(); switch(data.kAlign) { case kLeft: { break; } case kMid: { pArc->setRadius(dR - 0.5 * data.dThick); break; } case kRight: { pArc->setRadius(dR - data.dThick); break; } default: break; } return pArc; } AcDbCircle* pCir = AcDbCircle::cast(pBase); if (pCir != NULL) { AcDbArc* pArcT = new AcDbArc; pArcT->setStartAngle(0.0); pArcT->setEndAngle(2.0 * PI - 1.e-6);//接近圆 switch(data.kAlign) { case kLeft: { pArcT->setRadius(pCir->radius()); break; } case kMid: { pArcT->setRadius(pCir->radius() - 0.5 * data.dThick); break; } case kRight: { pArcT->setRadius(pCir->radius() - data.dThick); break; } default: break; } pArcT->setCenter(pCir->center()); delete pBase; return pArcT; } AcDbEllipse* pEllp = AcDbEllipse::cast(pBase); if (pEllp != NULL) { AcGeVector3d vtMaj = pEllp->majorAxis(); double radRatio = pEllp->radiusRatio(); double dMaj = vtMaj.length(); double dMin = pEllp->minorAxis().length(); switch(data.kAlign) { case kLeft: { break; } case kMid: { dMaj -= 0.5 * data.dThick; dMin -= 0.5 * data.dThick; radRatio = dMin / dMaj; break; } case kRight: { dMaj -= data.dThick; dMin -= data.dThick; radRatio = dMin / dMaj; break; } default: break; } vtMaj.normalize(); vtMaj *= dMaj; AcDbEllipse* pEllArc = new AcDbEllipse; pEllArc->set(pEllp->center(),pEllp->normal(),vtMaj,radRatio); //折算为PL delete pBase; return pEllArc; } //其他未知 delete pBase; } return NULL; } bool AecDbXWall::GetInsideCurves(AcDbVoidPtrArray& arCurves) const { assertReadEnabled(); //如果是异形截面 int nShape = 0; m_mapSpecXData.GetAt(KEY_SECSHAPE,nShape); if (nShape == eUserDef) { AcDb3dSolid* pSolidDraw = GetDraw3dSolid(false); if (pSolidDraw != NULL) { AcGeMatrix3d xform; OrthoProjected3DSolid(pSolidDraw,AcGePlane::kXYPlane,xform,arCurves); delete pSolidDraw; } } //立面拉强和内线相交的保留 BOOL bIsVView = FALSE; m_mapSpecXData.GetAt(KEY_VVIEW,bIsVView); if (bIsVView) { AcDbCurve* pRight = NULL; if (m_pRegion != NULL && m_pBaseCurve != NULL) { AcDbCurve* pCurve = m_pBaseCurve; //1.创建整体Solid AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); AcGePoint3d ptStart(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptStart); AcGePoint3d ptEnd; pCurve->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pCurve->getFirstDeriv(ptStart, vtNormal); AcDbRegion* pCloneRegion = (AcDbRegion*)m_pRegion->clone(); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptStart); AcDbLine* pLn2 = GetOrthoProjectOnXY(pCloneRegion); if (pLn2 != NULL) { AcGePoint3d ptS,ptE,ptOn; ptS = pLn2->startPoint(); ptE = pLn2->endPoint(); AcDbCurve* pCurve = NULL; AcGePoint3dArray arPts; for (int i = 0;i < arCurves.length();i++) { pCurve = (AcDbCurve*)arCurves.at(i); arPts.removeAll(); pLn2->intersectWith(pCurve,AcDb::kOnBothOperands,arPts); if (arPts.length() == 1) { ptOn = arPts.first(); if (ptS.distanceTo(ptOn) < 1.e-1 || ptE.distanceTo(ptOn) < 1.e-1) { arCurves.removeAt(i); delete pCurve; i -= 1; } } else { arCurves.removeAt(i); delete pCurve; i -= 1; } } } delete pCloneRegion; } } return true; } AcDbCurve* AecDbXWall::GetMidCurve() const { assertReadEnabled(); return GetBaseCurve(); } AcDbCurve* AecDbXWall::GetRightCurve() const { assertReadEnabled(); BOOL bIsVView = FALSE; m_mapSpecXData.GetAt(KEY_VVIEW,bIsVView); if (bIsVView) { AcDbCurve* pRight = NULL; if (m_pRegion != NULL && m_pBaseCurve != NULL) { AcDbCurve* pCurve = m_pBaseCurve; //1.创建整体Solid AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); AcGePoint3d ptStart(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptStart); AcGePoint3d ptEnd; pCurve->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pCurve->getFirstDeriv(ptStart, vtNormal); AcDbRegion* pCloneRegion = (AcDbRegion*)m_pRegion->clone(); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptStart); AcDbLine* pLn2 = GetOrthoProjectOnXY(pCloneRegion); pRight = pLn2; delete pCloneRegion; } return pRight; } AcDbCurve* pBase = GetBaseCurve(); //异形截面墙体 //异形截面墙体 int nShape = 0; m_mapSpecXData.GetAt(KEY_SECSHAPE,nShape); if (nShape == eUserDef) { AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); AcGePoint3d ptStart(AcGePoint3d::kOrigin); pBase->getStartPoint(ptStart); AcGePoint3d ptEnd; pBase->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pBase->getFirstDeriv(ptStart, vtNormal); AcDbRegion *pCloneRegion = (AcDbRegion*)m_pRegion->clone(); if (pCloneRegion != NULL) { transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptStart); AcDbLine* pLn1 = GetOrthoProjectOnXY(pCloneRegion); delete pCloneRegion; pCloneRegion = (AcDbRegion*)m_pRegion->clone(); pBase->getFirstDeriv(ptEnd, vtNormal); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd); AcDbLine* pLn2 = GetOrthoProjectOnXY(pCloneRegion); delete pCloneRegion; if (pBase != NULL && pLn1 != NULL && pLn2 != NULL) { AcGeVector3d vtL;//左线方向 AcGeVector3d vtT; AcDbLine* pLine = AcDbLine::cast(pBase); if (pLine != NULL) { vtL = pLine->endPoint() - pLine->startPoint(); vtL.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtL.normalize(); AcGePoint3d ptT; vtT = pLn1->endPoint() - pLn1->startPoint(); if (vtT.dotProduct(vtL) > 1.e-10) { } else { ptT = pLn1->startPoint(); pLn1->setStartPoint(pLn1->endPoint()); pLn1->setEndPoint(ptT); } vtT = pLn2->endPoint() - pLn2->startPoint(); if (vtT.dotProduct(vtL) > 1.e-10) { } else { ptT = pLn2->startPoint(); pLn2->setStartPoint(pLn2->endPoint()); pLn2->setEndPoint(ptT); } pLine->setStartPoint(pLn1->startPoint()); pLine->setEndPoint(pLn2->startPoint()); delete pLn1; delete pLn2; return pLine; } AcDbArc* pArc = AcDbArc::cast(pBase); if (pArc != NULL) { pArc->getStartPoint(ptStart); vtL = ptStart - pArc->center(); AcGePoint3d ptT; vtT = pLn1->endPoint() - pLn1->startPoint(); if (vtT.dotProduct(vtL) > 1.e-10) { } else { ptT = pLn1->startPoint(); pLn1->setStartPoint(pLn1->endPoint()); pLn1->setEndPoint(ptT); } ptT = pArc->center(); ptT.z = 0.0;//orth xy double dR = pLn1->startPoint().distanceTo(ptT); pArc->setRadius(dR); delete pLn1; delete pLn2; return pArc; } AcDbCircle* pCir = AcDbCircle::cast(pBase); if (pCir != NULL) { pCir->getStartPoint(ptStart); vtL = ptStart - pCir->center(); AcGePoint3d ptT; vtT = pLn1->endPoint() - pLn1->startPoint(); if (vtT.dotProduct(vtL) > 1.e-10) { } else { ptT = pLn1->startPoint(); pLn1->setStartPoint(pLn1->endPoint()); pLn1->setEndPoint(ptT); } ptT = pCir->center(); ptT.z = 0.0;//orth xy double dR = pLn1->startPoint().distanceTo(ptT); pCir->setRadius(dR); delete pLn1; delete pLn2; return pCir; } //... } } return NULL; } //标准墙体 if (pBase != NULL) { AcGeVector3d vtLine; WallData data; GetWallData(data); AcDbLine* pLine = AcDbLine::cast(pBase); if (pLine != NULL) { vtLine = pLine->endPoint() - pLine->startPoint(); vtLine.rotateBy(-PI / 2.0,AcGeVector3d::kZAxis); vtLine.normalize(); switch(data.kAlign) { case kLeft: { vtLine *= -data.dThick; break; } case kMid: { vtLine *= -0.5 * data.dThick; break; } case kRight: { break; } default: break; } AcGeMatrix3d xform; xform.setToTranslation(vtLine); pLine->transformBy(xform); return pLine; } AcDbArc* pArc = AcDbArc::cast(pBase); if (pArc != NULL) { double dR = pArc->radius(); switch(data.kAlign) { case kLeft: { pArc->setRadius(dR + data.dThick); break; } case kMid: { pArc->setRadius(dR + 0.5 * data.dThick); break; } case kRight: { break; } default: break; } return pArc; } AcDbCircle* pCir = AcDbCircle::cast(pBase); if (pCir != NULL) { AcDbArc* pArcT = new AcDbArc; pArcT->setStartAngle(0.0); pArcT->setEndAngle(2.0 * PI - 1.e-6);//接近圆 switch(data.kAlign) { case kLeft: { pArcT->setRadius(pCir->radius() + data.dThick); break; } case kMid: { pArcT->setRadius(pCir->radius() + 0.5 * data.dThick); break; } case kRight: { pArcT->setRadius(pCir->radius()); break; } default: break; } pArcT->setCenter(pCir->center()); delete pBase; return pArcT; } AcDbEllipse* pEllp = AcDbEllipse::cast(pBase); if (pEllp != NULL) { AcGeVector3d vtMaj = pEllp->majorAxis(); double radRatio = pEllp->radiusRatio(); double dMaj = vtMaj.length(); double dMin = pEllp->minorAxis().length(); switch(data.kAlign) { case kLeft: { dMaj += data.dThick; dMin += data.dThick; radRatio = dMin / dMaj; break; } case kMid: { dMaj += 0.5 * data.dThick; dMin += 0.5 * data.dThick; radRatio = dMin / dMaj; break; } case kRight: { break; } default: break; } vtMaj.normalize(); vtMaj *= dMaj; AcDbEllipse* pEllArc = new AcDbEllipse; pEllArc->set(pEllp->center(),pEllp->normal(),vtMaj,radRatio); delete pBase; return pEllArc; } //其他未知 delete pBase; } return NULL; } AecEqui::AecCurveElement AecDbXWall::GetLeftElement(bool bRealLeft /*= false*/) const { assertReadEnabled(); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); AcDbCurve* pL = GetLeftCurve(); if (pL != NULL) { AcDbLine* pLn = AcDbLine::cast(pL); if (pLn != NULL) { el.ptGe[0] = pLn->startPoint(); el.ptGe[1] = pLn->endPoint(); el.ptGe[2] = pLn->endPoint(); } AcDbArc* pArc = AcDbArc::cast(pL); if (pArc != NULL) { pArc->getStartPoint(el.ptGe[0]); pArc->getEndPoint(el.ptGe[2]); el.ptGe[1] = GetArcMidPoint(pArc); } if (m_drawable2d.HasEdage() && pL != NULL && !bRealLeft)//是直线的情况 { AecComplexCurve cmpl; m_drawable2d.GetEdage(cmpl); AcGeVector3d vt1,vt2; for (int j = 0;j < cmpl.length();j++) { AecEqui::AecCurveElement& eT = cmpl.atByRef(j); //判断共线 if (IsOnCurve(pL,eT)) { el = eT; break; } } } delete pL; } return el; } AecEqui::AecCurveElement AecDbXWall::GetMidElement() const { assertReadEnabled(); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); AcDbCurve* pL = GetMidCurve(); if (pL != NULL) { AcDbLine* pLn = AcDbLine::cast(pL); if (pLn != NULL) { el.ptGe[0] = pLn->startPoint(); el.ptGe[1] = pLn->endPoint(); el.ptGe[2] = pLn->endPoint(); } AcDbArc* pArc = AcDbArc::cast(pL); if (pArc != NULL) { pArc->getStartPoint(el.ptGe[0]); pArc->getEndPoint(el.ptGe[2]); el.ptGe[1] = GetArcMidPoint(pArc); } delete pL; } return el; } AecEqui::AecCurveElement AecDbXWall::GetRightElement(bool bRealRight/* = false*/) const { assertReadEnabled(); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); AcDbCurve* pL = GetRightCurve(); if (pL != NULL) { AcDbLine* pLn = AcDbLine::cast(pL); if (pLn != NULL) { el.ptGe[0] = pLn->startPoint(); el.ptGe[1] = pLn->endPoint(); el.ptGe[2] = pLn->endPoint(); } AcDbArc* pArc = AcDbArc::cast(pL); if (pArc != NULL) { pArc->getStartPoint(el.ptGe[0]); pArc->getEndPoint(el.ptGe[2]); el.ptGe[1] = GetArcMidPoint(pArc); } delete pL; } if (m_drawable2d.HasEdage() && pL != NULL && !bRealRight)//是直线的情况 { AecComplexCurve cmpl; m_drawable2d.GetEdage(cmpl); AcGeVector3d vt1,vt2; for (int j = 0;j < cmpl.length();j++) { AecEqui::AecCurveElement& eT = cmpl.atByRef(j); //判断共线 vt1 = eT.ptGe[0] - el.ptGe[2]; vt2 = eT.ptGe[2] - el.ptGe[0]; if (vt1.isParallelTo(vt2)) { el = eT; break; } } } return el; } static void ConvertToNEls(AcDbCurve* pER,AecComplexCurve& cmpl,int nSegs) { AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); int nPoints = nSegs + 1; double dSta = 0.0,dEnd = 0.0; pER->getStartParam(dSta); pER->getEndParam(dEnd); double dStep = (dEnd - dSta) / nPoints; AcGePoint3d pt; AcGePoint3dArray arPts; for (int i = 0;i < nPoints;i++) { pER->getPointAtParam(dSta + i * dStep,pt); if (!arPts.isEmpty()) { el.ptGe[0] = arPts.last(); el.ptGe[1] = pt; el.ptGe[2] = pt; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); } arPts.append(pt); } } AcDbLine* AecDbXWall::GetOrthoProjectOnXY(AcDbRegion* pRegion) { AcDbLine* pLn = NULL; if (pRegion != NULL)//前提是Region垂直XY面 { AcGeVector3d vtNorm; pRegion->getNormal(vtNorm); AcGePlane plan; pRegion->getPlane(plan); AcGePoint3d ptOrg; AcGeVector3d vtX,vtY; plan.get(ptOrg,vtX,vtY); AcGeLine3d ln; ln.set(AcGePoint3d::kOrigin,vtNorm); if (ln.isParallelTo(AcGePlane::kXYPlane)) { AcDbExtents ext; pRegion->getGeomExtents(ext); AcGePoint3d ptSta = ext.minPoint(); ptSta.z = 0.0; AcGePoint3d ptEnd = ext.maxPoint(); ptEnd.z = 0.0; pLn = new AcDbLine; pLn->setStartPoint(ptSta); pLn->setEndPoint(ptEnd); } } return pLn; } void AecDbXWall::GetOrthoProjectOnXY(AcDbRegion* pRegion,AcGePoint3dArray& arPts) { if (pRegion != NULL) { AcDbVoidPtrArray arEntPtrs; pRegion->explode(arEntPtrs); AcGePoint3d ptS,ptE; AcDbVoidPtrArray arCurs; AcDbEntity* pEnt = NULL; for (int i = 0;i < arEntPtrs.length();i++) { pEnt = (AcDbEntity*)arEntPtrs.at(i); AcDbCurve* pCurve = AcDbCurve::cast(pEnt); if (pCurve != NULL) { AcDbPolyline* pPl = AcDbPolyline::cast(pCurve); if (pPl != NULL) { for (int i = 0;i < pPl->numVerts();i++) { pPl->getPointAt(i,ptS); if (arPts.find(ptS) == -1) arPts.append(ptS); } delete pPl; } else { pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); if (arPts.find(ptS) == -1) arPts.append(ptS); if (arPts.find(ptE) == -1) arPts.append(ptE); } } else { delete pEnt; } } } } bool AecDbXWall::GetStandardDraw2d(AecComplexCurveDraw& draw2d,bool bHasEnd/* = true*/) const { AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); AecComplexCurve cmpl; BOOL bIsVView = FALSE; m_mapSpecXData.GetAt(KEY_VVIEW,bIsVView); if (bIsVView)//立面墙体 { // AcDbRegion* pRegionWall = m_pRegion; AcDbCurve* pCurve = m_pBaseCurve; if (pRegionWall != NULL && pCurve != NULL) { //1.创建整体Solid AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); AcGePoint3d ptStart(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptStart); AcGePoint3d ptEnd; pCurve->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pCurve->getFirstDeriv(ptStart, vtNormal); AcDbRegion *pCloneRegion = (AcDbRegion*)m_pRegion->clone(); if (pCloneRegion != NULL) { transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptStart); AcDbLine* pLn1 = GetOrthoProjectOnXY(pCloneRegion); delete pCloneRegion; pCloneRegion = (AcDbRegion*)m_pRegion->clone(); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd); AcDbLine* pLn2 = GetOrthoProjectOnXY(pCloneRegion); delete pCloneRegion; if (pLn1 != NULL) { el.ptGe[0] = pLn1->startPoint(); el.ptGe[1] = pLn1->endPoint(); el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); } if (pLn2 != NULL) { el.ptGe[0] = pLn2->startPoint(); el.ptGe[1] = pLn2->endPoint(); el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); } if (pLn1 != NULL && pLn2 != NULL) { el.ptGe[0] = pLn1->startPoint(); el.ptGe[1] = pLn2->startPoint(); el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); el.ptGe[0] = pLn1->endPoint(); el.ptGe[1] = pLn2->endPoint(); el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); delete pLn1;delete pLn2; } } } if (!cmpl.isEmpty()) { cmpl.OrthoProjectedToXYPlane(); draw2d.SetEdage(cmpl); } return !cmpl.isEmpty(); } //标准墙体 AcDbCurve* pLeft = GetLeftCurve(); AcDbCurve* pRight = GetRightCurve(); if (pLeft != NULL && pRight != NULL) { //直墙 AcDbLine* pLnL = AcDbLine::cast(pLeft); AcDbLine* pLnR = AcDbLine::cast(pRight); if (pLnL != NULL && pLnR != NULL) { el.ptGe[0] = pLnL->startPoint(); el.ptGe[1] = pLnL->endPoint(); el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); el.ptGe[0] = pLnR->startPoint(); el.ptGe[1] = pLnR->endPoint(); el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); } //弧形墙 AcDbArc* pArcL = AcDbArc::cast(pLeft); AcDbArc* pArcR = AcDbArc::cast(pRight); if (pArcL != NULL && pArcR != NULL) { if (m_pBaseCurve->isKindOf(AcDbCircle::desc()))//圆墙 { //L AcGePoint3d ptCen = pArcL->center(); double dR = pArcL->radius(); el.ptGe[0] = ptCen; el.ptGe[0].x += dR; el.ptGe[1] = ptCen; el.ptGe[1].y += dR; el.ptGe[2] = ptCen; el.ptGe[2].x -= dR; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); el.ptGe[1].y -= 2.0 * dR; cmpl.append(el); ptCen = pArcR->center(); dR = pArcR->radius(); el.ptGe[0] = ptCen; el.ptGe[0].x += dR; el.ptGe[1] = ptCen; el.ptGe[1].y += dR; el.ptGe[2] = ptCen; el.ptGe[2].x -= dR; cmpl.append(el); el.ptGe[1].y -= 2.0 * dR; cmpl.append(el); } else { pArcL->getStartPoint(el.ptGe[0]); pArcL->getEndPoint(el.ptGe[2]); el.ptGe[1] = GetArcMidPoint(pArcL); el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); pArcR->getStartPoint(el.ptGe[0]); pArcR->getEndPoint(el.ptGe[2]); el.ptGe[1] = GetArcMidPoint(pArcR); el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); } } AcDbCircle* pCirL = AcDbCircle::cast(pLeft); AcDbCircle* pCirR = AcDbCircle::cast(pRight); if (pCirL != NULL && pCirR != NULL) { //L AcGePoint3d ptCen = pCirL->center(); double dR = pCirL->radius(); el.ptGe[0] = ptCen; el.ptGe[0].x += dR; el.ptGe[1] = ptCen; el.ptGe[1].y += dR; el.ptGe[2] = ptCen; el.ptGe[2].x -= dR; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; cmpl.append(el); el.ptGe[1].y -= 2.0 * dR; cmpl.append(el); ptCen = pCirL->center(); dR = pCirR->radius(); el.ptGe[0] = ptCen; el.ptGe[0].x += dR; el.ptGe[1] = ptCen; el.ptGe[1].y += dR; el.ptGe[2] = ptCen; el.ptGe[2].x -= dR; cmpl.append(el); el.ptGe[1].y -= 2.0 * dR; cmpl.append(el); } AcDbEllipse* pEL = AcDbEllipse::cast(pLeft); AcDbEllipse* pER = AcDbEllipse::cast(pRight); if (pEL != NULL && pER != NULL) { //变成n根直线段 ConvertToNEls(pEL,cmpl,40); ConvertToNEls(pER,cmpl,40); } //圆墙已经折算成弧墙0-359.98888 if (m_pBaseCurve->isKindOf(AcDbCircle::desc()) ||//圆墙 m_pBaseCurve->isKindOf(AcDbEllipse::desc()))//椭圆墙 { //... } else { //封口线 AecComplexCurve cmplSE; pLeft->getStartPoint(el.ptGe[0]); pRight->getStartPoint(el.ptGe[1]); el.ptGe[2] = el.ptGe[1]; el.gsMark = 1; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; if (bHasEnd) cmpl.append(el); cmplSE.append(el); pLeft->getEndPoint(el.ptGe[0]); pRight->getEndPoint(el.ptGe[1]); el.ptGe[2] = el.ptGe[1]; el.gsMark = 2; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; if (bHasEnd) cmpl.append(el); cmplSE.append(el); cmplSE.OrthoProjectedToXYPlane(); m_2dHideTail.SetEdage(cmplSE); } // cmpl.OrthoProjectedToXYPlane(); draw2d.SetEdage(cmpl); delete pLeft; delete pRight; } return true; } bool AecDbXWall::GetStandardDraw2d(AecComplexCurve& draw2d,bool bHasEnd/* = true*/) const { assertReadEnabled(); AecComplexCurveDraw edge; GetStandardDraw2d(edge,bHasEnd); edge.GetEdage(draw2d); return true; } bool AecDbXWall::GetStandardDraw2d(AcDbVoidPtrArray& draw2d,bool bHasEnd/* = true*/) const { BOOL bIsVView = FALSE; m_mapSpecXData.GetAt(KEY_VVIEW,bIsVView); if (bIsVView) { AcDbRegion* pRegionWall = m_pRegion; AcDbCurve* pCurve = m_pBaseCurve; if (pRegionWall != NULL && pCurve != NULL) { //1.创建整体Solid AcGePoint3d ptOnRegion; m_mapSpecXData.GetAt(KEY_SECCEN,ptOnRegion); double dSta = 0.0; pCurve->getStartParam(dSta); AcGeVector3d vtDir; pCurve->getFirstDeriv(dSta,vtDir); AcGePoint3d ptOnPlan; pCurve->getStartPoint(ptOnPlan); AcGeVector3d vtNormReg; pRegionWall->getNormal(vtNormReg); if (vtNormReg.isParallelTo(vtDir))//平行,立面拉成的墙体 { //立面墙体 AcDbVoidPtrArray arCurPtrs,arRelt; pRegionWall->explode(arCurPtrs); //取出点 AcGePoint3d pt1,pt2; AcGePoint3dArray arPts; AcDbCurve* pCrvTmp = NULL; for (int k = 0;k < arCurPtrs.length();k++) { pCrvTmp = (AcDbCurve*)arCurPtrs.at(k); if (pCrvTmp != NULL) { pCrvTmp->getStartPoint(pt1); pCrvTmp->getEndPoint(pt2); //投影到XY pt1.z = 0.0; pt2.z = 0.0; if (arPts.find(pt1) == -1) { arPts.append(pt1); } if (arPts.find(pt2) == -1) { arPts.append(pt2); } } } if (!arPts.isEmpty()) { AecCoverBooleanOper::SortPoints(arPts,pCrvTmp); pt1 = arPts.first(); pt2 = arPts.last(); AcDbLine* pLn = AcDbLine::cast(m_pBaseCurve); if (pLn != NULL) { AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); AcGeVector3d vtV = pLn->endPoint() - pLn->startPoint(); AcGeVector3d vtL = pt2 - pt1; AcGeVector3d vtLV = vtL;vtLV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); if (!vtLV.isCodirectionalTo(vtV)) vtV.negate(); AcDbLine* pLn = NULL; el.ptGe[0] = pt1; el.ptGe[0] += 0.5 * vtV; el.ptGe[1] = pt2; el.ptGe[1] += 0.5 * vtV; el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; AecComplexCurve::MakeLine(el,pLn); if (pLn != NULL) { pLn->setNormal(AcGeVector3d::kZAxis); draw2d.append(pLn); } pLn = NULL; el.ptGe[0] = pt1; el.ptGe[0] -= 0.5 * vtV; el.ptGe[1] = pt2; el.ptGe[1] -= 0.5 * vtV; el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; AecComplexCurve::MakeLine(el,pLn); if (pLn != NULL) { pLn->setNormal(AcGeVector3d::kZAxis); draw2d.append(pLn); } //端线 pLn = NULL; el.ptGe[0] = pt1; el.ptGe[0] += 0.5 * vtV; el.ptGe[1] = pt1; el.ptGe[1] -= 0.5 * vtV; el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; AecComplexCurve::MakeLine(el,pLn); if (pLn != NULL) { pLn->setNormal(AcGeVector3d::kZAxis); draw2d.append(pLn); } pLn = NULL; el.ptGe[0] = pt2; el.ptGe[0] += 0.5 * vtV; el.ptGe[1] = pt2; el.ptGe[1] -= 0.5 * vtV; el.ptGe[2] = el.ptGe[1]; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; AecComplexCurve::MakeLine(el,pLn); if (pLn != NULL) { pLn->setNormal(AcGeVector3d::kZAxis); draw2d.append(pLn); } } } FreeBuffer(0,arCurPtrs); } } return !draw2d.isEmpty(); } //异形截面墙体 //标准墙体 AcDbCurve* pLeft = GetLeftCurve(); AcDbCurve* pRight = GetRightCurve(); if (pLeft != NULL && pRight != NULL) { //直墙 AcDbLine* pLnL = AcDbLine::cast(pLeft); AcDbLine* pLnR = AcDbLine::cast(pRight); if (pLnL != NULL && pLnR != NULL) { draw2d.append(pLeft); draw2d.append(pRight); } //弧形墙 AcDbArc* pArcL = AcDbArc::cast(pLeft); AcDbArc* pArcR = AcDbArc::cast(pRight); if (pArcL != NULL && pArcR != NULL) { draw2d.append(pLeft); draw2d.append(pRight); } //圆墙 已经折算成弧墙 0-359.9888 AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); //封口线 if (bHasEnd) { AcDbLine* pLnT = NULL; pLeft->getStartPoint(el.ptGe[0]); pRight->getStartPoint(el.ptGe[1]); el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; pLnT = new AcDbLine(el.ptGe[0],el.ptGe[1]); pLnT->setNormal(AcGeVector3d::kZAxis); draw2d.append(pLnT); pLeft->getEndPoint(el.ptGe[0]); pRight->getEndPoint(el.ptGe[1]); el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; pLnT = new AcDbLine(el.ptGe[0],el.ptGe[1]); pLnT->setNormal(AcGeVector3d::kZAxis); draw2d.append(pLnT); } } return true; } //标准封闭的墙线 bool AecDbXWall::GetStandardDraw2d(AcDbPolyline *&pPL) const { assertReadEnabled(); AcDbVoidPtrArray arCurPtrs; GetStandardDraw2d(arCurPtrs, true); AcDbVoidPtrArray arRes; AcDbCurve* pCrv = KTCADUtilityEx::ConvertBoundCurve(arCurPtrs, arRes); if (pCrv != NULL) { pPL = AcDbPolyline::cast(pCrv); } return (pPL != NULL) ? true : false; } bool AecDbXWall::GetStandardDraw2d() { assertWriteEnabled(); AecComplexCurve cmpl; m_drawable2d.SetEdage(cmpl); return GetStandardDraw2d(m_drawable2d); } void AecDbXWall::SetDraw2dables(const AecComplexCurve& draw2d) { AssertWriteEnabled(); int nColor = kColorByLayer; m_mapSpecXData.GetAt(_T("COLOR"), nColor); m_drawable2d.SetEdage(draw2d); m_drawable2d.SetColor(nColor); if (draw2d.isEmpty()) { //端部标记也置空 m_2dHideTail.SetEdage(draw2d); } } void ComplexCurveAddCurSpace(const AecComplexCurve& draw2dWall,int nColor) { AcDbCurve* pCurve = NULL; for (int i = 0;i < draw2dWall.length();i++) { const AecEqui::AecCurveElement& el = draw2dWall.at(i); pCurve = NULL; AecComplexCurve::MakeCurve(el,pCurve); if (pCurve != NULL) { pCurve->setColorIndex(nColor); AddToModelSpace(pCurve); } } } void AecDbXWall::SubtractDraw2d(const AecComplexCurve& cmplSub) { AecComplexCurve draw2dWall; GetDraw2dables(draw2dWall); //TEST //ComplexCurveAddCurSpace(draw2dWall,1); //ComplexCurveAddCurSpace(cmplSub,2); AecCoverBooleanOper::BoolSubtract(draw2dWall,cmplSub); SetDraw2dables(draw2dWall); //ComplexCurveAddCurSpace(draw2dWall,3); } /* * 涉及命令 PL_ZJCH PL_DXCH 2024-05-15 */ void AecDbXWall::SubtractXOpeningDraw2d(AecComplexCurveDraw& draw2d) const { assertReadEnabled(); AecComplexCurve cmplDraw2d; draw2d.GetEdage(cmplDraw2d); AcDb3dSolid *pSolidPart = NULL; AcDbObjectId id; AcDbEntity *pEnt = NULL; Acad::ErrorStatus es; for (int i = 0; i < m_arAssocPartEntIds.length(); i++) { id = m_arAssocPartEntIds.at(i); if (Acad::eOk == (es = acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead))) { AecDbZLineXOpening *pZXOpen = AecDbZLineXOpening::cast(pEnt); if (pZXOpen != NULL) { AecComplexCurve win2d; pZXOpen->GetStandardDraw2d(win2d, false); AecCoverBooleanOper::BoolSubtract(cmplDraw2d, win2d); } pEnt->close(); } } draw2d.RemoveEdage(); draw2d.SetEdage(cmplDraw2d); } void AecDbXWall::BoolUniteDraw2d(const AecComplexCurve& cmplUnt) { AecComplexCurve draw2dWall; GetDraw2dables(draw2dWall); AecCoverBooleanOper::BoolUnite(draw2dWall,cmplUnt); SetDraw2dables(draw2dWall); } void AecDbXWall::AppendDraw2d(const AecComplexCurve& cmpl) { AecComplexCurve cmplDraw; m_drawable2d.GetEdage(cmplDraw); AssertWriteEnabled(); cmplDraw.append(cmpl); m_drawable2d.SetEdage(cmplDraw); int nColor = kColorByLayer; m_mapSpecXData.GetAt(_T("COLOR"), nColor); m_drawable2d.SetColor(nColor); } void AecDbXWall::AddLineBreakSegment(AcGePoint3d& pt1,AcGePoint3d& pt2) { assertWriteEnabled(); Clean2DBuffer(); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); double dW = 0.0; m_mapSpecXData.GetAt(KEY_PLOTW,dW); pt1.z = 0.0;pt2.z = 0.0; el.dWidth = dW; el.ptGe[0] = pt1; el.ptGe[1] = pt2; el.ptGe[2] = pt2; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; el.bHided = TRUE; AecComplexCurve& cmpl = m_drawable2d.GetRefEdage(); if (cmpl.length() > 0) { AecEqui::AecCurveElement& el0 = cmpl.atByRef(0); el.dWidth = el0.dWidth; } cmpl.append(el); cmpl.merge(); cmpl.boolSubtract(); } void AecDbXWall::AddArcBreakSegment(AcGePoint3d& pt1,AcGePoint3d& ptMid,AcGePoint3d& pt2) { assertWriteEnabled(); Clean2DBuffer(); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); double dW = 0.0; m_mapSpecXData.GetAt(KEY_PLOTW,dW); pt1.z = 0.0;pt2.z = 0.0;ptMid.z = 0.0; el.dWidth = dW; el.ptGe[0] = pt1; el.ptGe[1] = ptMid; el.ptGe[2] = pt2; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; el.bHided = TRUE; AecComplexCurve& cmpl = m_drawable2d.GetRefEdage(); if (cmpl.length() > 0) { AecEqui::AecCurveElement& el0 = cmpl.atByRef(0); el.dWidth = el0.dWidth; } cmpl.append(el); cmpl.merge(); cmpl.boolSubtract(); } void AecDbXWall::AddLineDashedSegment(AcGePoint3d& pt1,AcGePoint3d& pt2) { assertWriteEnabled(); Clean2DBuffer(); //先擦除 AddLineBreakSegment(pt1,pt2); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); double dW = 0.0; m_mapSpecXData.GetAt(KEY_PLOTW,dW); pt1.z = 0.0;pt2.z = 0.0; el.dWidth = dW; el.ptGe[0] = pt1; el.ptGe[1] = pt2; el.ptGe[2] = pt2; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; el.bHided = FALSE; el.idSubLay = layerId(); el.idSubLty = KTSetting::InitLineStyle(_T("DASHED")); AecComplexCurve& cmpl = m_drawable2d.GetRefEdage(); if (cmpl.length() > 0) { AecEqui::AecCurveElement& el0 = cmpl.atByRef(0); el.dWidth = el0.dWidth; } cmpl.append(el); } void AecDbXWall::AddArcDashedSegment(AcGePoint3d& pt1,AcGePoint3d& ptMid,AcGePoint3d& pt2) { assertWriteEnabled(); Clean2DBuffer(); AddArcBreakSegment(pt1,ptMid,pt2); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); double dW = 0.0; m_mapSpecXData.GetAt(KEY_PLOTW,dW); pt1.z = 0.0;pt2.z = 0.0;ptMid.z = 0.0; el.dWidth = dW; el.ptGe[0] = pt1; el.ptGe[1] = ptMid; el.ptGe[2] = pt2; el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; el.bHided = FALSE; el.idSubLay = layerId(); el.idSubLty = KTSetting::InitLineStyle(_T("DASHED")); AecComplexCurve& cmpl = m_drawable2d.GetRefEdage(); if (cmpl.length() > 0) { AecEqui::AecCurveElement& el0 = cmpl.atByRef(0); el.dWidth = el0.dWidth; } cmpl.append(el); } void AecDbXWall::AddLineSegment(AcGePoint3d& pt1,AcGePoint3d& pt2) { assertWriteEnabled(); Clean2DBuffer(); //先擦除 AddLineBreakSegment(pt1,pt2); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); double dW = 0.0; m_mapSpecXData.GetAt(KEY_PLOTW,dW); pt1.z = 0.0;pt2.z = 0.0; el.dWidth = dW; el.ptGe[0] = pt1; el.ptGe[1] = pt2; el.ptGe[2] = pt2; el.bHided = FALSE; el.idSubLay = layerId(); el.idSubLty = linetypeId(); el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; AecComplexCurve& cmpl = m_drawable2d.GetRefEdage(); if (cmpl.length() > 0) { AecEqui::AecCurveElement& el0 = cmpl.atByRef(0); el.dWidth = el0.dWidth; } cmpl.append(el); } void AecDbXWall::AddArcSegment(AcGePoint3d& pt1,AcGePoint3d& ptMid,AcGePoint3d& pt2) { assertWriteEnabled(); Clean2DBuffer(); AddArcBreakSegment(pt1,ptMid,pt2); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); double dW = 0.0; m_mapSpecXData.GetAt(KEY_PLOTW,dW); pt1.z = 0.0;pt2.z = 0.0;ptMid.z = 0.0; el.dWidth = dW; el.ptGe[0] = pt1; el.ptGe[1] = ptMid; el.ptGe[2] = pt2; el.bHided = 0; el.idSubLay = layerId(); el.idSubLty = linetypeId(); el.ptGe[0].z = 0.0; el.ptGe[1].z = 0.0; el.ptGe[2].z = 0.0; AecComplexCurve& cmpl = m_drawable2d.GetRefEdage(); if (cmpl.length() > 0) { AecEqui::AecCurveElement& el0 = cmpl.atByRef(0); el.dWidth = el0.dWidth; } cmpl.append(el); } Acad::ErrorStatus AecDbXWall::ClearForDraw2dables() { AssertWriteEnabled(); m_drawable2d.RemoveEdage(); //端部标记也置空 m_2dHideTail.RemoveEdage(); return Acad::eOk; } Acad::ErrorStatus AecDbXWall::extend(double newParam) { AssertWriteEnabled(); Acad::ErrorStatus es = AecDbEwPipeBase::extend(newParam); if (es == Acad::eOk) { //EXTEND 需要ClearFor...工艺视图 AecWall2DJoin::Extend 不需要ClearFor... 矛盾 struct resbuf rb; acedGetVar(_T("CMDNAMES"),&rb); if (_tcscmp(rb.resval.rstring,_T("EXTEND")) == 0) { ClearForDraw2dables(); } } return es; } Acad::ErrorStatus AecDbXWall::extend(Adesk::Boolean extendStart, const AcGePoint3d& toPoint) { AssertWriteEnabled(); Acad::ErrorStatus es = AecDbEwPipeBase::extend(extendStart,toPoint); if (es == Acad::eOk) { //EXTEND 需要ClearFor...工艺视图 AecWall2DJoin::Extend 不需要ClearFor... 矛盾 struct resbuf rb; acedGetVar(_T("CMDNAMES"),&rb); if (_tcscmp(rb.resval.rstring,_T("EXTEND")) == 0) { ClearForDraw2dables(); } } return es; } Acad::ErrorStatus AecDbXWall::subErase(Adesk::Boolean erasing) { if (erasing) { GripMessage msg; memset(&msg,0,sizeof(GripMessage)); msg.nType = 6; msg.idHost = objectId(); msg.idAsso = objectId(); msg.ptGrip = StartPoint(); msg.ptRelt = EndPoint(); WallData* pWdata = new WallData; memset(pWdata,0,sizeof(WallData)); GetWallData(*pWdata); msg.nData = 0; msg.pParam = pWdata; msg.fData = 0.0; //PushGripMessage(msg); //墙体复原 //if ( IsWall2DJoin() ) //{ //acedPostCommand(_T("\x03")); //acedPostCommand(_T("PL_QTFY\n")); //} } return AecDbBDPipeBase::subErase(erasing); } bool AecDbXWall::IsWall2DJoin() { AcGePoint3d ptS = StartPoint(); AcGePoint3d ptE = EndPoint(); AcGeVector3d vtS,vtE; getFirstDeriv(ptS,vtS); vtS.negate();//向外 getFirstDeriv(ptE,vtE); AcDbRay ray1; ray1.setBasePoint(ptS); ray1.setUnitDir(vtS); AcDbRay ray2; ray2.setBasePoint(ptE); ray2.setUnitDir(vtE); AcGePoint3dArray arPts; const AcDbVoidPtrArray& ar2D = Get2DBuffer(); for (int i = 0;i < ar2D.length();i++) { AcDbEntity* pEnt = (AcDbEntity*)ar2D.at(i); ray1.intersectWith(pEnt,AcDb::kOnBothOperands,AcGePlane::kXYPlane,arPts); ray2.intersectWith(pEnt,AcDb::kOnBothOperands,AcGePlane::kXYPlane,arPts); } if (arPts.length() < 2) return true; return false; } void AecDbXWall::RemoveTailDraw2d(const AcGePoint3d& ptPos) { AssertWriteEnabled(); AcGePoint3d ptMid; double dDist = 0.0; //WallData data; //GetWallData(data); //调整到起始点 AcGePoint3d ptOn; getClosestPointTo(ptPos,ptOn,Adesk::kFalse); AcGePoint3d ptS,ptE; getStartPoint(ptS); getEndPoint(ptE); double dDis1 = ptOn.distanceTo(ptS); double dDis2 = ptOn.distanceTo(ptE); if (dDis1 < dDis2) { ptOn = ptS; } else { ptOn = ptE; } //TEST //AcDbCircle* pCir = new AcDbCircle; //pCir->setCenter(ptOn); //pCir->setRadius(10.0); //AddToModelSpace(pCir); bool bRemoved = false; AcGeVector3d vt1,vt2; AecComplexCurve& cmpl = m_2dHideTail.GetRefEdage(); for (int i = 0;i < cmpl.length();i++) { AecEqui::AecCurveElement& elT = cmpl.atByRef(i); //判断ptOn 落在elT上 vt1 = elT.ptGe[0] - ptOn; vt2 = elT.ptGe[2] - ptOn; if (vt1.isParallelTo(vt2) && !vt1.isCodirectionalTo(vt2)) { cmpl.removeAt(i); break; } } AecComplexCurve& cmpl2 = m_drawable2d.GetRefEdage(); for (int i = 0;i < cmpl2.length();i++) { AecEqui::AecCurveElement& elT = cmpl2.atByRef(i); //判断ptOn 落在elT上 vt1 = elT.ptGe[0] - ptOn; vt2 = elT.ptGe[2] - ptOn; if (vt1.isParallelTo(vt2) && !vt1.isCodirectionalTo(vt2)) { cmpl2.removeAt(i); break; } } int nPos1 = -1; int nPos = GetNearPosition(ptPos); RemoveAddtionShow3dPart(nPos); /*//移除补上的窟窿 BOOL bAddShow = FALSE; AecDbX3dPart* pPart = NULL; for (int i = 0;i < m_arX3DPartPtrs.length();i++) { pPart = m_arX3DPartPtrs.at(i); pPart->GetSpecialtyData()->GetAt(KEY_ADDTIONSHOW,bAddShow); if (bAddShow) { pPart->GetSpecialtyData()->GetAt(KEY_POS,nPos1); if (nPos == nPos1 && nPos1 > -1) { m_arX3DPartPtrs.removeAt(i); delete pPart; i -= 1; } } }*/ } bool AecDbXWall::RemoveAddtionShow3dPart(int nPos) { AssertWriteEnabled(); int nPos1 = -1; //移除补上的窟窿 BOOL bAddShow = FALSE; AecDbX3dPart* pPart = NULL; for (int i = 0;i < m_arX3DPartPtrs.length();i++) { pPart = m_arX3DPartPtrs.at(i); pPart->GetSpecialtyData()->GetAt(KEY_ADDTIONSHOW,bAddShow); if (bAddShow) { pPart->GetSpecialtyData()->GetAt(KEY_POS,nPos1); if (nPos == nPos1 && nPos1 > -1) { m_arX3DPartPtrs.removeAt(i); delete pPart; i -= 1; } } } return true; } bool AecDbXWall::GetTailDraw2d(const AcGePoint3d& ptPos,AecEqui::AecCurveElement& el) const { assertReadEnabled(); AecComplexCurve cmpL; GetDrawable2dLeft(cmpL); AecComplexCurve cmpR; GetDrawable2dRight(cmpR); //获取两头的点 AcGePoint3d ptLSE[2]; bool bL = GetTailLineElement(ptLSE,cmpL); //获取两头的点 AcGePoint3d ptRSE[2]; bool bR = GetTailLineElement(ptRSE,cmpR); // double dDis1 = ptPos.distanceTo(MidPoint(ptLSE[0],ptRSE[0])); double dDis2 = ptPos.distanceTo(MidPoint(ptLSE[1],ptRSE[1])); if (dDis1 < dDis2) { el.ptGe[0] = ptLSE[0]; el.ptGe[1] = ptRSE[0]; el.ptGe[2] = ptRSE[0]; } else { el.ptGe[0] = ptLSE[1]; el.ptGe[1] = ptRSE[1]; el.ptGe[2] = ptRSE[1]; } return true; } void AecDbXWall::SetInsulation(int nPos, InsulData &data) { assertWriteEnabled(); CString sKey; sKey.Format(_T("%s%d"), PIPE_INSTHICK, nPos); m_mapSpecXData.SetAt(sKey, data.dThick); sKey.Format(_T("%s%dSP"), PIPE_INSTHICK, nPos); m_mapSpecXData.SetAt(sKey, _T("界面处理剂;粘接层;保温层;抗裂保护层;耐碱网格布;柔性腻子层;饰面层")); sKey.Format(_T("%s%dST"), PIPE_INSTHICK, nPos); m_mapSpecXData.SetAt(sKey, _T("TRACKS")); } bool AecDbXWall::GetInsulation(int nPos, InsulData &data) const { assertReadEnabled(); //示例 data.dThick = 100;//mm CString sKey; sKey.Format(_T("%s%d"), PIPE_INSTHICK,nPos); m_mapSpecXData.GetAt(sKey, data.dThick); _tcscpy(data.szInsSpec, _T("界面处理剂;粘接层;保温层;抗裂保护层;耐碱网格布;柔性腻子层;饰面层")); _tcscpy(data.szLnStyle, _T("TRACKS")); sKey.Format(_T("%s%dSP"), PIPE_INSTHICK, nPos); m_mapSpecXData.GetAt(sKey, data.szInsSpec); sKey.Format(_T("%s%dST"), PIPE_INSTHICK, nPos); m_mapSpecXData.GetAt(sKey, data.szLnStyle); return true; } void AecDbXWall::GetDraw2dables(AecComplexCurve& draw2d) const { assertReadEnabled(); m_drawable2d.GetEdage(draw2d); draw2d.OrthoProjectedToXYPlane(); } bool AecDbXWall::GetInsulDraw2dables(AecComplexCurve &draw2dL, AecComplexCurve &draw2dR) const { assertReadEnabled(); InsulData dataL; memset(&dataL, 0, sizeof(InsulData)); GetInsulation(0, dataL); InsulData dataR; memset(&dataR, 1, sizeof(InsulData)); GetInsulation(1, dataR); AecComplexCurve cmplCrv; GetDraw2dables(cmplCrv); AecEqui::AecCurveElement elL = GetLeftElement(); AecEqui::AecCurveElement elR = GetRightElement(); AcDbCurve *pCurveL = NULL; AecComplexCurve::MakeCurve(elL, pCurveL); AcDbCurve *pCurveR = NULL; AecComplexCurve::MakeCurve(elR, pCurveR); AcDbLine lnBase; bool bIsLine = m_pBaseCurve->isKindOf(AcDbLine::desc()); if (bIsLine) { AcGePoint3d ptS, ptE,ptS1,ptE1; if (pCurveL != NULL && pCurveR != NULL) { pCurveL->getStartPoint(ptS); pCurveL->getEndPoint(ptE); pCurveR->getStartPoint(ptS1); pCurveR->getEndPoint(ptE1); lnBase.setStartPoint(MidPoint(ptS, ptS1)); lnBase.setEndPoint(MidPoint(ptE, ptE1)); } } AcGeVector3d vtOff(0,0,0); AcGePoint3d ptOn; for (int i = 0;i < cmplCrv.length();i++) { AecEqui::AecCurveElement el = cmplCrv.at(i); //判断共线 if (IsOnCurve(pCurveL, el) && !el.bHided) { if (bIsLine)//LINE { if (el.bHided) { continue; } //偏移 lnBase.getClosestPointTo(el.ptGe[0], ptOn, Adesk::kTrue); vtOff = el.ptGe[0] - ptOn; vtOff.normalize(); vtOff *= dataL.dThick; el.ptGe[0] += vtOff; el.ptGe[1] += vtOff; el.ptGe[2] += vtOff; draw2dL.append(el); } else//ARC { if (el.bHided) { continue; } AcDbArc* pArc = FormatArc(el.ptGe[0], el.ptGe[1], el.ptGe[2]); if (pArc != NULL) { for (int n = 0; n < 3; n++) { vtOff = pArc->center() - el.ptGe[n]; vtOff.normalize(); el.ptGe[n] += vtOff * dataL.dThick; } draw2dL.append(el); delete pArc; } } continue; } if (IsOnCurve(pCurveR, el) && !el.bHided) { //偏移 if (bIsLine)//LINE { if (el.bHided) { continue; } lnBase.getClosestPointTo(el.ptGe[0], ptOn, Adesk::kTrue); vtOff = el.ptGe[0] - ptOn; vtOff.normalize(); vtOff *= dataR.dThick; el.ptGe[0] += vtOff; el.ptGe[1] += vtOff; el.ptGe[2] += vtOff; draw2dR.append(el); } else//ARC { if (el.bHided) { continue; } AcDbArc *pArc = FormatArc(el.ptGe[0], el.ptGe[1], el.ptGe[2]); if (pArc != NULL) { for (int n = 0; n < 3; n++) { vtOff = el.ptGe[n] - pArc->center(); vtOff.normalize(); el.ptGe[n] += vtOff * dataR.dThick; } draw2dR.append(el); delete pArc; } } continue; } } if (pCurveL != NULL) delete pCurveL; if (pCurveR != NULL) delete pCurveR; return (!draw2dR.isEmpty() && !draw2dL.isEmpty()) ? true : false; } void AecDbXWall::GetDraw2dHideTail(AecComplexCurve& draw2d) const { assertReadEnabled(); m_2dHideTail.GetEdage(draw2d); draw2d.OrthoProjectedToXYPlane(); } void AecDbXWall::SetDraw2dHideTail(const AecComplexCurve& draw2d) { AssertWriteEnabled(); m_2dHideTail.SetEdage(draw2d); } Acad::ErrorStatus AecDbXWall::Draw2d(AcGiDraw &dc) const { assertReadEnabled(); if (g_BALock::instance().Draw() != BIT_SUCCESS) return Acad::eOk; //管线系统屏蔽掉 if ( dc.IsDragging() ) { //return Acad::eOk; } AcDbObjectId idCurLay = dc.GetLayerId(); AcDbObjectId idCurLty = dc.GetLineTypeId(); Adesk::UInt16 nCrBk = colorIndex(); int nColor = nCrBk; if ( m_mapSpecXData.GetAt(_T("COLOR"),nColor) ) { dc.SetColor(nColor); } DrawDTYG2D(dc); //二维缓存,未知出错! if (Has2DBuffer()) { AcDbEntity* pEnt = NULL; const AcDbVoidPtrArray &ar2D = Get2DBuffer(); for (int i = 0;i < ar2D.length();i++) { pEnt = (AcDbEntity*)ar2D.at(i); pEnt->setColorIndex(nColor); dc.DrawEntity(*pEnt); } dc.SetColor(nCrBk); dc.SetLayer(idCurLay); dc.SetLineType(idCurLty); return Acad::eOk; } if (!m_drawable2d.HasEdage()) { int nShape = 0; if ( m_mapSpecXData.GetAt(KEY_SECSHAPE,nShape) ) { if (nShape == eXShape) { return AecDbEwPipeBase::Draw2d(dc); } } //没有融合干涉前的标准绘制 AecComplexCurveDraw draw2d; GetStandardDraw2d(draw2d); DrawBrokenOpen(draw2d); SubDrawPlotWidth(draw2d); draw2d.SetHideDraw(FALSE); draw2d.SetColor(nColor); draw2d.Draw2d(dc,layerId(),m_idDashLayer,m_idCenterLayer,NULL,TRUE); m_drawable2d = draw2d; AcDbVoidPtrArray arPtrs; draw2d.explode(arPtrs,layerId(),m_idDashLayer,m_idCenterLayer,NULL,TRUE); Add2DBuffer(arPtrs); } else//有 { //m_drawable2d可能来自融合处理结果. //融合结果绘制 AecComplexCurveDraw draw2d; draw2d.copyFrom(m_drawable2d); //在此减去带型窗,转角窗户的压墙线 // 对于上述窗户命令中的如下代码,导致墙体的三维融合挖空过度 //pWall->SubtractDraw2d(win2d); //所以二维在此临时裁剪,外部命令不裁剪 //涉及命令 PL_ZJCH PL_DXCH 2024 - 05 - 15 SubtractXOpeningDraw2d(draw2d); SubDrawPlotWidth(draw2d); draw2d.SetHideDraw(FALSE); draw2d.SetColor(nColor); draw2d.Draw2d(dc,layerId(),m_idDashLayer,m_idCenterLayer,NULL,TRUE); DrawBrokenOpen(draw2d); //取端部线 AecComplexCurveDraw draw2dTail; draw2dTail.copyFrom(m_2dHideTail); SubDrawPlotWidth(draw2dTail); draw2dTail.SetHideDraw(FALSE); draw2dTail.SetColor(nColor); draw2dTail.Draw2d(dc,layerId(),m_idDashLayer,m_idCenterLayer,NULL,TRUE); AcDbVoidPtrArray arPtrs; draw2d.explode(arPtrs,layerId(),m_idDashLayer,m_idCenterLayer,NULL,TRUE); draw2dTail.explode(arPtrs,layerId(),m_idDashLayer,m_idCenterLayer,NULL,TRUE); Add2DBuffer(arPtrs); } AcDbVoidPtrArray arCurves; GetInsideCurves(arCurves); AcDbEntity* pEnt = NULL; for (int i = 0;i < arCurves.length();i++) { pEnt = (AcDbEntity*)arCurves.at(i); if (pEnt != NULL) { pEnt->setLayer(idCurLay); pEnt->setColorIndex(nColor); dc.DrawEntity(pEnt); Add2DBuffer(pEnt); } } dc.SetColor(nCrBk); dc.SetLayer(idCurLay); dc.SetLineType(idCurLty); return Acad::eOk; } Acad::ErrorStatus AecDbXWall::DrawBrokenOpen(AecComplexCurveDraw& draw2d) const { AecComplexCurve cmpl; draw2d.GetEdage(cmpl); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); AcDbLine* pLine = AcDbLine::cast(m_pBaseCurve); if (pLine == NULL) return Acad::eOk; AcGeVector3d vtL = pLine->endPoint() - pLine->startPoint(); vtL.normalize(); AcGeVector3d vtV = vtL; vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); AecComplexCurve cmpl2; double dThick = 0.0; m_mapSpecXData.GetAt(KEY_SIZE1,dThick); //绘制断墙体符号 AcGePoint3d ptGeT,ptGeBK; AcGePoint3dArray arPoints; CString sIndex; for(int i = 0;i < PIPE_BROKENNUM;i++) { sIndex.Format(_T("BKOP%d"),i); if (m_mapSpecXData.GetAt(sIndex,ptGeBK)) { m_pBaseCurve->getPointAtDist(ptGeBK.x,ptGeT); ptGeT.z = 0.0;//仅仅俯视 arPoints.append(ptGeT); el.ptGe[0] = ptGeT; m_pBaseCurve->getPointAtDist(ptGeBK.x + ptGeBK.y,ptGeT); ptGeT.z = 0.0;//仅仅俯视 arPoints.append(ptGeT); el.ptGe[1] = ptGeT; el.ptGe[2] = ptGeT; el.ptGe[0] += vtV * 0.5 * dThick; el.ptGe[1] += vtV * 0.5 * dThick; el.ptGe[2] += vtV * 0.5 * dThick; cmpl2.append(el); el.ptGe[0] -= vtV * dThick; el.ptGe[1] -= vtV * dThick; el.ptGe[2] -= vtV * dThick; cmpl2.append(el); } } if ( !cmpl2.isEmpty() ) { AecCoverBooleanOper::BoolSubtract(cmpl,cmpl2); cmpl.OrthoProjectedToXYPlane(); draw2d.SetEdage(cmpl); //符号在外部绘制 } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::SubDrawPlotWidth(AecComplexCurveDraw& draw2d) const { double dW = 0.0; AcGeVector3d vt; if ( m_mapSpecXData.GetAt(KEY_PLOTW,dW) ) { AecComplexCurve& cmpl = draw2d.GetRefEdage(); for (int i = 0;i < cmpl.length();i++) { AecEqui::AecCurveElement& el = cmpl.atByRef(i); el.dWidth = dW; //两头延伸半个宽度 if (dW > 1.e-6) { if (el.ptGe[1].distanceTo(el.ptGe[2]) < 1.e-3)//是直线 { vt = el.ptGe[2] - el.ptGe[0]; vt.normalize(); vt *= 0.5 * dW; el.ptGe[0] -= vt; el.ptGe[2] += vt; el.ptGe[1] = el.ptGe[2]; } else { //待定... } } } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::Draw3d(AcGiDraw &dc) const { assertReadEnabled(); if (g_BALock::instance().Draw() != BIT_SUCCESS) return Acad::eOk; //管线系统屏蔽掉 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 (IsActive()) { nColor = kMagenta; m_mapSpecXData.GetAt(KEY_ACTIVECR,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); if ( IsActive() ) { BackupColorIndex(pEnt); pEnt->setColorIndex(nColor); } else { SetBackupColorIndex(pEnt); } dc.DrawEntity(*pEnt); } dc.SetLayer(idLay); dc.SetColor(nCrBk); return Acad::eOk; } AcCmTransparency tr = transparency(); AcDb3dSolid* pSolidDraw = GetDraw3dSolid(false); if (pSolidDraw != NULL) { pSolidDraw->setTransparency(tr); pSolidDraw->setLayer(layerId()); pSolidDraw->setColorIndex(nColor); dc.DrawEntity(pSolidDraw); Add3DBuffer(pSolidDraw); } dc.SetLayer(idLay); dc.SetColor(nCrBk); return Acad::eOk; } bool AecDbXWall::GetInterface(AcArray& arInfs) const { assertReadEnabled(); AcDbCurve* pCurve = GetBaseCurve(); if (pCurve != NULL) { double dSta = 0.0,dEnd = 0.0; pCurve->getStartParam(dSta); pCurve->getEndParam(dEnd); AcGeVector3d vt0,vt1; pCurve->getFirstDeriv(dSta,vt0); pCurve->getFirstDeriv(dEnd,vt1); AcGePoint3d ptSta,ptEnd; pCurve->getStartPoint(ptSta); pCurve->getEndPoint(ptEnd); double dThick = 0.0; m_mapSpecXData.GetAt(KEY_SIZE1,dThick); AecInterface inf; inf.idOwner = objectId(); inf.nType = -1; inf.dGasket = 0; inf.ptPos = ptSta; inf.dSize1 = dThick; inf.dSize2 = dThick; inf.vtDir = vt0; arInfs.append(inf); inf.ptPos = ptEnd; inf.dSize1 = dThick; inf.dSize2 = dThick; inf.vtDir = vt1; arInfs.append(inf); delete pCurve; return true; } return false; } bool AecDbXWall::GetInterface(int nIndex,AecInterface& inf) const { assertReadEnabled(); AcArray arInfs; GetInterface(arInfs); if (nIndex > -1 && nIndex < arInfs.length()) { inf = arInfs.at(nIndex); return true; } return false; } int AecDbXWall::GetInterfaceCount() const { assertReadEnabled(); AcArray arInfs; GetInterface(arInfs); return arInfs.length(); } int AecDbXWall::GetActiveInf() const { assertReadEnabled(); return -1; } void AecDbXWall::SetActiveInf(int nIndex) { } void AecDbXWall::LockInf(int nInf) { } bool AecDbXWall::TransformAssocInf(int nInf,const AcGeMatrix3d& xform) { AssertWriteEnabled(); AcDbCurve* pBaseCrv = GetBaseCurve(); if (pBaseCrv == NULL) return false; AcArray arInf; GetInterface(arInf); if (nInf > -1 && nInf < arInf.length() ) { AecInterface& inf = arInf.at(nInf); AcGePoint3d ptGe = inf.ptPos; ptGe.transformBy(xform); AcDbLine* pLine = AcDbLine::cast(pBaseCrv); if (pLine != NULL)//直墙 { AcGePoint3d ptSta,ptEnd; ptSta = pLine->startPoint(); ptEnd = pLine->endPoint(); if (inf.ptPos.distanceTo(ptSta) < 1.e-1) { pLine->setStartPoint(ptGe);//新位置 SetBaseCurve(pLine); delete pBaseCrv; return false;//不在继续发消息 } if (inf.ptPos.distanceTo(ptEnd) < 1.e-1) { pLine->setEndPoint(ptGe);//新位置 SetBaseCurve(pLine); delete pBaseCrv; return false;//不在继续发消息 } } AcDbArc* pArc = AcDbArc::cast(pBaseCrv);//弧墙 if (pArc != NULL) { AcGePoint3d ptSta,ptEnd,ptMid; pArc->getStartPoint(ptSta); pArc->getEndPoint(ptEnd); double dSta = 0.0,dEnd = 0.0; pArc->getStartParam(dSta); pArc->getEndParam(dEnd); double dMid = (dSta + dEnd) / 2.0; pArc->getPointAtParam(dMid,ptMid); if (inf.ptPos.distanceTo(ptSta) < 1.e-1) { AcDbArc* pArc2 = KTCADUtilityEx::FormatArc(ptGe,ptMid,ptEnd); if (pArc2 != NULL) { pArc->setStartAngle(pArc2->startAngle()); pArc->setEndAngle(pArc2->endAngle()); pArc->setCenter(pArc2->center()); pArc->setRadius(pArc2->radius()); SetBaseCurve(pArc2); delete pBaseCrv; delete pArc2; } return false;//不在继续发消息 } if (inf.ptPos.distanceTo(ptEnd) < 1.e-1) { AcDbArc* pArc2 = KTCADUtilityEx::FormatArc(ptSta,ptMid,ptGe); if (pArc2 != NULL) { pArc->setStartAngle(pArc2->startAngle()); pArc->setEndAngle(pArc2->endAngle()); pArc->setCenter(pArc2->center()); pArc->setRadius(pArc2->radius()); SetBaseCurve(pArc2); delete pBaseCrv; delete pArc2; } return false;//不在继续发消息 } } } delete pBaseCrv; return true; } Acad::ErrorStatus AecDbXWall::subGetGripPoints( AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const { assertReadEnabled(); AcGePoint3dArray gripPoints; ImpGetGripPoints(gripPoints,bitflags); int nColor = kWhite; AcDbGripData* pGripData = NULL; if ( bitflags >= 1394)//节点 { memset(&m_pGripAppData[0],0,sizeof(AecGripData)); m_pGripAppData[0].nIndex = 0; m_pGripAppData[0].ePos = eFlag; m_pGripAppData[0].nColor = nColor; m_pGripAppData[0].ptGrip = gripPoints.at(0); m_pGripAppData[0].pOwner = (AcDbEntity*)this; pGripData = new AcDbGripData; pGripData->setGripPoint(gripPoints.at(0)); pGripData->setAppData((void*)&m_pGripAppData[0]); pGripData->setWorldDraw(AecGripCback::WorldDrawfunc); pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc); _tcscpy(m_pGripAppData[0].szTip,_T("点击定位造族<墙体>记录")); _tcscpy(m_pGripAppData[0].szID,m_sGUID); grips.append(pGripData); return Acad::eOk; } else { EPosition ePos; CString sTip; for (int i = 0;i < gripPoints.length();i++) { ePos = ExplainGripIndex(i,sTip); memset(&m_pGripAppData[i],0,sizeof(AecGripData)); m_pGripAppData[i].nIndex = i; m_pGripAppData[i].ePos = ePos; m_pGripAppData[i].nColor = kBlue; m_pGripAppData[i].ptGrip = gripPoints.at(i); _tcscpy(m_pGripAppData[i].szTip,sTip); _tcscpy(m_pGripAppData[i].szID,m_sGUID); m_pGripAppData[i].pOwner = (AcDbEntity*)this; pGripData = new AcDbGripData; pGripData->setGripPoint(gripPoints.at(i)); pGripData->setAppData((void*)&m_pGripAppData[i]); pGripData->setWorldDraw(AecGripCback::WorldDrawfunc); pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc); grips.append(pGripData); } } //调用基类加入单击修改 SubAddHitEditGrip(grips); //动态标注 //直线,半径 标注风格 if (!grips.isEmpty()) { SubAddDimPoints(grips,curViewDir); } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::SubAddDimPoints(AcDbGripDataPtrArray& grips,const AcGeVector3d& curViewDir) const { if (GetDimGripOff()) return Acad::eOk; if (IsVViewWall()) { } else { WallData data; GetWallData(data); //中心线 AcDbLine* pLn = AcDbLine::cast(m_pBaseCurve); if (pLn != NULL) { //长度 AcGePoint3d ptSta = pLn->startPoint(); AcGePoint3d ptEnd = pLn->endPoint(); AcGeVector3d vtL = ptEnd - ptSta; vtL.normalize(); AcGeVector3d vtV = vtL; vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); AcGePoint3d ptMid; ptSta.z = data.dBomEl; ptEnd.z = data.dBomEl; ptSta -= vtV * 15.0;//外放一下 ptEnd -= vtV * 15.0;//外放一下 ptSta.z -= 10.0;//去掉10毫米,让出夹点 ptEnd.z -= 10.0;//去掉10毫米,让出夹点 ptMid = MidPoint(ptSta,ptEnd); ptMid.z -= 10.0 * 100.0;//标注文字位置 AddDimPoints(grips,curViewDir,ptSta,ptEnd,ptMid,0); //高度 ptEnd = ptSta; ptEnd.z += data.dH; ptMid = MidPoint(ptSta,ptEnd); ptMid -= vtL * 10.0 * 100.0;//标注文字位置 AddDimPoints(grips,curViewDir,ptSta,ptEnd,ptMid,0); //厚度,[注:内部折算为中心对齐] ptSta += vtV * 10.0;//复位 ptEnd += vtV * 10.0;//复位 ptSta -= vtL * 10.0;//外放一下 ptSta += vtV * 0.5 * data.dThick; ptEnd = ptSta; ptEnd -= vtV * data.dThick; ptMid = MidPoint(ptSta,ptEnd); ptMid.z -= 5.0 * 100.0;//标注文字位置 AddDimPoints(grips,curViewDir,ptSta,ptEnd,ptMid,0); //洞口标注 ptSta = pLn->startPoint(); AcGePoint3d ptOn; AcDbObjectId id; AcDbEntity* pEnt = NULL; Acad::ErrorStatus es; CString sName; if (objectId().isValid()) { AcDbObjectIdArray arDim;//补正协同误加的重复 for (int ii = 0;ii < m_arAssocPartEntIds.length();ii++) { id = m_arAssocPartEntIds.at(ii); if (arDim.find(id) != -1) continue; arDim.append(id); if ( Acad::eOk == (es = acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead))) { AecDbX3dPartEntity* pPart = AecDbX3dPartEntity::cast(pEnt); if (pPart != NULL) { sName = pPart->GetName(); if (sName.CompareNoCase(_T("开洞")) == 0 || sName.CompareNoCase(_T("套管")) == 0) { ptEnd = pPart->GetOrgPoint(true); pLn->getClosestPointTo(ptEnd,ptOn,Adesk::kTrue); ptOn.z = ptEnd.z; ptSta.z = ptEnd.z; ptMid = MidPoint(ptSta,ptEnd); ptMid.z -= ii * 5.0 * 100.0;//标注文字位置 //洞位置 AddDimPoints(grips,curViewDir,ptSta,ptOn,ptMid,0); //洞口尺寸参见洞口对象 } } AecDbXOpening *pOpen = AecDbXOpening::cast(pEnt); if (pOpen != NULL) { OpeningData opData; memset(&opData, 0, sizeof(OpeningData)); pOpen->GetOpeningData(opData); ptEnd = opData.ptPos; pLn->getClosestPointTo(ptEnd, ptOn, Adesk::kTrue); ptOn.z = ptEnd.z; ptSta.z = ptEnd.z; ptMid = MidPoint(ptSta, ptEnd); ptMid.z -= ii * 5.0 * 100.0;//标注文字位置 //洞位置 AddDimPoints(grips, curViewDir, ptSta, ptOn, ptMid, 0); //门窗尺寸参见洞口对象 } pEnt->close(); } } } } AcDbArc* pArc = AcDbArc::cast(m_pBaseCurve); if (pArc != NULL) { AcGePoint3d ptSta; pArc->getStartPoint(ptSta); AcGeVector3d vtL; pArc->getFirstDeriv(ptSta,vtL); vtL.normalize(); vtL.negate(); //半径标注 ptSta.z = data.dBomEl; AcGePoint3d ptEnd = pArc->center(); ptEnd.z = data.dBomEl; AcGePoint3d ptAMid = GetArcMidPoint(pArc); ptAMid.z = data.dBomEl; AcGePoint3d ptMid = MidPoint(ptAMid,ptEnd); AddDimPoints(grips,curViewDir,ptAMid,ptEnd,ptMid,1,pArc->radius()); //高度 ptEnd = ptSta; ptEnd.z += data.dH; ptMid = MidPoint(ptSta,ptEnd); ptMid -= vtL * 10.0 * 100.0;//标注文字位置 AddDimPoints(grips,curViewDir,ptSta,ptEnd,ptMid,0); //厚度,[注:内部折算为中心对齐] pArc->getStartPoint(ptSta); ptEnd = pArc->center(); AcGeVector3d vtV = ptSta - ptEnd; vtV.normalize(); ptSta += vtV * 0.5 * data.dThick; ptEnd = ptSta; ptEnd -= vtV * data.dThick; ptMid = MidPoint(ptSta,ptEnd); ptSta.z = ptEnd.z = data.dBomEl; ptMid.z -= 5.0 * 100.0;//标注文字位置 AddDimPoints(grips,curViewDir,ptSta,ptEnd,ptMid,0); //角度 pArc->getStartPoint(ptSta); pArc->getEndPoint(ptEnd); ptMid = GetArcMidPoint(pArc); ptMid.z -= 10.0 * 100.0;//标注文字位置 double dSt = pArc->startAngle(); double dEt = pArc->endAngle(); if (dEt < dSt) dEt += 2.0 * PI; double dAngle = dEt - dSt; dAngle *= 180.0 / PI; AddDimPoints(grips,curViewDir,ptSta,ptEnd,ptMid,3,dAngle); } AcDbCircle* pCir = AcDbCircle::cast(m_pBaseCurve); if (pCir != NULL) { AcGePoint3d ptSta; pCir->getStartPoint(ptSta); AcGeVector3d vtL; pCir->getFirstDeriv(ptSta,vtL); vtL.normalize(); vtL.negate(); //半径标注 ptSta.z = data.dBomEl; AcGePoint3d ptEnd = pCir->center(); ptEnd.z = data.dBomEl; AcGePoint3d ptMid = MidPoint(ptSta,ptEnd); AddDimPoints(grips,curViewDir,ptSta,ptEnd,ptMid,1,pCir->radius()); //高度 ptEnd = ptSta; ptEnd.z += data.dH; ptMid = MidPoint(ptSta,ptEnd); ptMid -= vtL * 10.0 * 100.0;//标注文字位置 AddDimPoints(grips,curViewDir,ptSta,ptEnd,ptMid,0); //厚度,[注:内部折算为中心对齐] pCir->getStartPoint(ptSta); ptEnd = pCir->center(); AcGeVector3d vtV = ptSta - ptEnd; vtV.normalize(); ptSta += vtV * 0.5 * data.dThick; ptEnd = ptSta; ptEnd -= vtV * data.dThick; ptMid = MidPoint(ptSta,ptEnd); ptSta.z = ptEnd.z = data.dBomEl; ptMid.z -= 5.0 * 100.0;//标注文字位置 AddDimPoints(grips,curViewDir,ptSta,ptEnd,ptMid,0); } //加入洞口尺寸示意 AddHoleDimPoints(grips,curViewDir); } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::ImpGetGripPoints(AcGePoint3dArray& gripPoints,const int bitflags) const { assertReadEnabled(); //上下左右前后 夹点 AcDbCurve* pBaseCrv = m_pBaseCurve; if (pBaseCrv != NULL) { WallData data; GetWallData(data); if (data.nSecShape == eRect) { return ImpGetRectWallGripPoints(gripPoints,data); } else if(data.nSecShape == eWw) { return ImpGetWwWallGripPoints(gripPoints,data); } else if (data.nSecShape == eUserDef) { return ImpGetUserDefWallGripPoints(gripPoints,data); } else if (data.nSecShape == eXShape) { return ImpGetXShapeSectionWallGripPoints(gripPoints,data); } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::ImpGetRectWallGripPoints(AcGePoint3dArray& gripPoints,const WallData& data) const { AcDbCurve* pBaseCrv = m_pBaseCurve; if (pBaseCrv == NULL) { return Acad::eOk; } int nAlign = 0; m_mapSpecXData.GetAt(KEY_ALIGN,nAlign); EAlign kAlign = (EAlign)nAlign; AcGePoint3d ptGe[3],ptTmp; pBaseCrv->getStartPoint(ptGe[0]); pBaseCrv->getEndPoint(ptGe[2]); double dSta = 0.0,dEnd = 0.0,dH = 0.0,dW = 0.0; pBaseCrv->getStartParam(dSta); pBaseCrv->getEndParam(dEnd); pBaseCrv->getPointAtParam((dSta+dEnd) / 2.0,ptGe[1]); double dCmd = PixelToWcs(10); AcGeVector3d vtL; AcDbLine* pLn = AcDbLine::cast(pBaseCrv); if (pLn != NULL) { vtL = pLn->endPoint() - pLn->startPoint(); vtL.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtL.normalize(); } //2.弧线墙体 AcDbArc* pArc = AcDbArc::cast(pBaseCrv); if (pArc != NULL) { vtL = ptGe[1] - pArc->center(); vtL.normalize(); } if (pArc != NULL || pLn != NULL) { //下中 3个点 曲线 for (int i = 0;i < 3;i++) { ptGe[i].z = data.dBomEl; gripPoints.append(ptGe[i]); } //中下 1个点 改标高 ptTmp = ptGe[1]; ptTmp.z -= dCmd; gripPoints.append(ptTmp); //下前 中点 ptGe[1] += vtL * 0.5 * data.dThick; gripPoints.append(ptGe[1]); //下后 中点 ptGe[1] -= vtL * data.dThick; gripPoints.append(ptGe[1]); //上 1个点 //3D视图下 if (!Is2DView()) { ptGe[1] += vtL * 0.5 * data.dThick; ptGe[1].z += data.dH; gripPoints.append(ptGe[1]); } return Acad::eOk; } //3.圆墙体 AcDbCircle* pCir = AcDbCircle::cast(pBaseCrv); if (pCir != NULL) { //下中 3个点 ->0度处 改半径和改内外宽 vtL = AcGeVector3d::kXAxis; switch(kAlign) { case kLeft: { ptGe[1] = pCir->center() + ( pCir->radius() + 0.5 * data.dThick) * vtL; ptGe[0] = pCir->center() + ( pCir->radius() ) * vtL; ptGe[2] = pCir->center() + ( pCir->radius() + data.dThick) * vtL; break; } case kMid: { ptGe[0] = pCir->center() + ( pCir->radius() - 0.5 * data.dThick) * vtL; ptGe[1] = pCir->center() + ( pCir->radius() ) * vtL; ptGe[2] = pCir->center() + ( pCir->radius() + 0.5 * data.dThick) * vtL; break; } case kRight: { ptGe[1] = pCir->center() + ( pCir->radius() - 0.5 * data.dThick) * vtL; ptGe[0] = pCir->center() + ( pCir->radius() ) * vtL; ptGe[2] = pCir->center() + ( pCir->radius() - data.dThick) * vtL; break; } default: break; } for (int i = 0;i < 3;i++) { ptGe[i].z = data.dBomEl; gripPoints.append(ptGe[i]); } //下中 1个点 ->位移点 ptTmp = pCir->center(); ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); //中下 1个点 ->拉底 ptTmp.z -= dCmd; gripPoints.append(ptTmp); //顶部中 ->拉高 ptTmp = pCir->center(); ptTmp.z = data.dBomEl; ptTmp.z += data.dH; gripPoints.append(ptTmp); } AcDbEllipse* pEllip = AcDbEllipse::cast(pBaseCrv); if (pEllip != NULL) { //下中 3个点 ->0度处 改半径和改内外宽 vtL = AcGeVector3d::kXAxis; switch(kAlign) { case kLeft: { ptGe[0] = pEllip->center() + ( pEllip->majorAxis().length() + 0.5 * data.dThick) * vtL; ptGe[1] = pEllip->center() + ( pEllip->majorAxis().length() ) * vtL; ptGe[2] = pEllip->center() + ( pEllip->majorAxis().length() + data.dThick) * vtL; break; } case kMid: { ptGe[0] = pEllip->center() + ( pEllip->majorAxis().length() - 0.5 * data.dThick) * vtL; ptGe[1] = pEllip->center() + ( pEllip->majorAxis().length() ) * vtL; ptGe[2] = pEllip->center() + ( pEllip->majorAxis().length() + 0.5 * data.dThick) * vtL; break; } case kRight: { ptGe[0] = pEllip->center() + ( pEllip->majorAxis().length() - 0.5 * data.dThick) * vtL; ptGe[1] = pEllip->center() + ( pEllip->majorAxis().length() ) * vtL; ptGe[2] = pEllip->center() + ( pEllip->majorAxis().length() - data.dThick) * vtL; break; } default: break; } for (int i = 0;i < 3;i++) { ptGe[i].z = data.dBomEl; gripPoints.append(ptGe[i]); } //下中 1个点 ->位移点 ptTmp = pEllip->center(); ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); //中下 1个点 ->拉底 ptTmp.z -= dCmd; gripPoints.append(ptTmp); //顶部中 ->拉高 ptTmp = pEllip->center(); ptTmp.z = data.dBomEl; ptTmp.z += data.dH; gripPoints.append(ptTmp); } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::ImpGetWwWallGripPoints(AcGePoint3dArray& gripPoints,const WallData& data) const { assertReadEnabled(); AcDbCurve* pBaseCrv = m_pBaseCurve; AcDbLine* pLn = AcDbLine::cast(pBaseCrv); AcDbArc* pArc = AcDbArc::cast(pBaseCrv); AcGePoint3d ptGe[3],ptTmp,ptGe1; double dCmd = PixelToWcs(10); AcGeVector3d vtL; if (pLn != NULL || pArc != NULL) { pBaseCrv->getStartPoint(ptGe[0]); pBaseCrv->getEndPoint(ptGe[2]); double dSta = 0.0,dEnd = 0.0,dH = 0.0,dW = 0.0; pBaseCrv->getStartParam(dSta); pBaseCrv->getEndParam(dEnd); pBaseCrv->getPointAtParam((dSta+dEnd) / 2.0,ptGe[1]); ptGe1 = ptGe[1]; AcDbLine* pLn = AcDbLine::cast(pBaseCrv); if (pLn != NULL) { vtL = pLn->endPoint() - pLn->startPoint(); vtL.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtL.normalize(); } //2.弧线墙体 AcDbArc* pArc = AcDbArc::cast(pBaseCrv); if (pArc != NULL) { vtL = ptGe[1] - pArc->center(); vtL.normalize(); } //下中 3个点 for (int i = 0;i < 3;i++) { ptGe[i].z = data.dBomEl; gripPoints.append(ptGe[i]); } //中下 1个点 ptTmp = ptGe[1]; ptTmp.z -= dCmd; gripPoints.append(ptTmp); //下前 中点 ptGe[1] += vtL * 0.5 * data.dThick2; gripPoints.append(ptGe[1]); //下后 中点 ptGe[1] -= vtL * data.dThick2; gripPoints.append(ptGe[1]); //上 1个点 //3D视图下 //if (!Is2DView()) { //上三个点-> 中,宽,宽 ptGe[1] = ptGe1; ptGe[1].z = data.dBomEl; ptGe[1].z += data.dH; gripPoints.append(ptGe[1]); ptGe[1] += vtL * 0.5 * data.dThick; gripPoints.append(ptGe[1]); ptGe[1] -= vtL * data.dThick; gripPoints.append(ptGe[1]); } return Acad::eOk; } AcDbCircle* pCir = AcDbCircle::cast(pBaseCrv); if (pCir != NULL) { //下中 3个点 ->0度处 改半径和改内外宽 vtL = AcGeVector3d::kXAxis; ptTmp = pCir->center(); ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); ptTmp = pCir->center() + pCir->radius() * vtL; ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); //中下 1个点 ->改标高 ptTmp.z -= dCmd; gripPoints.append(ptTmp); return Acad::eOk; } AcDbEllipse* pEllip = AcDbEllipse::cast(pBaseCrv); if (pEllip != NULL) { //下中 3个点 ->0度处 改半径和改内外宽 vtL = AcGeVector3d::kXAxis; ptTmp = pEllip->center(); ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); ptTmp = pEllip->center() + pEllip->majorAxis(); ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); //中下 1个点 ->改标高 ptTmp.z -= dCmd; gripPoints.append(ptTmp); return Acad::eOk; } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::ImpGetUserDefWallGripPoints(AcGePoint3dArray& gripPoints,const WallData& data) const { AcDbCurve* pBaseCrv = m_pBaseCurve; AcDbLine* pLn = AcDbLine::cast(pBaseCrv); AcDbArc* pArc = AcDbArc::cast(pBaseCrv); AcGePoint3d ptGe[3],ptTmp,ptGe1; double dCmd = PixelToWcs(10); AcGeVector3d vtL; if (pLn != NULL || pArc != NULL) { pBaseCrv->getStartPoint(ptGe[0]); pBaseCrv->getEndPoint(ptGe[2]); double dSta = 0.0,dEnd = 0.0,dH = 0.0,dW = 0.0; pBaseCrv->getStartParam(dSta); pBaseCrv->getEndParam(dEnd); pBaseCrv->getPointAtParam((dSta+dEnd) / 2.0,ptGe[1]); ptGe1 = ptGe[1]; //下中 3个点 for (int i = 0;i < 3;i++) { ptGe[i].z = data.dBomEl; gripPoints.append(ptGe[i]); } return Acad::eOk; } AcDbCircle* pCir = AcDbCircle::cast(pBaseCrv); if (pCir != NULL) { //下中 3个点 ->0度处 改圆心,半径,标高 vtL = AcGeVector3d::kXAxis; ptTmp = pCir->center(); ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); ptTmp = pCir->center() + pCir->radius() * vtL; ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); return Acad::eOk; } AcDbEllipse* pEllip = AcDbEllipse::cast(pBaseCrv); if (pEllip != NULL) { //下中 3个点 ->0度处 改圆心,半径,标高 vtL = AcGeVector3d::kXAxis; ptTmp = pEllip->center(); ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); ptTmp = pEllip->center() + pEllip->majorAxis(); ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); return Acad::eOk; } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::ImpGetXShapeSectionWallGripPoints(AcGePoint3dArray& gripPoints,const WallData& data) const { AcDbLine* pLn = AcDbLine::cast(m_pBaseCurve); AcGePoint3d ptGe[3],ptTmp,ptGe1; double dCmd = PixelToWcs(10); AcGeVector3d vtL; if (pLn != NULL) { ptGe[0] = pLn->startPoint(); ptGe[2] = pLn->endPoint(); ptGe[1] = MidPoint(ptGe[0],ptGe[2]); //下中 3个点 for (int i = 0;i < 3;i++) { gripPoints.append(ptGe[i]); } } return Acad::eOk; } EPosition AecDbXWall::ExplainGripIndex(int nIndex,CString& sTip) const { assertReadEnabled(); WallData data; GetWallData(data); AcDbLine* pLn = AcDbLine::cast(m_pBaseCurve); AcDbArc* pArc = AcDbArc::cast(m_pBaseCurve); AcDbCircle* pCir = AcDbCircle::cast(m_pBaseCurve); AcDbEllipse* pEllip = AcDbEllipse::cast(m_pBaseCurve); EPosition ePos = eAdjust0; if (data.nSecShape == eRect) { if (pLn != NULL || pArc != NULL) { switch(nIndex)//最多 11 个点 { case 0://下中线sta ->改起点 { ePos = eStart; sTip = _T("墙线的起点拉伸点"); break; } case 1://下中线mid ->位置移动 { ePos = eMid; sTip = _T("墙线的位置修改夹点"); break; } case 2://下中线End ->改终点 { ePos = eEnd; sTip = _T("墙线的终点拉伸点"); break; } case 3://下中线中下 ->改标高 { ePos = eAdjust0; sTip = _T("墙线的标高修改夹点"); break; } case 4://前线mid ->改宽,不改长 { ePos = eAdjust0; sTip = _T("墙线的宽度修改夹点"); break; } case 5://后线mid ->改宽,不改长 { ePos = eAdjust0; sTip = _T("墙线的宽度修改夹点"); break; } case 6://上线mid ->改高度 { ePos = eAdjust0; sTip = _T("墙线的高度修改夹点"); break; } default: break; } return ePos; } if (pCir != NULL || pEllip != NULL) { switch(nIndex)//最多 11 个点 { case 0://内半径sta ->改内宽 { ePos = eStart; sTip = _T("墙线的改内宽拉伸点"); break; } case 1://半径 ->改半径 { ePos = eMid; sTip = _T("墙线的改半径夹点"); break; } case 2://外半径 ->改外宽 { ePos = eEnd; sTip = _T("墙线的改外宽拉伸点"); break; } case 3://圆心 { ePos = eAdjust0; sTip = _T("墙线的移动夹点"); break; } case 4://圆心下 ->改标高和高 { ePos = eAdjust0; sTip = _T("墙线的标高修改夹点"); break; } case 5://圆心上 ->改高度 { ePos = eAdjust0; sTip = _T("墙线的高度修改夹点"); break; } default: break; } return ePos; } } else if (data.nSecShape == eWw) { if (pLn != NULL || pArc != NULL) { switch(nIndex) { case 0://下中线sta ->改起点 { ePos = eStart; sTip = _T("墙线的起点拉伸点"); break; } case 1://下中线mid ->位置移动 { ePos = eMid; sTip = _T("墙线的位置修改夹点"); break; } case 2://下中线End ->改终点 { ePos = eEnd; sTip = _T("墙线的终点拉伸点"); break; } case 3://下中线中下 ->改标高 { ePos = eAdjust0; sTip = _T("墙线的标高修改夹点"); break; } case 4://前线mid ->改宽,不改长 { ePos = eAdjust0; sTip = _T("墙线的宽度修改夹点"); break; } case 5://后线mid ->改宽,不改长 { ePos = eAdjust0; sTip = _T("墙线的宽度修改夹点"); break; } case 6://上中 { ePos = eMid; sTip = _T("墙线的位置修改夹点"); break; } case 7://上左宽 { ePos = eAdjust0; sTip = _T("墙线的宽度修改夹点"); break; } case 8://上右宽 { ePos = eAdjust0; sTip = _T("墙线的宽度修改夹点"); break; } default: break; } return ePos; } if (pCir != NULL || pEllip != NULL) { switch(nIndex) { case 0: { ePos = eStart; sTip = _T("墙线的位置修改夹点"); break; } case 1: { ePos = eMid; sTip = _T("圆墙线的半径修改夹点"); break; } case 2: { ePos = eAdjust0; sTip = _T("圆墙线的标高修改夹点"); break; } default: break; } return ePos; } } else if (data.nSecShape == eUserDef) { if (pLn != NULL || pArc != NULL) { switch(nIndex) { case 0://下中线sta ->改起点 { ePos = eStart; sTip = _T("墙线的起点拉伸点"); break; } case 1://下中线mid ->位置移动 { ePos = eMid; sTip = _T("墙线的位置修改夹点"); break; } case 2://下中线End ->改终点 { ePos = eEnd; sTip = _T("墙线的终点拉伸点"); break; } case 3://下中线中下 ->改标高 { ePos = eAdjust0; sTip = _T("墙线的标高修改夹点"); break; } default: break; } return ePos; } if (pCir != NULL || pEllip != NULL) { switch(nIndex) { case 0://改圆心 { ePos = eStart; sTip = _T("圆墙线的圆心修改夹点"); break; } case 1://半径 { ePos = eMid; sTip = _T("圆墙线的半径修改夹点"); break; } case 2://标高 { ePos = eEnd; sTip = _T("圆墙线的标高拉伸点"); break; } default: break; } return ePos; } } return ePos; } LPCTSTR AecDbXWall::GetGripCmd() const { assertReadEnabled(); CString sCmd = _T("EW_HZQT"); m_mapSpecXData.GetAt(_T("GRIPCMD"),sCmd);//可能重定义 return sCmd; } Acad::ErrorStatus AecDbXWall::subMoveGripPointsAt(const AcDbVoidPtrArray& gripAppData, const AcGeVector3d& offset, const int bitflags) { AssertWriteEnabled(); ClearForDraw2dables(); WallData data; GetWallData(data); Acad::ErrorStatus es; PreRefreshOpeningDraw(); if (HitOnGripEdit(gripAppData)) { return Acad::eOk; } if (data.nSecShape == eRect) { es = ImpMoveRectWallGripPointsAt(gripAppData,offset); } else if(data.nSecShape == eWw) { es = ImpMoveWwWallGripPointsAt(gripAppData,offset); } else if (data.nSecShape == eUserDef) { es = ImpMoveUserDefWallGripPointsAt(gripAppData,offset); } else if (data.nSecShape == eXShape) { es = ImpMoveXShapeSectionWallGripPointsAt(gripAppData,offset); } RefreshOpeningDraw(); return es; } Acad::ErrorStatus AecDbXWall::PreRefreshOpeningDraw() { if (objectId().isValid()) { AcDbEntity* pEnt = NULL; for (int i = 0;i < m_arAssocPartEntIds.length();i++) { if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,m_arAssocPartEntIds.at(i),AcDb::kForRead)) { AecDbXOpening* pOpen = AecDbXOpening::cast(pEnt); if (pOpen != NULL) { AecComplexCurve win2d; pOpen->GetStandardDraw2d(win2d,false); BoolUniteDraw2d(win2d); } pEnt->close(); } } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::RefreshOpeningDraw() { if (objectId().isValid()) { GripMessage msg; memset(&msg,0,sizeof(GripMessage)); msg.nType = 3; msg.idHost = objectId(); msg.nData = 0; msg.pParam = NULL; msg.fData = 0.0; msg.ptGrip.set(0,0,0); PushGripMessage(msg); acedPostCommand(_T("\x03")); acedPostCommand(_T("PL_QMSX\n")); } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::ImpMoveRectWallGripPointsAt(const AcDbVoidPtrArray& gripAppData, const AcGeVector3d& offset) { AecGripData* pAppData = NULL; AcDbIntArray arIndex; if ( gripAppData.isEmpty() ) { return Acad::eOk; } pAppData = (AecGripData*)gripAppData.first(); arIndex.append(pAppData->nIndex); AcGeVector3d vtOffset = offset; if (offset.isZeroLength()) return Acad::eOk; AcGeVector3d vtXYOffset; vtXYOffset = vtOffset.orthoProject(AcGeVector3d::kZAxis); AcGeVector3d vtZOffset; vtZOffset = vtOffset.orthoProject(AcGeVector3d::kXAxis); AcGeVector3d vtWidth,vtL,vtW,vtH; int nGripIndex = arIndex.first(); AcGeMatrix3d xformM; xformM.setToTranslation(vtOffset); WallData data; GetWallData(data); AcGePoint3d ptTmp,ptTmp2; AcGeMatrix3d xform; double dThick = 0.0,dHAdd = 0.0; double dLen = offset.length(); AcDbCurve* pBaseCrv = m_pBaseCurve; if (pBaseCrv != NULL) { //1.直线墙 AcDbLine* pLn = AcDbLine::cast(pBaseCrv); if (pLn != NULL) { vtL = pLn->endPoint() - pLn->startPoint(); vtW = vtL; vtW.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); switch(pAppData->nIndex)//最多 6 个点 { case 0://下中线sta ->改起点 { AcGeVector3d vt(offset); vt.z = GetElevation(0); dLen = vt.length(); ptTmp = pLn->startPoint(); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; pLn->setStartPoint(ptTmp); break; } case 1://下中线mid ->位置移动 { xform.setToTranslation(vtOffset); pLn->transformBy(xform); TransformAssocPartEnt(xform); TransformDTYGPartEnt(xform); break; } case 2://下中线End ->改终点 { AcGeVector3d vt(offset); vt.z = GetElevation(0); dLen = vt.length(); ptTmp = pLn->endPoint(); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; pLn->setEndPoint(ptTmp); break; } case 3://下中线中下 ->改标高 { ptTmp = pLn->startPoint(); //ptTmp += vtOffset; vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtZOffset; dHAdd = pLn->startPoint().z - ptTmp.z; if (data.nSecShape == eRect)//矩形墙体 { if ( (data.dH + dHAdd)>1.e-3) { SetWallData(data.dThick,data.dH + dHAdd,data.dBomEl - dHAdd); } } break; } case 4://前线mid ->改宽,不改长 { vtWidth = vtXYOffset.orthoProject(vtL); ptTmp = pLn->startPoint(); ptTmp2 = ptTmp + vtWidth; int nDir = 1; dThick = dLen;//vtWidth.length();//增加的宽度 if (!vtW.isCodirectionalTo(vtWidth)) { dThick *= -1.0; //vtWidth.negate(); nDir = -1; } if ( (data.dThick + dThick ) > 1.e-3) { //中线移动一半 vtWidth.normalize(); vtWidth *= dLen; xform.setToTranslation(0.5 * vtWidth); pLn->transformBy(xform); AcGePoint3d ptS = pLn->startPoint(); AcGePoint3d ptE = pLn->endPoint(); if (data.nSecShape == eRect)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dBomEl); //洞口改宽 vtWidth.normalize(); vtWidth *= dThick; vtWidth *= nDir; HoleAndPipeExtend(dThick,0.5 * vtWidth); } else { //... } } break; } case 5://后线mid ->改宽,不改长 { vtWidth = vtXYOffset.orthoProject(vtL); ptTmp = pLn->startPoint(); ptTmp2 = ptTmp + vtWidth; int nDir = 1; dThick = dLen;//vtWidth.length();//增加的宽度 if (vtW.isCodirectionalTo(vtWidth)) { dThick *= -1.0; //vtWidth.negate(); nDir = -1; } if ( (data.dThick + dThick) > 1.e-3) { //中线移动一半 vtWidth.normalize(); vtWidth *= dLen; xform.setToTranslation(0.5 * vtWidth); pLn->transformBy(xform); if (data.nSecShape == eRect)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dBomEl); //洞口改宽 vtWidth.normalize(); vtWidth *= dThick; vtWidth *= nDir; HoleAndPipeExtend(dThick,0.5 * vtWidth); } else { //.. } } break; } case 6://上线mid ->改高度 { ptTmp = pLn->startPoint(); //ptTmp += vtOffset; vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtZOffset; dHAdd = ptTmp.z - pLn->startPoint().z; if (data.nSecShape == eRect)//矩形墙体 { if ( (data.dH + dHAdd) > 1.e-3) { SetWallData(data.dThick,data.dH + dHAdd,data.dBomEl); } } break; } default: break; } } //2.弧线墙体 AcDbArc* pArc = AcDbArc::cast(pBaseCrv); if (pArc != NULL) { AcGePoint3d ptGe[3]; double dSta = 0.0,dEnd = 0.0,dR = 0.0; pArc->getStartParam(dSta); pArc->getEndParam(dEnd); pArc->getPointAtParam((dSta+dEnd) / 2.0,ptGe[1]); vtW = ptGe[1] - pArc->center(); vtW.normalize(); vtL = vtW; vtL.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); dR = pArc->radius(); switch(pAppData->nIndex)//最多 6 个点 { case 0://下中线sta ->改起点 { pArc->getStartPoint(ptTmp); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; pArc->getEndPoint(ptTmp2); AcDbArc* pArcNew = FormatArc(ptTmp,ptGe[1],ptTmp2); if (pArcNew != NULL) { pArc->setStartAngle(pArcNew->startAngle()); pArc->setEndAngle(pArcNew->endAngle()); pArc->setCenter(pArcNew->center()); pArc->setRadius(pArcNew->radius()); delete pArcNew; } break; } case 1://下中线mid ->位置移动 { //xform.setToTranslation(vtXYOffset); xform.setToTranslation(vtOffset); pArc->transformBy(xform); TransformAssocPartEnt(xform); TransformDTYGPartEnt(xform); break; } case 2://下中线End ->改终点 { pArc->getEndPoint(ptTmp); pArc->getStartPoint(ptTmp2); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; AcDbArc* pArcNew = FormatArc(ptTmp2,ptGe[1],ptTmp); if (pArcNew != NULL) { pArc->setStartAngle(pArcNew->startAngle()); pArc->setEndAngle(pArcNew->endAngle()); pArc->setCenter(pArcNew->center()); pArc->setRadius(pArcNew->radius()); delete pArcNew; } break; } case 3://下中线中下 ->改标高和高度 { pArc->getStartPoint(ptTmp); vtZOffset.normalize(); vtZOffset *= dLen; //ptTmp += vtOffset; ptTmp += vtZOffset; pArc->getStartPoint(ptTmp2); dHAdd = ptTmp2.z - ptTmp.z; if (data.nSecShape == eRect)//矩形墙体 { SetWallData(data.dThick,data.dH + dHAdd,data.dBomEl - dHAdd); } break; } case 4://前线mid ->改宽,不改长 { vtWidth = vtXYOffset.orthoProject(vtL); pArc->getStartPoint(ptTmp); ptTmp2 = ptTmp + vtWidth; dThick = dLen;//vtWidth.length();//增加的宽度 if (vtW.dotProduct(vtWidth) < 1.e-3)//反向 { dThick *= -1.0; vtWidth.negate(); } if ( (data.dThick + dThick) > 1.e-3) { pArc->setRadius(dR + 0.5 * dThick); if (data.nSecShape == eRect)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dBomEl); //洞口调整 AdjustHoleAndPipe(data.dThick,dThick,-1); } } break; } case 5://后线mid ->改宽,不改长 { vtWidth = vtXYOffset.orthoProject(vtL); pArc->getStartPoint(ptTmp); ptTmp2 = ptTmp + vtWidth; //中线移动一半 dThick = dLen;//vtWidth.length();//增加的宽度 if (vtW.dotProduct(vtWidth) > 1.e-3)//正向 { dThick *= -1.0; } if ( (data.dThick + dThick) > 1.e-3) { pArc->setRadius(dR - 0.5 * dThick); if (data.nSecShape == eRect)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dBomEl); //洞口调整 AdjustHoleAndPipe(data.dThick,dThick); } } break; } case 6://上线mid ->改高度 { pArc->getStartPoint(ptTmp); ptTmp2 = ptTmp; //ptTmp += vtOffset; vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtZOffset; dHAdd = ptTmp.z - ptTmp2.z; if (data.nSecShape == eRect)//矩形墙体 { if ( (data.dH + dHAdd) > 1.e-3) { SetWallData(data.dThick,data.dH + dHAdd,data.dBomEl); } } break; } default: break; } } //3.圆墙体 AcDbCircle* pCir = AcDbCircle::cast(pBaseCrv); if (pCir != NULL) { double dR = pCir->radius(); switch(pAppData->nIndex)//最多 6 个点 { case 0://改内宽 { vtWidth = vtXYOffset.orthoProject(AcGeVector3d::kYAxis); dThick = vtWidth.length();//增加的宽度 if (vtWidth.isCodirectionalTo(AcGeVector3d::kXAxis)) { dThick *= -1.0; vtWidth.negate(); } if ( (data.dThick + dThick) > 1.e-3) { //中线移动一半 //xform.setToTranslation(0.5 * vtWidth); pCir->setRadius(dR - 0.5 * dThick); if (data.nSecShape == eRect)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dBomEl); //洞口调整 AdjustHoleAndPipe(data.dThick,dThick,-1); } } break; } case 1://改半径 { vtWidth = vtXYOffset.orthoProject(AcGeVector3d::kYAxis); dThick = vtWidth.length();//增加的半径 if (!vtWidth.isCodirectionalTo(AcGeVector3d::kXAxis)) { dThick *= -1.0; } if ( (pCir->radius() + dThick) > 1.e-3) { pCir->setRadius(pCir->radius() + dThick); //洞口改宽 HoleAndPipeExtend(dThick,AcGeVector3d(0,0,0)); } break; } case 2://改外宽 { vtWidth = vtXYOffset.orthoProject(AcGeVector3d::kYAxis); dThick = vtWidth.length();//增加的宽度 if (!vtWidth.isCodirectionalTo(AcGeVector3d::kXAxis)) { dThick *= -1.0; vtWidth.negate(); } //中线移动一半 if ( (data.dThick + dThick) > 1.e-3) { xform.setToTranslation(0.5 * vtWidth); //pCir->transformBy(xform); pCir->setRadius(dR + 0.5 * dThick); if (data.nSecShape == eRect)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dBomEl); //洞口调整 AdjustHoleAndPipe(data.dThick,dThick); } } break; } case 3://下中 ->位移点 { xform.setToTranslation(vtXYOffset); pCir->transformBy(xform); break; } case 4://中下 ->拉底,改标高 { ptTmp = pCir->center(); ptTmp += vtOffset; dHAdd = pCir->center().z - ptTmp.z; if (data.nSecShape == eRect)//矩形墙体 { if ( (data.dH + dHAdd) > 1.e-3) { SetWallData(data.dThick,data.dH + dHAdd,data.dBomEl - dHAdd); } } break; } case 5://顶部中 ->拉高 { ptTmp = pCir->center(); ptTmp.z = data.dBomEl; ptTmp.z += data.dH; ptTmp2 = ptTmp; ptTmp2 += vtOffset; dHAdd = ptTmp2.z - ptTmp.z; if (data.nSecShape == eRect)//矩形墙体 { if ( (data.dH + dHAdd) > 1.e-3) { SetWallData(data.dThick,data.dH + dHAdd,data.dBomEl); } } break; } default: break; } } AcDbEllipse* pEllip = AcDbEllipse::cast(pBaseCrv); if (pEllip != NULL) { switch(pAppData->nIndex)//最多 6 个点 { case 0://改内宽 { vtWidth = vtXYOffset.orthoProject(AcGeVector3d::kYAxis); dThick = vtWidth.length();//增加的宽度 if (vtWidth.isCodirectionalTo(AcGeVector3d::kXAxis)) { dThick *= -1.0; vtWidth.negate(); } //中线移动一半 if ( (data.dThick + dThick) > 1.e-3) { xform.setToTranslation(0.5 * vtWidth); pEllip->transformBy(xform); if (data.nSecShape == eRect)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dBomEl); } } break; } case 1://改半径 { vtWidth = vtXYOffset.orthoProject(AcGeVector3d::kYAxis); dThick = vtWidth.length();//增加的半径 if (!vtWidth.isCodirectionalTo(AcGeVector3d::kXAxis)) { dThick *= -1.0; } AcGeVector3d vtMaj = pEllip->majorAxis(); double dMaj = vtMaj.length() + dThick; vtMaj.normalize(); vtMaj *= dMaj; pEllip->set(pEllip->center(),AcGeVector3d::kZAxis,vtMaj,pEllip->radiusRatio()); break; } case 2://改外宽 { vtWidth = vtXYOffset.orthoProject(AcGeVector3d::kYAxis); dThick = vtWidth.length();//增加的宽度 if (!vtWidth.isCodirectionalTo(AcGeVector3d::kXAxis)) { dThick *= -1.0; vtWidth.negate(); } //中线移动一半 if ( (data.dThick + dThick) > 1.e-3) { xform.setToTranslation(0.5 * vtWidth); pEllip->transformBy(xform); if (data.nSecShape == eRect)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dBomEl); } } break; } case 3://下中 ->位移点 { xform.setToTranslation(vtXYOffset); pEllip->transformBy(xform); break; } case 4://中下 ->拉底,改标高 { ptTmp = pEllip->center(); ptTmp += vtOffset; dHAdd = pEllip->center().z - ptTmp.z; if (data.nSecShape == eRect)//矩形墙体 { if ( (data.dH + dHAdd) > 1.e-3) { SetWallData(data.dThick,data.dH + dHAdd,data.dBomEl - dHAdd); } } break; } case 5://顶部中 ->拉高 { ptTmp = pEllip->center(); ptTmp.z = data.dBomEl; ptTmp.z += data.dH; ptTmp2 = ptTmp; ptTmp2 += vtOffset; dHAdd = ptTmp2.z - ptTmp.z; if (data.nSecShape == eRect)//矩形墙体 { if ( (data.dH + dHAdd) > 1.e-3) { SetWallData(data.dThick,data.dH + dHAdd,data.dBomEl); } } break; } default: break; } } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::ImpMoveWwWallGripPointsAt(const AcDbVoidPtrArray& gripAppData, const AcGeVector3d& offset) { AssertWriteEnabled(); AecGripData* pAppData = NULL; AcDbIntArray arIndex; if ( gripAppData.isEmpty() ) { return Acad::eOk; } pAppData = (AecGripData*)gripAppData.first(); arIndex.append(pAppData->nIndex); double dLen = offset.length(); AcGeVector3d vtOffset = offset; AcGeVector3d vtXYOffset; vtXYOffset = vtOffset.orthoProject(AcGeVector3d::kZAxis); AcGeVector3d vtZOffset; vtZOffset = vtOffset.orthoProject(AcGeVector3d::kXAxis); AcGeVector3d vtWidth,vtL,vtW,vtH; int nGripIndex = arIndex.first(); AcGeMatrix3d xformM; xformM.setToTranslation(vtOffset); WallData data; GetWallData(data); AcGePoint3d ptTmp,ptTmp2; AcGeMatrix3d xform; double dThick = 0.0,dHAdd = 0.0; double dThick2 = 0.0,dH2 = 0.0; AcDbCurve* pBaseCrv = m_pBaseCurve; if (pBaseCrv != NULL) { AcDbLine* pLn = AcDbLine::cast(pBaseCrv); if (pLn != NULL) { vtL = pLn->endPoint() - pLn->startPoint(); vtW = vtL; vtW.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); switch(nGripIndex) { case 0://下中线sta ->改起点 { ptTmp = pLn->startPoint(); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; pLn->setStartPoint(ptTmp); break; } case 1://下中线mid ->位置移动 { xform.setToTranslation(vtOffset); pLn->transformBy(xform); TransformAssocPartEnt(xform); TransformDTYGPartEnt(xform); break; } case 2://下中线End ->改终点 { ptTmp = pLn->endPoint(); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; pLn->setEndPoint(ptTmp); break; } case 3://下中线中下 ->改标高 { ptTmp = pLn->startPoint(); //ptTmp += vtOffset; vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtZOffset; dHAdd = pLn->startPoint().z - ptTmp.z; if (data.nSecShape == eWw)//矩形墙体 { if ( (data.dH2 + dHAdd) > 1.e-1) { SetWallData(data.dThick,data.dH + dHAdd,data.dThick2,data.dH2 + dHAdd,data.nW2Pos,data.dBomEl - dHAdd,data.kAlign); } } break; } case 4://前线mid ->改宽,不改长 { vtWidth = vtXYOffset.orthoProject(vtL); ptTmp = pLn->startPoint(); ptTmp2 = ptTmp + vtWidth; vtWidth.normalize(); vtWidth *= dLen; xform.setToTranslation(0.5 * vtWidth); pLn->transformBy(xform); dThick2 = dLen;//vtWidth.length();//增加的宽度 if (!vtW.isCodirectionalTo(vtWidth)) { dThick2 *= -1.0; } if ( (data.dThick2 + dThick2) > 1.e-2)//矩形墙体 { SetWallData(data.dThick,data.dH,data.dThick2 + dThick2,data.dH2,data.nW2Pos,data.dBomEl,data.kAlign); } break; } case 5://后线mid ->改宽,不改长 { vtWidth = vtXYOffset.orthoProject(vtL); ptTmp = pLn->startPoint(); ptTmp2 = ptTmp + vtWidth; //中线移动一半 vtWidth.normalize(); vtWidth *= dLen; xform.setToTranslation(0.5 * vtWidth); pLn->transformBy(xform); dThick2 = dLen;//vtWidth.length();//增加的宽度 if (vtW.isCodirectionalTo(vtWidth)) { dThick2 *= -1.0; } if ( (data.dThick2 + dThick2) > 1.e-2)//矩形墙体 { SetWallData(data.dThick,data.dH,data.dThick2 + dThick2,data.dH2,data.nW2Pos,data.dBomEl,data.kAlign); } break; } case 6://上三个点->中 改高 { //vtH = AcGeVector3d::kZAxis; vtH = vtZOffset; vtH *= dLen; //vtH.z = dLen;//offset.z; if ( (data.dH + vtH.z ) > 1.e-2) { SetWallData(data.dThick,data.dH + vtH.z,data.dThick2,data.dH2,data.nW2Pos,data.dBomEl,data.kAlign); } break; } case 7://宽 { vtWidth = vtXYOffset.orthoProject(vtL); ptTmp = pLn->startPoint(); ptTmp2 = ptTmp + vtWidth; vtWidth.normalize(); vtWidth *= dLen; xform.setToTranslation(0.5 * vtWidth); pLn->transformBy(xform); dThick = dLen;//vtWidth.length();//增加的宽度 if (!vtW.isCodirectionalTo(vtWidth)) { dThick *= -1.0; } if ( (data.dThick + dThick) > 1.e-2)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dThick2 + dThick,data.dH2,data.nW2Pos,data.dBomEl,data.kAlign); } break; } case 8://宽 { vtWidth = vtXYOffset.orthoProject(vtL); ptTmp = pLn->startPoint(); ptTmp2 = ptTmp + vtWidth; //中线移动一半 vtWidth.normalize(); vtWidth *= dLen; xform.setToTranslation(0.5 * vtWidth); pLn->transformBy(xform); dThick = dLen;//vtWidth.length();//增加的宽度 if (vtW.isCodirectionalTo(vtWidth)) { dThick *= -1.0; } if ( (data.dThick + dThick) > 1.e-2)//矩形墙体 { SetWallData(data.dThick + dThick,data.dH,data.dThick2 + dThick,data.dH2,data.nW2Pos,data.dBomEl,data.kAlign); } break; } default: break; } return Acad::eOk; } AcDbArc* pArc = AcDbArc::cast(pBaseCrv); if (pArc != NULL) { AcGePoint3d ptGe[3]; double dSta = 0.0,dEnd = 0.0,dR = 0.0; pArc->getStartParam(dSta); pArc->getEndParam(dEnd); pArc->getPointAtParam((dSta+dEnd) / 2.0,ptGe[1]); vtW = ptGe[1] - pArc->center(); vtW.normalize(); vtL = vtW; vtL.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); dR = pArc->radius(); switch(pAppData->nIndex)//最多 6 个点 { case 0://下中线sta ->改起点 { pArc->getStartPoint(ptTmp); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; pArc->getEndPoint(ptTmp2); AcDbArc* pArcNew = FormatArc(ptTmp,ptGe[1],ptTmp2); if (pArcNew != NULL) { pArc->setStartAngle(pArcNew->startAngle()); pArc->setEndAngle(pArcNew->endAngle()); pArc->setCenter(pArcNew->center()); pArc->setRadius(pArcNew->radius()); delete pArcNew; } break; } case 1://下中线mid ->位置移动 { xform.setToTranslation(vtOffset); pArc->transformBy(xform); TransformAssocPartEnt(xform); TransformDTYGPartEnt(xform); break; } case 2://下中线End ->改终点 { pArc->getEndPoint(ptTmp); pArc->getStartPoint(ptTmp2); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; AcDbArc* pArcNew = FormatArc(ptTmp2,ptGe[1],ptTmp); if (pArcNew != NULL) { pArc->setStartAngle(pArcNew->startAngle()); pArc->setEndAngle(pArcNew->endAngle()); pArc->setCenter(pArcNew->center()); pArc->setRadius(pArcNew->radius()); delete pArcNew; } break; } case 3://中下 1个点 改H2 { pArc->getStartPoint(ptTmp); //ptTmp += vtOffset; vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtZOffset; pArc->getStartPoint(ptTmp2); dHAdd = ptTmp2.z - ptTmp.z; if (data.nSecShape == eWw)//矩形墙体 { if ( (data.dH2 + dHAdd) > 1.e-1) { SetWallData(data.dThick,data.dH + dHAdd,data.dThick2,data.dH2 + dHAdd,data.nW2Pos,data.dBomEl - dHAdd,data.kAlign); } } break; } case 4://前线mid ->改宽,不改长 { vtWidth = vtXYOffset.orthoProject(vtL); pArc->getStartPoint(ptTmp); ptTmp2 = ptTmp + vtWidth; dThick2 = dLen;//vtWidth.length();//增加的宽度 if (vtW.dotProduct(vtWidth) < 1.e-3)//反向 { dThick2 *= -1.0; } if ( (data.dThick2 + dThick2) > 1.e-3) { pArc->setRadius(dR + 0.5 * dThick2); if ( (data.dThick2 + dThick2) > 1.e-2) { SetWallData(data.dThick,data.dH,data.dThick2 + dThick2,data.dH2,data.nW2Pos,data.dBomEl,data.kAlign); } } break; } case 5://后线mid ->改宽,不改长 { vtWidth = vtXYOffset.orthoProject(vtL); pArc->getStartPoint(ptTmp); ptTmp2 = ptTmp + vtWidth; //中线移动一半 dThick2 = dLen;//vtWidth.length();//增加的宽度 if (vtW.dotProduct(vtWidth) > 1.e-3)//正向 { dThick2 *= -1.0; } if ( (data.dThick + dThick) > 1.e-3) { pArc->setRadius(dR - 0.5 * dThick2); if ( (data.dThick2 + dThick2) > 1.e-2) { SetWallData(data.dThick,data.dH,data.dThick2 + dThick2,data.dH2,data.nW2Pos,data.dBomEl,data.kAlign); } } break; } default: break; } /* //下中 3个点 ->0度处 改半径和改内外宽 vtL = AcGeVector3d::kXAxis; ptTmp = pCir->center(); ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); ptTmp = pCir->center() + pCir->radius() * vtL; ptTmp.z = data.dBomEl; gripPoints.append(ptTmp); //中下 1个点 ->改标高 ptTmp.z -= dCmd; gripPoints.append(ptTmp); return Acad::eOk; */ } AcDbCircle* pCir = AcDbCircle::cast(pBaseCrv); if (pCir != NULL) { switch(pAppData->nIndex) { case 0://中心,位移 { xform.setToTranslation(vtOffset); pCir->transformBy(xform); TransformAssocPartEnt(xform); TransformDTYGPartEnt(xform); break; } case 1://改半径 { ptTmp = pCir->center() + pCir->radius() * AcGeVector3d::kXAxis; ptTmp += vtXYOffset; double dR = ptTmp.distanceTo(pCir->center()); pCir->setRadius(dR); break; } case 2://改标高 { ptTmp = pCir->center(); //ptTmp += vtOffset; vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtZOffset; ptTmp2 = pCir->center(); dHAdd = ptTmp2.z - ptTmp.z; if (data.nSecShape == eWw)//矩形墙体 { if ( (data.dH2 + dHAdd) > 1.e-1) { SetWallData(data.dThick,data.dH + dHAdd,data.dThick2,data.dH2 + dHAdd,data.nW2Pos,data.dBomEl - dHAdd,data.kAlign); } } break; } default: break; } } AcDbEllipse* pEllip = AcDbEllipse::cast(pBaseCrv); if (pEllip != NULL) { switch(pAppData->nIndex) { case 0://中心,位移 { xform.setToTranslation(vtOffset); pEllip->transformBy(xform); TransformAssocPartEnt(xform); TransformDTYGPartEnt(xform); break; } case 1://改半径 { ptTmp = pEllip->center() + pEllip->majorAxis(); ptTmp += vtXYOffset; double dR = ptTmp.distanceTo(pEllip->center()); AcGeVector3d vtMaj = pEllip->majorAxis(); vtMaj.normalize(); vtMaj *= dR; pEllip->set(pEllip->center(),pEllip->normal(),vtMaj,pEllip->radiusRatio()); break; } case 2://改标高 { ptTmp = pEllip->center(); //ptTmp += vtOffset; vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtZOffset; ptTmp2 = pEllip->center(); dHAdd = ptTmp2.z - ptTmp.z; if (data.nSecShape == eWw)//矩形墙体 { if ( (data.dH2 + dHAdd) > 1.e-1) { SetWallData(data.dThick,data.dH + dHAdd,data.dThick2,data.dH2 + dHAdd,data.nW2Pos,data.dBomEl - dHAdd,data.kAlign); } } break; } default: break; } } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::ImpMoveUserDefWallGripPointsAt(const AcDbVoidPtrArray& gripAppData, const AcGeVector3d& offset) { AssertWriteEnabled(); AecGripData* pAppData = NULL; AcDbIntArray arIndex; if ( gripAppData.isEmpty() ) { return Acad::eOk; } pAppData = (AecGripData*)gripAppData.first(); arIndex.append(pAppData->nIndex); AcGeVector3d vtOffset = offset; AcGeVector3d vtXYOffset; vtXYOffset = vtOffset.orthoProject(AcGeVector3d::kZAxis); AcGeVector3d vtZOffset; vtZOffset = vtOffset.orthoProject(AcGeVector3d::kXAxis); AcGeVector3d vtWidth,vtL,vtW,vtH; int nGripIndex = arIndex.first(); AcGeMatrix3d xformM; xformM.setToTranslation(vtOffset); double dLen = offset.length(); WallData data; GetWallData(data); AcGePoint3d ptTmp,ptTmp2; AcGeMatrix3d xform; double dThick = 0.0,dHAdd = 0.0; double dThick2 = 0.0,dH2 = 0.0; AcDbCurve* pBaseCrv = m_pBaseCurve; if (pBaseCrv != NULL) { AcDbLine* pLn = AcDbLine::cast(pBaseCrv); if (pLn != NULL) { vtL = pLn->endPoint() - pLn->startPoint(); vtW = vtL; vtW.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); switch(nGripIndex) { case 0://下中线sta ->改起点 { ptTmp = pLn->startPoint(); vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtXYOffset; pLn->setStartPoint(ptTmp); break; } case 1://下中线mid ->位置移动 { xform.setToTranslation(vtOffset); pLn->transformBy(xform); TransformAssocPartEnt(xform); TransformDTYGPartEnt(xform); break; } case 2://下中线End ->改终点 { ptTmp = pLn->endPoint(); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; pLn->setEndPoint(ptTmp); break; } default: break; } return Acad::eOk; } AcDbArc* pArc = AcDbArc::cast(pBaseCrv); if (pArc != NULL) { AcGePoint3d ptGe[3]; double dSta = 0.0,dEnd = 0.0,dR = 0.0; pArc->getStartParam(dSta); pArc->getEndParam(dEnd); pArc->getPointAtParam((dSta+dEnd) / 2.0,ptGe[1]); vtW = ptGe[1] - pArc->center(); vtW.normalize(); vtL = vtW; vtL.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); dR = pArc->radius(); switch(pAppData->nIndex)//最多 6 个点 { case 0://下中线sta ->改起点 { pArc->getStartPoint(ptTmp); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; pArc->getEndPoint(ptTmp2); AcDbArc* pArcNew = FormatArc(ptTmp,ptGe[1],ptTmp2); if (pArcNew != NULL) { pArc->setStartAngle(pArcNew->startAngle()); pArc->setEndAngle(pArcNew->endAngle()); pArc->setCenter(pArcNew->center()); pArc->setRadius(pArcNew->radius()); delete pArcNew; } break; } case 1://下中线mid ->位置移动 { xform.setToTranslation(vtOffset); pArc->transformBy(xform); TransformAssocPartEnt(xform); TransformDTYGPartEnt(xform); break; } case 2://下中线End ->改终点 { pArc->getEndPoint(ptTmp); pArc->getStartPoint(ptTmp2); vtXYOffset.normalize(); vtXYOffset *= dLen; ptTmp += vtXYOffset; AcDbArc* pArcNew = FormatArc(ptTmp2,ptGe[1],ptTmp); if (pArcNew != NULL) { pArc->setStartAngle(pArcNew->startAngle()); pArc->setEndAngle(pArcNew->endAngle()); pArc->setCenter(pArcNew->center()); pArc->setRadius(pArcNew->radius()); delete pArcNew; } break; } } return Acad::eOk; } AcDbCircle* pCir = AcDbCircle::cast(pBaseCrv); if (pCir != NULL) { double dR = 0.0; switch(pAppData->nIndex)//最多 6 个点 { case 0:// 下中 ->位移点 { xform.setToTranslation(vtOffset); pCir->transformBy(xform); break; } case 1://改半径 { vtWidth = vtXYOffset.orthoProject(AcGeVector3d::kYAxis); dThick = dLen;//vtWidth.length();//增加的半径 if (!vtWidth.isCodirectionalTo(AcGeVector3d::kXAxis)) { dThick *= -1.0; } dR = pCir->radius() + dThick; if (dR > 1.e-2) { pCir->setRadius(pCir->radius() + dThick); } break; } default: break; } return Acad::eOk; } AcDbEllipse* pEllip = AcDbEllipse::cast(pBaseCrv); if (pEllip != NULL) { double dR = 0.0; switch(pAppData->nIndex)//最多 6 个点 { case 0://改半径 { vtWidth = vtXYOffset.orthoProject(AcGeVector3d::kYAxis); dThick = dLen;//vtWidth.length();//增加的半径 if (!vtWidth.isCodirectionalTo(AcGeVector3d::kXAxis)) { dThick *= -1.0; } dR = pEllip->majorAxis().length() + dThick; if (dR > 1.e-2) { AcGeVector3d vtMaj = pEllip->majorAxis(); vtMaj.normalize(); vtMaj *= dR; pEllip->set(pEllip->center(),pEllip->normal(),vtMaj,pEllip->radiusRatio()); } break; } case 1://下中 ->位移点 { xform.setToTranslation(vtOffset); pEllip->transformBy(xform); break; } default: break; } return Acad::eOk; } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::ImpMoveXShapeSectionWallGripPointsAt(const AcDbVoidPtrArray& gripAppData, const AcGeVector3d& offset) { AssertWriteEnabled(); AecGripData* pAppData = NULL; AcDbIntArray arIndex; if ( gripAppData.isEmpty() ) { return Acad::eOk; } pAppData = (AecGripData*)gripAppData.first(); arIndex.append(pAppData->nIndex); AcGeVector3d vtOffset = offset; AcGeVector3d vtXYOffset; vtXYOffset = vtOffset.orthoProject(AcGeVector3d::kZAxis); AcGeVector3d vtZOffset; vtZOffset = vtOffset.orthoProject(AcGeVector3d::kXAxis); AcGeVector3d vtWidth,vtL,vtW,vtH; int nGripIndex = arIndex.first(); AcGeMatrix3d xformM; xformM.setToTranslation(vtOffset); double dLen = offset.length(); WallData data; GetWallData(data); AcGePoint3d ptTmp,ptTmp2; AcGeMatrix3d xform; double dThick = 0.0,dHAdd = 0.0; double dThick2 = 0.0,dH2 = 0.0; AcDbCurve* pBaseCrv = m_pBaseCurve; if (pBaseCrv != NULL) { AcDbLine* pLn = AcDbLine::cast(pBaseCrv); if (pLn != NULL) { vtL = pLn->endPoint() - pLn->startPoint(); vtW = vtL; vtW.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); switch(nGripIndex) { case 0://下中线sta ->改起点 { ptTmp = pLn->startPoint(); vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtZOffset; pLn->setStartPoint(ptTmp); break; } case 1://下中线mid ->位置移动 { xform.setToTranslation(vtOffset); pLn->transformBy(xform); TransformAssocPartEnt(xform); TransformDTYGPartEnt(xform); break; } case 2://下中线End ->改终点 { ptTmp = pLn->endPoint(); vtZOffset.normalize(); vtZOffset *= dLen; ptTmp += vtZOffset; pLn->setEndPoint(ptTmp); break; } default: break; } } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const { assertReadEnabled(); if (m_pBaseCurve != NULL) { AcGeVector3d vt; AcGePoint3d ptSta,ptEnd,ptMid; AcDbLine* pLn = AcDbLine::cast(m_pBaseCurve); if (pLn != NULL) { ptSta = pLn->startPoint(); ptEnd = pLn->endPoint(); ptMid = MidPoint(ptSta,ptEnd); vt = ptEnd - ptSta; pLn->getStretchPoints(stretchPoints); vt.normalize(); vt.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); WallData data; GetWallData(data); //厚度 ptMid += vt * 0.5 * data.dThick; stretchPoints.append(ptMid); ptMid -= vt * data.dThick; stretchPoints.append(ptMid); //底部墙体标高 ptMid.z = data.dBomEl; stretchPoints.append(ptMid); //顶部墙体高度 ptMid.z += data.dH; stretchPoints.append(ptMid); } else { m_pBaseCurve->getStretchPoints(stretchPoints); WallData data; GetWallData(data); //墙体高度 double dS = 0.0,dE = 0.0; getStartParam(dS); getEndParam(dE); getPointAtParam((dS + dE) / 2.0,ptMid); //底部墙体标高 ptMid.z = data.dBomEl; stretchPoints.append(ptMid); ptMid.z += data.dH; stretchPoints.append(ptMid); } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::MoveHeightStretchPoint(int nPos,const AcGeVector3d& offset) { AssertWriteEnabled(); AcGeVector3d vtZ; vtZ = offset.orthoProject(AcGeVector3d::kYAxis); double dh = vtZ.length(); if (nPos == 0)//底部标高位点 { double dH = 0.0; m_mapSpecXData.GetAt(KEY_SIZE2,dH); if (vtZ.isCodirectionalTo(AcGeVector3d::kZAxis)) { dh *= -1.0; } WallData data; GetWallData(data); dH += dh; data.dBomEl -= dh; if (dH > 10.0)//至少10个高度 { int nW2Pos = 0; m_mapSpecXData.GetAt(KEY_W2POS,nW2Pos); SetWallData(data.dThick,dH,data.dThick2,data.dH2,nW2Pos,data.dBomEl,kMid); AcGeMatrix3d xMove; xMove.setToTranslation(vtZ); m_pBaseCurve->transformBy(xMove); } } else if (nPos == 1)//顶部高度位点 { if (vtZ.isCodirectionalTo(-AcGeVector3d::kZAxis)) { dh *= -1.0; } double dH = 0.0; m_mapSpecXData.GetAt(KEY_SIZE2,dH); dH += dh; if (dH > 10.0)//至少10个高度 { WallData data; GetWallData(data); int nW2Pos = 0; m_mapSpecXData.GetAt(KEY_W2POS,nW2Pos); SetWallData(data.dThick,dH,data.dThick2,data.dH2,nW2Pos,data.dBomEl,kMid); } } return Acad::eOk; } Acad::ErrorStatus AecDbXWall::subMoveStretchPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset) { AssertWriteEnabled(); ClearForDraw2dables(); Acad::ErrorStatus es; if (m_pBaseCurve != NULL) { AcDbLine* pLn = AcDbLine::cast(m_pBaseCurve); if (pLn != NULL) //直线墙体 { AcGePoint3dArray arPts; pLn->getStretchPoints(arPts); //由于增加的墙体高度,所以arPts + 2 //0,1.. nStartIndex (厚度) ,nStartIndex+1 (厚度) ,nStartIndex+2 (高度) int nStartIndex = arPts.length(); //如果含有墙体高度的index extern BOOL IsFrontView(); if (IsFrontView()) { if (indices.find(nStartIndex + 2) != -1 && indices.find(nStartIndex + 3) == -1)//含有底部标高位点,且立面拉伸 { return MoveHeightStretchPoint(0,offset); } if (indices.find(nStartIndex + 3) != -1 && indices.find(nStartIndex + 2) == -1)//含有顶部高度位点,且立面拉伸 { return MoveHeightStretchPoint(1,offset); } if (indices.find(nStartIndex + 3) != -1 && indices.find(nStartIndex + 2) != -1) { //移动 AcGeMatrix3d xMove; xMove.setToTranslation(offset); //立面移动 double dh = offset.length(); if (offset.isCodirectionalTo(AcGeVector3d::kZAxis)) { dh *= -1.0; } WallData data; GetWallData(data); data.dBomEl -= dh; int nW2Pos = 0; m_mapSpecXData.GetAt(KEY_W2POS,nW2Pos); SetWallData(data.dThick,data.dH,data.dThick2,data.dH2,nW2Pos,data.dBomEl,kMid); m_pBaseCurve->transformBy(xMove); } return Acad::eOk; } //其他俯视图的拉伸处理.... AcGePoint3d ptSta = pLn->startPoint(); AcGePoint3d ptEnd = pLn->endPoint(); AcGePoint3d ptMid = MidPoint(ptSta,ptEnd); AcGeVector3d vtL = ptEnd - ptSta; vtL.z = 0.0; //3 AcGeVector3d vtV = vtL; vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); //4 AcGeVector3d vtV0 = vtV; vtV0.negate(); AcGeVector3d vtOff = offset; vtOff.z = 0.0; //0,1.. nStartIndex,nStartIndex+1 //如果含有 nStartIndex 或 nStartIndex+1 int nbHasThickGrip = 0; int nGripIndex = 0; for (int i = 0;i < indices.length();i++) { nGripIndex = indices.at(i); if (nGripIndex == nStartIndex || nGripIndex == (nStartIndex+1)) { nbHasThickGrip += nGripIndex; } } if (nbHasThickGrip < ( 2 * nStartIndex + 1) && nbHasThickGrip >= nStartIndex )//只有一个的情况 { double dAngL = vtOff.angleTo(vtL); if ( (dAngL - PI / 2.0) > 1.e-10) { dAngL = PI - dAngL; } double dAngV = vtOff.angleTo(vtV); if ( (dAngV - PI / 2.0) > 1.e-10) { dAngV = PI - dAngV; } if (dAngL < dAngV)//标准拉伸 { es = m_pBaseCurve->moveStretchPointsAt(indices,offset); } else { double dL = offset.length(); vtOff = offset.orthoProject(vtL); vtOff.normalize(); vtOff *= dL; double dThick = 0.0; m_mapSpecXData.GetAt(KEY_SIZE1,dThick); if (nbHasThickGrip == nStartIndex)//vtV { if (vtOff.dotProduct(vtV) > 1.e-10) { //增厚 dThick += dL; } else { dThick -= dL; } ptSta += 0.5 * vtOff; ptEnd += 0.5 * vtOff; pLn->setStartPoint(ptSta); pLn->setEndPoint(ptEnd); double dH = 0.0,dBomEl = 0.0; m_mapSpecXData.GetAt(KEY_SIZE2,dH); m_mapSpecXData.GetAt(PIPE_EL,dBomEl); double dThick2 = 0.0,dH2 = 0.0; m_mapSpecXData.GetAt(KEY_SIZE3,dThick2); m_mapSpecXData.GetAt(KEY_SIZE4,dH2); int nW2Pos = 0; m_mapSpecXData.GetAt(KEY_W2POS,nW2Pos); SetWallData(dThick,dH,dThick2,dH2,nW2Pos,dBomEl,kMid); } else// 4 vtV0 { if (vtOff.dotProduct(vtV0) > 1.e-10) { //增厚 dThick += dL; } else { dThick -= dL; } ptSta += 0.5 * vtOff; ptEnd += 0.5 * vtOff; pLn->setStartPoint(ptSta); pLn->setEndPoint(ptEnd); double dH = 0.0,dBomEl = 0.0; m_mapSpecXData.GetAt(KEY_SIZE2,dH); m_mapSpecXData.GetAt(PIPE_EL,dBomEl); double dThick2 = 0.0,dH2 = 0.0; m_mapSpecXData.GetAt(KEY_SIZE3,dThick2); m_mapSpecXData.GetAt(KEY_SIZE4,dH2); int nW2Pos = 0; m_mapSpecXData.GetAt(KEY_W2POS,nW2Pos); SetWallData(dThick,dH,dThick2,dH2,nW2Pos,dBomEl,kMid); } } } else { es = m_pBaseCurve->moveStretchPointsAt(indices,offset); } } else { AcGePoint3dArray arPts; m_pBaseCurve->getStretchPoints(arPts); //由于增加的墙体高度,所以arPts + 2 //0,1.. nStartIndex (厚度) ,nStartIndex+1 (厚度) ,nStartIndex+2 (高度) int nStartIndex = arPts.length(); //如果含有墙体高度的index extern BOOL IsFrontView(); if (IsFrontView()) { if (indices.find(nStartIndex + 0) != -1 && indices.find(nStartIndex + 1) == -1)//含有底部标高位点,且立面拉伸 { return MoveHeightStretchPoint(0,offset); } if (indices.find(nStartIndex + 1) != -1 && indices.find(nStartIndex + 0) == -1)//含有顶部高度位点,且立面拉伸 { return MoveHeightStretchPoint(1,offset); } if (indices.find(nStartIndex + 0) != -1 && indices.find(nStartIndex + 1) != -1) { //移动 AcGeMatrix3d xMove; xMove.setToTranslation(offset); //立面移动 double dh = offset.length(); if (offset.isCodirectionalTo(AcGeVector3d::kZAxis)) { dh *= -1.0; } WallData data; GetWallData(data); data.dBomEl -= dh; int nW2Pos = 0; m_mapSpecXData.GetAt(KEY_W2POS,nW2Pos); SetWallData(data.dThick,data.dH,data.dThick2,data.dH2,nW2Pos,data.dBomEl,kMid); m_pBaseCurve->transformBy(xMove); } return Acad::eOk; } //其他位点 es = m_pBaseCurve->moveStretchPointsAt(indices,offset); } } return es; } Acad::ErrorStatus AecDbXWall::AdjustHoleAndPipe(double dThickOld,double dThickAdd,int nDir) { AcDbObjectId id; AcDbEntity* pEnt = NULL; Acad::ErrorStatus es; if (objectId().isValid()) { for (int i = 0;i < m_arAssocPartEntIds.length();i++) { id = m_arAssocPartEntIds.at(i); if ( Acad::eOk == (es = acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite))) { AecDbX3dPartEntity* pPart = AecDbX3dPartEntity::cast(pEnt); if (pPart != NULL) { pPart->AdjustHoleAndPipe(dThickOld,dThickAdd,nDir); } pEnt->close(); } } } return Acad::eOk; } SHJson::WValue& AecDbXWall::ToJson(bool bExprotGeo) const { assertReadEnabled(); return AecDbBDPipeBase::ToJson(bExprotGeo); } bool AecDbXWall::ByJson(const SHJson::WValue &v) { AssertWriteEnabled(); return AecDbBDPipeBase::ByJson(v); } bool AecDbXWall::GetBimInfoTip(CString& sInfoTip) const { assertReadEnabled(); WallData data; GetWallData(data); CString sField,sFmt; if (data.nSecShape == eRect)//矩形 { sField = _T("矩形截面墙:\n"); sInfoTip += sField; MAKEFIELD(_T("墙体厚度"),_T("%.1f 毫米"),data.dThick,sInfoTip) MAKEFIELD(_T("墙体高度"),_T("%.1f 毫米"),data.dH,sInfoTip) MAKEFIELD(_T("墙体长度"),_T("%.1f 毫米"),GetLength(),sInfoTip) MAKEFIELD(_T("墙体低标高"),_T("%.3f 毫米"),data.dBomEl,sInfoTip) MAKEFIELD(_T("墙体体积"),_T("%.3f 立方米"),GetVolume() / 1.e9,sInfoTip) MAKEFIELD(_T("墙体面积"),_T("%.3f 平方米"),GetArea() / 1.e6,sInfoTip) MAKEFIELD(_T("墙体材质"),_T("%s"),data.szMat,sInfoTip) MAKEFIELD(_T("墙体编号"),_T("%s"),data.szNO,sInfoTip) } else if(data.nSecShape == eWw)//不等宽墙 { sField = _T("不等厚截面墙:\n"); sInfoTip += sField; MAKEFIELD(_T("墙体底厚度"),_T("%.1f 毫米"),data.dThick2,sInfoTip) MAKEFIELD(_T("墙体底高度"),_T("%.1f 毫米"),data.dH2,sInfoTip) MAKEFIELD(_T("墙体顶厚度"),_T("%.1f 毫米"),data.dThick,sInfoTip) MAKEFIELD(_T("墙体总高度"),_T("%.1f 毫米"),data.dH,sInfoTip) MAKEFIELD(_T("墙体长度"),_T("%.1f 毫米"),GetLength(),sInfoTip) MAKEFIELD(_T("墙体低标高"),_T("%.3f 毫米"),data.dBomEl,sInfoTip) MAKEFIELD(_T("墙体体积"),_T("%.3f 立方米"),GetVolume() / 1.e9,sInfoTip) MAKEFIELD(_T("墙体面积"),_T("%.3f 平方米"),GetArea() / 1.e6,sInfoTip ) MAKEFIELD(_T("墙体材质"),_T("%s"),data.szMat,sInfoTip) MAKEFIELD(_T("墙体编号"),_T("%s"),data.szNO,sInfoTip) } else if (data.nSecShape == eUserDef)//自定义截面 { sField = _T("自定义截面墙:\n"); sInfoTip += sField; MAKEFIELD(_T("墙体总厚"),_T("%.1f 毫米"),data.dThick,sInfoTip) MAKEFIELD(_T("墙体总高"),_T("%.1f 毫米"),data.dH,sInfoTip) MAKEFIELD(_T("墙体长度"),_T("%.1f 毫米"),GetLength(),sInfoTip) MAKEFIELD(_T("墙体低标高"),_T("%.3f 毫米"),data.dBomEl,sInfoTip) MAKEFIELD(_T("墙体体积"),_T("%.3f 立方米"),GetVolume() / 1.e9,sInfoTip ) MAKEFIELD(_T("墙体面积"), _T("%.3f 平方米"),GetArea() / 1.e6,sInfoTip ) MAKEFIELD(_T("墙体材质"),_T("%s"),data.szMat,sInfoTip) MAKEFIELD(_T("墙体编号"),_T("%s"),data.szNO,sInfoTip) } else { //... } return true; } int AecDbXWall::GetSectionDraw(const AcGePoint3d &ptFr, const AcGePoint3d &ptTo, const AcGeVector3d &vtViewDir, const AcGeVector3d &vtTo, AcDbVoidPtrArray &arRegionPtrs) const { AcDbVoidPtrArray arGetPtrs; AecDbBDPipeBase::GetSectionDraw(ptFr, ptTo, vtViewDir, vtTo, arGetPtrs); AcDbEntity *pEnt = NULL; AcDbCurve *pCrv = NULL; AcGePoint3d ptS, ptE; WallData data; GetWallData(data); for (int n = 0;n < arGetPtrs.length();n++) { pEnt = (AcDbEntity*)arGetPtrs.at(n); pCrv = AcDbCurve::cast(pEnt); if (pCrv != NULL) { pCrv->getStartPoint(ptS); pCrv->getEndPoint(ptE); if (fabs(ptS.distanceTo(ptE) - data.dThick) < 1.e-2)//和墙体等宽 { m_mapSpecXData.Write(pCrv, _T("BIMDATA")); } } } arRegionPtrs.append(arGetPtrs); return 0; } void AecDbXWall::ProcessHlrResult(const AcArray &ar , const std::map> &preAr , AcArray &output) const { double dW(.0); BOOL bBold = HlrCutOption::getEnvCutLW(this, dW); HlrCutOption::ProcessHlrResult(this , bBold , dW , FALSE , ar , preAr , output); } void AecDbXWall::PreprocessForHlr(const AcGePoint3d & ptPlnO , const AcGeVector3d & vtPlnN , AcArray& ar) const { // 如果实体和剖面相交,标记 HlrCutOption::setIntersectWithSection(this, AcGePlane(ptPlnO, vtPlnN)); } bool AecDbXWall::GetProperties(SimpleProperty::PropertySetByIndex &porpertys) const { /* 墙体类型 尺寸 标高 材质 不等厚设置 对齐方式 */ // 调用基类属性(如果需要) AecDbBDPipeBase::GetProperties(porpertys); CoreTools::setLayerPorperty(porpertys); CoreTools::setSubSystemPorperty(porpertys); WallData data; ::memset(&data, 0, sizeof(WallData)); GetWallData(data); // 1. 墙体类型 (根据几何基线判断) CString sWallType = _T("单线墙"); AcDbCurve *pCurve = GetBaseCurve(); if (pCurve != NULL) { if (pCurve->isKindOf(AcDbArc::desc())) { sWallType = _T("弧墙"); } // 还可以判断 AcDbCircle 等,但界面上只有单线和弧墙/圆墙 DELETE_PTR(pCurve); } SimpleProperty::makeAndInsert(porpertys, _T("墙体类型"), sWallType, false); bool bUserDef = (data.nSecShape == eUserDef); // 2. 基础属性 if (!bUserDef) { SimpleProperty::makeAndInsert(porpertys, _T("异形墙体"), _T("否"), false); SimpleProperty::makeAndInsert(porpertys, _T("墙体厚度"), data.dThick, true); SimpleProperty::makeAndInsert(porpertys, _T("墙体总高度"), data.dH, true); } else SimpleProperty::makeAndInsert(porpertys, _T("异形墙体"), _T("是"), false); SimpleProperty::makeAndInsert(porpertys, _T("底部标高"), data.dBomEl, true); SimpleProperty::makeAndInsert(porpertys, _T("墙体材质"), data.szMat, true); // 补充:如果是中线对齐,界面上有一个"中线对齐左厚" (IDC_EDIT3) // 虽然你没明确提,但为了完整性,通常会加上 if (data.kAlign == kMid) { double dLW = 0.5 * data.dThick; // 从 SpecialtyData 中获取 KEY_L,参考 SetFromWall GetSpecialtyData()->GetAt(KEY_L, dLW); SimpleProperty::makeAndInsert(porpertys, _T("中线对齐左厚"), dLW, true); } // 3. 自定义截面 (对应 IDC_CHECK1) // 在 SetFromWall 中: data.nSecShape == eUserDef 时 m_bUserDefSec = TRUE CString s(bUserDef ? _T("是") : _T("否")); SimpleProperty::makeAndInsert(porpertys, _T("自定义截面"), s, false); // 4. 基线对齐方式 (对应 IDC_RADIO1, 2, 3) CString sAlignBase = _T("中线对齐"); switch (data.kAlign) { case kMid: sAlignBase = _T("中线对齐"); break; case kLeft: sAlignBase = _T("左线对齐"); break; case kRight: sAlignBase = _T("右线对齐"); break; default: break; } std::vector ss; ss.push_back(_T("中线对齐")); ss.push_back(_T("左线对齐")); ss.push_back(_T("右线对齐")); SimpleProperty::makeAndInsert(porpertys, _T("基线对齐方式"), sAlignBase, true, ss); // 5. 墙体不等厚 (对应 IDC_CHECK2) // 在 SetFromWall 中: data.nSecShape == eWw 时 m_bHasW2 = TRUE bool bUnequal = (data.nSecShape == eWw); s = bUnequal ? _T("是") : _T("否"); ss.clear(); ss.push_back(_T("是")); ss.push_back(_T("否")); SimpleProperty::makeAndInsert(porpertys, _T("墙体不等厚"), s, false, ss); if (!bUserDef) { // 只有不等厚为"是"时,才显示下面的详细参数 if (bUnequal) { SimpleProperty::makeAndInsert(porpertys, _T("墙体底部厚度"), data.dThick2, true); SimpleProperty::makeAndInsert(porpertys, _T("墙体底部高度"), data.dH2, true); // 不等厚墙体对齐方式 (对应 IDC_RADIO7, 8, 9) // nW2Pos 通常对应 Radio 的索引: 0=左, 1=中, 2=右 CString sAlignW2 = _T("左侧外伸"); switch (data.nW2Pos) { case 0: sAlignW2 = _T("左侧外伸"); break; case 1: sAlignW2 = _T("居中对称"); break; case 2: sAlignW2 = _T("右侧外伸"); break; default: break; } ss.clear(); ss.push_back(_T("左侧外伸")); ss.push_back(_T("居中对称")); ss.push_back(_T("右侧外伸")); SimpleProperty::makeAndInsert(porpertys, _T("不等厚墙体对齐方式"), sAlignW2, true, ss); } } return true; } bool AecDbXWall::SetProperties(SimpleProperty::PropertySetByName &properties) { using namespace SimpleProperty; if (properties.m_set.empty()) return false; AecDbBDPipeBase::SetProperties(properties); WallData data; ::memset(&data, 0, sizeof(WallData)); GetWallData(data); AecDbObjXDataMap *pData = &m_mapSpecXData; // 是否自定义截面不会被修改 bool bUserDef = (data.nSecShape == eUserDef); // 是否不等厚墙体也不会被修改 bool bUnequal = (data.nSecShape == eWw); // 先取出修改之前的作为默认值 int ali = data.kAlign; CString s; if (properties.findAndSet(_T("基线对齐方式"), s)) { // 如果修改过,则被覆盖 if (s == _T("中线对齐")) ali = kMid; else if (s == _T("左线对齐")) ali = kLeft; else ali = kRight; pData->SetAt(KEY_ALIGN, ali); } properties.findAndSet(_T("墙体厚度"), pData, KEY_SIZE1); properties.findAndSet(_T("墙体总高度"), pData, KEY_SIZE2); properties.findAndSet(_T("底部标高"), pData, PIPE_EL); properties.findAndSet(_T("墙体材质"), pData, KEY_MATERIAL); properties.findAndSet(_T("中线对齐左厚"), pData, KEY_L); properties.findAndSet(_T("墙体底部厚度"), pData, KEY_SIZE3); properties.findAndSet(_T("墙体底部高度"), pData, KEY_SIZE4); int nW2Pos = data.nW2Pos; if (properties.findAndSet(_T("不等厚墙体对齐方式"), s)) { if (s == _T("左侧外伸")) nW2Pos = 0; else if (s == _T("居中对称")) nW2Pos = 1; else nW2Pos = 2; pData->SetAt(KEY_W2POS, nW2Pos); } // 先取出修改之前的作为默认值 double dEl(data.dBomEl); double dW(data.dThick), dH(data.dH), dW2(data.dThick2), dH2(data.dH2); // 现在取出最新的(如果被修改过) pData->GetAt(PIPE_EL, dEl); pData->GetAt(KEY_SIZE1, dW); pData->GetAt(KEY_SIZE2, dH); pData->GetAt(KEY_SIZE3, dW2); pData->GetAt(KEY_SIZE4, dH2); if (bUserDef) { // 自定义截面,对齐永远是kMid pData->SetAt(KEY_ALIGN, kMid); SetWallData(dEl, kMid); // 其他不变 } else if (bUnequal) { SetWallData(dW, dH, dW2, dH2, nW2Pos, dEl, (EAlign)ali); AdjustHoleAndPipe(dW - data.dThick); } else { SetWallData(dW, dH, dEl, (EAlign)ali); AdjustHoleAndPipe(dW - data.dThick); // 目前参考HZQTDlg.cpp来看,只有普通墙才会修改门窗 AcDbObjectIdArray arAssocIds; GetAssocPartIds(arAssocIds); Acad::ErrorStatus es; AcDbEntity *pEnt = NULL; AcDbObjectId id; for (int i = 0; i < arAssocIds.length(); i++) { id = arAssocIds.at(i); if (Acad::eOk == (es = acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite))) { AecDbXOpening *pOpen = AecDbXOpening::cast(pEnt); if (pOpen != NULL) { OpeningData data; memset(&data, 0, sizeof(OpeningData)); pOpen->GetOpeningData(data); data.dThick = dW; pOpen->UpdateOpeningData(data); } pEnt->close(); } } } AcGeMatrix3d xformEl; AcGeVector3d vtMove(0, 0, dEl - data.dBomEl); xformEl.setToTranslation(vtMove); TransformDTYGPartEnt(xformEl); TransformAssocPartEnt(xformEl); return true; }