//------------------------------------------------------------------------+ // Copyright (C), 1998-2011, Beijing Tangent Software Co. Ltd. // = FileName : TDbBaseWall类 // = Version : ver1.0 // = Author : CET // = CreateDate : 2011-04-25 // = Description: 抽象墙基线类实现 // = Maintainers: // //------------------------------------------------------------------------+ #include "stdafx.h" #ifdef TASD #include "TDbBaseWall.h" #include "TAsdKeyDefine.h" #include "TBaseWallIntegrateTool.h" #include "TAsdGlobleDef.h" #include "TDbStruFloorSlab.h" #include "TDbStruBeam.h" #define BASEWALL_AS_OBJ 0 //1作为对象,0抽象基类 extern bool g_bModifyAgain; extern BOOL g_bSplitFloor; extern void AddMsg(const TAssocMsg& assocMsg); #if (BASEWALL_AS_OBJ == 1) ACRX_DXF_DEFINE_MEMBERS(ATSBaseWall, ATSStruEntityBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_BASEWALL, "ATS_BASEWALL图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); #else ACRX_NO_CONS_DEFINE_MEMBERS(TDbBaseWall, TDbStruEntityBase); #endif IMPLEMENT_TENTBASE(TDbBaseWall); const Adesk::UInt8 TDbBaseWall::g_nVersion = 1; TDbBaseWall::TDbBaseWall() { } TDbBaseWall::~TDbBaseWall() { } Acad::ErrorStatus TDbBaseWall::dwgInFields( AcDbDwgFiler* pFiler ) { assertWriteEnabled(); Acad::ErrorStatus es = TDbCurveEntity::dwgInFields(pFiler); if(es != Acad::eOk) { return es; } // 版本号 Adesk::UInt8 nVer; pFiler->readItem(&nVer); // xy平面关联对象ID数组 Adesk::UInt8 nCount = 0; pFiler->readItem(&nCount); AcDbSoftPointerId id; m_arAssocBWallIds.setLogicalLength(0); for(Adesk::UInt8 i = 0; i < nCount; i++) { pFiler->readItem(&id); m_arAssocBWallIds.append(id); } // z平面关联对象ID数组 nCount = 0; pFiler->readItem(&nCount); m_arAssocZIds.setLogicalLength(0); for(i = 0; i < nCount; i++) { pFiler->readItem(&id); m_arAssocZIds.append(id); } // 关联洞对象ID数组 nCount = 0; pFiler->readItem(&nCount); m_arHoleIds.setLogicalLength(0); for(i = 0; i < nCount; i++) { pFiler->readItem(&id); m_arHoleIds.append(id); } // 关联板对象ID数组 nCount = 0; pFiler->readItem(&nCount); m_arSlabIds.setLogicalLength(0); for(i = 0; i < nCount; i++) { pFiler->readItem(&id); m_arSlabIds.append(id); } // 关联柱子对象ID数组 nCount = 0; pFiler->readItem(&nCount); m_arColumnIds.setLogicalLength(0); for(i = 0; i < nCount; i++) { pFiler->readItem(&id); m_arColumnIds.append(id); } return pFiler->filerStatus(); } Acad::ErrorStatus TDbBaseWall::dwgOutFields( AcDbDwgFiler* pFiler ) const { assertReadEnabled(); Acad::ErrorStatus es = TDbCurveEntity::dwgOutFields(pFiler); if(es != Acad::eOk) { return es; } pFiler->writeItem(g_nVersion); // xy平面关联对象ID数组 Adesk::UInt8 nCount=(Adesk::UInt8)m_arAssocBWallIds.length(); pFiler->writeItem(nCount); for (Adesk::UInt8 i = 0; i < nCount; i++) { pFiler->writeItem(AcDbSoftPointerId(m_arAssocBWallIds[i])); } // z平面关联对象ID数组 nCount=(Adesk::UInt8)m_arAssocZIds.length(); pFiler->writeItem(nCount); for (i = 0; i < nCount; i++) { pFiler->writeItem(AcDbSoftPointerId(m_arAssocZIds[i])); } // 关联洞对象ID数组 nCount=(Adesk::UInt8)m_arHoleIds.length(); pFiler->writeItem(nCount); for ( i = 0; i < nCount; i++) { pFiler->writeItem(AcDbSoftPointerId(m_arHoleIds[i])); } // 关联板对象ID数组 nCount=(Adesk::UInt8)m_arSlabIds.length(); pFiler->writeItem(nCount); for (i = 0; i < nCount; i++) { pFiler->writeItem(AcDbSoftPointerId(m_arSlabIds[i])); } // 关联柱子对象ID数组 nCount=(Adesk::UInt8)m_arColumnIds.length(); pFiler->writeItem(nCount); for (i = 0; i < nCount; i++) { pFiler->writeItem(AcDbSoftPointerId(m_arColumnIds[i])); } return pFiler->filerStatus(); } Acad::ErrorStatus TDbBaseWall::dxfInFields( AcDbDxfFiler* pFiler ) { return TDbCurveEntity::dxfInFields(pFiler); } Acad::ErrorStatus TDbBaseWall::dxfOutFields( AcDbDxfFiler* pFiler ) const { return TDbCurveEntity::dxfOutFields(pFiler); } Acad::ErrorStatus TDbBaseWall::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds ) const { assertReadEnabled(); return TDbCurveEntity::subGetOsnapPoints(osnapMode,gsSelectionMark, pickPoint,lastPoint,viewXform,snapPoints,geomIds); } Acad::ErrorStatus TDbBaseWall::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds, const AcGeMatrix3d& insertionMat ) const { assertReadEnabled(); #if (BASEWALL_AS_OBJ == 1) if(osnapMode == AcDb::kOsModeIns || osnapMode == AcDb::kOsModeMid || osnapMode == AcDb::kOsModeNear || osnapMode == AcDb::kOsModeEnd ) { AcGePoint3d ptS, ptE; GetAt(KEY_START, ptS); GetAt(KEY_END, ptE); snapPoints.append(ptS); snapPoints.append(ptE); } #endif return TDbCurveEntity::subGetOsnapPoints(osnapMode,gsSelectionMark, pickPoint,lastPoint,viewXform,snapPoints,geomIds,insertionMat); } Acad::ErrorStatus TDbBaseWall::subTransformBy( const AcGeMatrix3d& xform ) { assertWriteEnabled(); TDbCurveEntity::subTransformBy(xform); AcGePoint3d ptS, ptE; GetAt(KEY_START, ptS); GetAt(KEY_END, ptE); double dBulge = 0.0; GetAt(KEY_BULGE, dBulge); if (IsMirrorMatrix(xform) && fabs(dBulge) > g_angleZero) // 镜像 { TGGeArc arc(ptS, ptE, dBulge); TADSGePoint3d ptMid = arc.MidPoint(); ptS.transformBy(xform); ptE.transformBy(xform); ptMid.TransformBy(xform); TGGeArc arcNew(ptS, ptMid, ptE); TADSGePoint3d pt1, pt2; arcNew.GetStartPoint(pt1); arcNew.GetEndPoint(pt2); ptS = pt1; ptE = pt2; dBulge = arcNew.Bulge(); SetAt(KEY_START, ptS); SetAt(KEY_END, ptE); SetAt(KEY_BULGE, dBulge); } else { ptS.transformBy(xform); ptE.transformBy(xform); SetAt(KEY_START, ptS); SetAt(KEY_END, ptE); } return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::subGetGripPoints( AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds ) const { assertReadEnabled(); #if (BASEWALL_AS_OBJ == 1) AcGePoint3d ptS, ptE; GetAt(KEY_START, ptS); GetAt(KEY_END, ptE); gripPoints.append(ptS); gripPoints.append(ptE); double dBulge = 0.0; GetAt(KEY_BULGE, dBulge); TADSGePoint3d ptStart = ptS, ptEnd = ptE, ptMid; if (fabs(dBulge) < g_fZero) // 直线 { Midpoint(ptStart, ptE, ptMid); } else // 弧线 { TGGeArc arc(ptStart, ptEnd, dBulge); ptMid = arc.MidPoint(); } gripPoints.append(ptMid); #endif return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::subGetStretchPoints( AcGePoint3dArray& stretchPoints ) const { return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset ) { #if (BASEWALL_AS_OBJ == 1) AcGePoint3d ptS; GetAt(KEY_START, ptS); AcGePoint3d ptE; GetAt(KEY_END, ptE); int nIndex = indices[0]; if (nIndex == 0) // 起点 { ptS += offset; SetAt(KEY_START, ptS); } else if (nIndex == 1) // 终点 { ptE += offset; SetAt(KEY_END, ptE); } else if (nIndex == 2) // 中点 { double dBulge = 0.0; GetAt(KEY_BULGE, dBulge); if (fabs(dBulge) < g_angleZero) // 直线 { ptS += offset; SetAt(KEY_START, ptS); ptE += offset; SetAt(KEY_END, ptE); } else // 弧线 { TADSGePoint3d ptStart = ptS, ptEnd = ptE, ptMid; TGGeArc arc(ptStart, ptEnd, dBulge); ptMid = arc.MidPoint(); ptMid += offset; TGGeArc arcNew(ptStart, ptMid, ptEnd); // 移动后的新弧 arcNew.GetStartPoint(ptStart); arcNew.GetEndPoint(ptEnd); dBulge = arcNew.Bulge(); ptS = ptStart; ptE = ptEnd; SetAt(KEY_START, ptS); SetAt(KEY_END, ptE); SetAt(KEY_BULGE, dBulge); } } #endif return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::subMoveStretchPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset ) { return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::subGetClassID( CLSID* pClsid ) const { return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::subDeepClone( AcDbObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary ) const { assertReadEnabled(); return TDbStruEntityBase::subDeepClone(pOwner, pClonedObject, idMap, isPrimary); } Acad::ErrorStatus TDbBaseWall::subWblockClone( AcRxObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary ) const { assertReadEnabled(); return TDbStruEntityBase::subWblockClone(pOwner, pClonedObject, idMap, isPrimary); } Acad::ErrorStatus TDbBaseWall::subIntersectWith( const AcDbEntity* ent, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/ ) const { AcDbCurve *pCurve = GetBaseCurve(); if (pCurve == NULL) { return Acad::eInvalidInput; } Acad::ErrorStatus st = pCurve->intersectWith(ent, intType, points, thisGsMarker, otherGsMarker); delete pCurve; return st; } Acad::ErrorStatus TDbBaseWall::subIntersectWith( const AcDbEntity* ent, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/ ) const { AcDbCurve *pCurve = GetBaseCurve(); if (pCurve == NULL) { return Acad::eInvalidInput; } Acad::ErrorStatus st = pCurve->intersectWith(ent, intType, projPlane, points, thisGsMarker, otherGsMarker); delete pCurve; return st; } AcDbCurve* TDbBaseWall::GetBaseCurve() const { assertReadEnabled(); AcGePoint3d ptS, ptE; GetAt(KEY_START, ptS); GetAt(KEY_END, ptE); double dBulge = 0.0; GetAt(KEY_BULGE, dBulge); /* dBulge = atan(dBulge) * 4;*/ //AcDbPolyline *pPoly = new AcDbPolyline; //pPoly->addVertexAt(0, ptS.convert2d(AcGePlane::kXYPlane), tan(dBulge / 4)); //pPoly->addVertexAt(1,ptE.convert2d(AcGePlane::kXYPlane)); TGGeCurveSegment cvSeg(ptS,ptE,dBulge); return cvSeg.AsAcDbCurve(); } //用于trim/extent时修改对象 Acad::ErrorStatus TDbBaseWall::SetBaseCurve(AcDbCurve* pCurve) { if (pCurve == NULL) { return Acad::eInvalidInput; } assertWriteEnabled(); AcGePoint3d ptS, ptE; GetAt(KEY_START, ptS); GetAt(KEY_END, ptE); AcDbLine *pLine = AcDbLine::cast(pCurve); AcDbArc *pArc = AcDbArc::cast(pCurve); if (pLine) { SetAt(KEY_START, AcGePoint3d(pLine->startPoint().x, pLine->startPoint().y, ptS.z)); SetAt(KEY_END, AcGePoint3d(pLine->endPoint().x, pLine->endPoint().y, ptE.z)); SetAt(KEY_BULGE, 0.0); } else if (pArc) { TGGeArc ar(TADSGePoint3d(pArc->center()), pArc->radius(), pArc->startAngle(), pArc->endAngle()); TGGeCurveSegment cvCenter; cvCenter = ar; SetAt(KEY_START, AcGePoint3d(cvCenter.StartPoint().x, cvCenter.StartPoint().y, ptS.z)); SetAt(KEY_END, AcGePoint3d(cvCenter.EndPoint().x, cvCenter.EndPoint().y, ptE.z)); SetAt(KEY_BULGE, cvCenter.GetBulge()); } else { return Acad::eInvalidInput; } return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::GetClipBoundary( TGGePoly2D& poly ) const { return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::GetGripText( int i, CString &cs ) const { Acad::ErrorStatus es=Acad::eOk; switch(i) { case 0: cs=_T("改变起点"); break; case 1: cs=_T("改变终点"); break; case 2: { double dBulge = 0.0; GetAt(KEY_BULGE, dBulge); if (fabs(dBulge) < g_angleZero) // 直线 { cs = _T("平移"); } else // 弧线 { cs = _T("改变中点"); } break; } default: es=Acad::eInvalidInput; break; } return es; } Acad::ErrorStatus TDbBaseWall::ExplodeOrDraw3d( TGGiExplodeDrawBase &dc ) const { return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::ExplodeOrDraw2d( TGGiExplodeDrawBase &dc ) const { assertReadEnabled(); #if (BASEWALL_AS_OBJ == 1) TBaseWallLine bwlThis; GetThisBaseWallLine(bwlThis); // 通过融合剪切墙体 TDPtrList arBaseWallLinesS, arBaseWallLinesM, arBaseWallLinesE; GetAssocBaseWallLine(arBaseWallLinesS, arBaseWallLinesM, arBaseWallLinesE); // 起点融合 TBaseWallIntegrateTool::IntegrateAtTail(true, bwlThis, arBaseWallLinesS); // 终点融合 TBaseWallIntegrateTool::IntegrateAtTail(false, bwlThis, arBaseWallLinesE); // 墙内融合 for (int i = 0; i < arBaseWallLinesM.Length(); i++) { TBaseWallIntegrateTool::Integrate(bwlThis,*arBaseWallLinesM[i]); } TGGeVisibilityPoly2D left, right; left = bwlThis.GetLeftLine(); right = bwlThis.GetRightLine(); DrawBaseWall2d(dc, left, true); DrawBaseWall2d(dc, right, false); #endif return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::GetExtents2d( TADSGePoint3d &ptLow, TADSGePoint3d &ptUp ) const { return Acad::eOk; } Acad::ErrorStatus TDbBaseWall::GetExtents( TADSGePoint3d &ptLow, TADSGePoint3d &ptUp ) const { return Acad::eOk; } bool TDbBaseWall::UnifyElevation( double dElevation ) { SetBottomElev(dElevation); return true; } void TDbBaseWall::GetTips( TDPtrList & lstInfo ) const { #if (BASEWALL_AS_OBJ == 1) int nWeight = 0; GetAt(KEY_WEIGHT, nWeight); lstInfo.Append(new TObjInfoUnit(_T("优先级"), TCString(_T("%d"), nWeight))); lstInfo.Append(new TObjInfoUnit(_T("关联个数"), TCString(_T("%d"), m_arAssocBWallIds.length()))); #endif } const TCHAR * TDbBaseWall::GetDefaultLayer() const { return NULL; } BOOL TDbBaseWall::IsValid() const { return TRUE; } void TDbBaseWall::CopyPropertiesFrom( AcDbEntity *pSrcEntity, unsigned gMatchFlag ) { assertWriteEnabled(); TDbStruEntityBase::CopyPropertiesFrom(pSrcEntity, gMatchFlag); TDbBaseWall *pBaseWall = TDbBaseWall::cast(pSrcEntity); if(pBaseWall != NULL) { /*double dWidth = 0.0, dHeight = 0.0; GetAt(KEY_W, dWidth); GetAt(KEY_H, dHeight); int nWeight = 0; GetAt(KEY_WEIGHT, nWeight); GetSpecialtyData()->Empty(); *GetSpecialtyData() = *pBaseWall->GetSpecialtyData(); SetAt(KEY_W, dWidth); SetAt(KEY_H, dHeight); SetAt(KEY_WEIGHT, nWeight);*/ } } TEntityBase::DrawType TDbBaseWall::GetDrawType() const { assertReadEnabled(); return TEntityBase::k2Dand3D; } bool TDbBaseWall::GetStandardFaceBody( AcDbVoidPtrArray& arFacePtrs ) const { return false; } bool TDbBaseWall::GetSafeProtectedSpace( AcDbVoidPtrArray& arFacePtrs ) const { return false; } bool TDbBaseWall::GetSection( const AcDbFace &face, const AcGeVector3d& vtPlaneSecDir, std::vector §ionRecords, AcDbVoidPtrArray& arFillPtrs ) const { return false; } CString TDbBaseWall::GetXml(const AcGeMatrix3d& mat) const { return _T(""); } void TDbBaseWall::PostAssocMsg( TAssocMsg assocMsg ) const { } void TDbBaseWall::ReceiveAssocMsg( TAssocMsg assocMsg ) { #if (BASEWALL_AS_OBJ == 1) AcDbObjectId id = assocMsg.GetAssocId(); if (!m_arAssocBWallIds.contains(id)) { m_arAssocBWallIds.append(id); } return; #endif assertWriteEnabled(); //不是夹点消息直接返回 if (assocMsg.GetMethod() != TAssocMsg::kMovegrippoint) { return; } TGGeCurveSegment cvCL = GetCenterLine(); double dElevS = cvCL.GetStartPoint().z; double dElevE = cvCL.GetEndPoint().z; cvCL.SetElevation(0); AcGeVector3d vtDir = (cvCL.GetEndPoint() - cvCL.GetStartPoint()).AsAcGeVector3d(); AcGeVector3d vtOffset = assocMsg.GetOffset(); AcGePoint3d ptTarget = assocMsg.GetTarget(); double dRet = vtOffset.dotProduct(vtDir); if (fabs(vtOffset.dotProduct(vtDir)) < _DIST_SNAP) //垂直 { AcGePoint3d ptStart = cvCL.GetStartPoint().AsAcGePoint3d(); AcGePoint3d ptEnd = cvCL.GetEndPoint().AsAcGePoint3d(); ptStart += vtOffset; ptStart.z = dElevS; SetAt(KEY_START, ptStart); ptEnd += vtOffset; ptEnd.z = dElevE; SetAt(KEY_END, ptEnd); TAssocMsg msg; msg.SetAssocId(objectId()); msg.SetMethod(TAssocMsg::kMovegrippoint); msg.SetTarget(cvCL.MidPoint().AsAcGePoint3d()); msg.SetOffset(vtOffset); AddMsg(msg); } else //不垂直时只需修改自身起始点,不发送消息 { TADSGePoint3d pt = ptTarget; pt.z = 0; if (vtOffset.isParallelTo(vtDir)) //平行 { cvCL.ProjectToMe(pt, pt); } else //斜交 { AcGeVector3d vtOrth = vtOffset.perpVector(); vtOrth = vtOffset; vtOrth.rotateBy(PI*0.5, AcGeVector3d::kZAxis); TADSGePoint3d ptEnd = ptTarget + vtOrth; TGGeCurveSegment cv(ptTarget, ptEnd, 0, LS_INFINITE); cv.SetElevation(0); cvCL.SetLineFlag(LS_INFINITE); cv.Intersection(cvCL, pt, TADSGePoint3d()); //求投影向量 double dAng = vtOffset.angleTo(vtDir); double dLen = vtOffset.length(); dLen /= fabs(cos(dAng)); //偏移向量在线上的投影长度 vtOffset = vtDir.normal(); vtOffset.z = 0; vtOffset *= dLen; if (dAng > PI*0.5) { vtOffset.negate(); } } int nPos = (pt & cvCL); //交点与线的位置关系 if (nPos == PR_ONPT1) //起点 { AcGePoint3d ptMod = cvCL.GetStartPoint().AsAcGePoint3d(); ptMod += vtOffset; ptMod.z = dElevS; SetAt(KEY_START, ptMod); } else if (nPos == PR_ONPT2) //终点 { AcGePoint3d ptMod = cvCL.GetEndPoint().AsAcGePoint3d(); ptMod += vtOffset; ptMod.z = dElevE; SetAt(KEY_END, ptMod); } else if (nPos == PR_INSIDE) //线内 { AcGePoint3d ptMod = pt.AsAcGePoint3d(); ptMod += vtOffset; nPos = (TADSGePoint3d(ptMod) & cvCL); if (nPos == PR_EXTEND) //新位置交点在线外时需要延长 { if (vtOffset.angleTo(vtDir) < _DIST_SNAP)//同向 { ptMod.z = dElevE; SetAt(KEY_END, ptMod); } else { ptMod.z = dElevS; SetAt(KEY_START, ptMod); } } } } } void TDbBaseWall::MakeAssocRelation( AcDbObjectIdArray& ids ) { #if (BASEWALL_AS_OBJ == 1) for (int i = 0; i < ids.length(); i++) { if (!m_arAssocBWallIds.contains(ids[i])) { m_arAssocBWallIds.append(ids[i]); } } #endif } // 不验证关系,直接建立关联关系 void TDbBaseWall::MakeAssocRelationDirect(const AcDbObjectId& idObj) { assertWriteEnabled(); TPickEntSet ss(SS_FREE); ss += idObj; TEntitySet ent; for (long i = 0; i < ss.Length(); i++) { ent = ss[i]; if (ent.Is(_T("ATS_STRUBEAM")) ||ent.Is(_T("ATS_WALL"))) // 梁 { if (!m_arAssocBWallIds.contains(idObj)) { m_arAssocBWallIds.append(idObj); } } else if (ent.Is(_T("ATS_COLUMN"))) // 柱子 { if (!m_arColumnIds.contains(idObj)) { m_arColumnIds.append(idObj); } } else if (ent.Is(_T("ATS_STRU_FLOORSLAB"))) // 板 { if (!m_arSlabIds.contains(idObj)) { m_arSlabIds.append(idObj); } } else if (ent.Is(_T("TCH_STRU_HOLE"))) // 墙洞 { if (!m_arHoleIds.contains(idObj)) { m_arHoleIds.append(idObj); } } } } void TDbBaseWall::RemoveAssocRelation( AcDbObjectId& id ) { m_arAssocBWallIds.remove(id); } void TDbBaseWall::GetAssocRelation( int nType, AcDbObjectIdArray& ar ) const { assertReadEnabled(); switch(nType) { case ASSOC_XY: // XY平面关联 { ar = m_arAssocBWallIds; break; } case ASSOC_Z: // Z平面关联 { //ar = m_arAssocZIds; break; } case ASSOC_HOLE: // 关联洞 { ar = m_arHoleIds; break; } case ASSOC_SLAB:// 关联楼板 { ar = m_arSlabIds; break; } case ASSOC_COLU: // 关联柱 { ar = m_arColumnIds; break; } case ASSOC_ALL: //所有关联 { ar.setLogicalLength(0); if (m_arAssocBWallIds.length() > 0) { ar.append(m_arAssocBWallIds); } if (m_arColumnIds.length() > 0) { ar.append(m_arColumnIds); } if (m_arSlabIds.length() > 0) { ar.append(m_arSlabIds); } if (m_arHoleIds.length() > 0) { ar.append(m_arHoleIds); } //if (m_arAssocZIds.length() > 0) //{ // ar.append(m_arAssocZIds); //} break; } } } void TDbBaseWall::GetThisBaseWallLine( TBaseWallLine& baseWall ) const { assertReadEnabled(); AcGePoint3d ptS, ptE; GetAt(KEY_START, ptS); GetAt(KEY_END, ptE); ptS.z = 0.0; ptE.z = 0.0; double dBulge = 0.0, dWidth = 0.0; GetAt(KEY_BULGE, dBulge); GetTotalWidth(dWidth); TGGeVisibilityPoly2D left; // 左线 TGGeVisibilityPoly2D right; // 右线 if (fabs(dBulge) < g_angleZero) // 直线 { // 偏移向量 AcGeVector3d vt = ptE - ptS; vt.normalize(); vt.rotateBy(PI/2, AcGeVector3d::kZAxis); // 墙线1 ptS += vt * dWidth * 0.5; ptE += vt * dWidth * 0.5; left.AppendNode(ptS); left.AppendNode(ptE); // 墙线2 ptS -= vt * dWidth; ptE -= vt * dWidth; right.AppendNode(ptS); right.AppendNode(ptE); } else // 弧线 { TADSGePoint3d ptStart = ptS, ptEnd = ptE; // 创建新弧取圆心 TGGeArc arc(ptStart, ptEnd, dBulge); AcGePoint3d ptCenter = arc.GetCenterPt(); // 创建偏移向量 AcGeVector3d vt1 = ptStart - ptCenter, vt2 = ptEnd - ptCenter; vt1.normalize(); vt2.normalize(); vt1 *= dWidth * 0.5; vt2 *= dWidth * 0.5; // 创建弧墙 ptS = ptStart + vt1; ptE = ptEnd + vt2; right.AppendNode(ptS,dBulge); right.AppendNode(ptE); ptS = ptStart - vt1; ptE = ptEnd - vt2; left.AppendNode(ptS,dBulge); left.AppendNode(ptE); } int nWeight = 0; GetAt(KEY_WEIGHT, nWeight); baseWall.SetLeftLine(left); baseWall.SetRightLine(right); baseWall.SetWeight(nWeight); } void TDbBaseWall::GetAssocBaseWallLine( TDPtrList& arBaseWallLinesS, TDPtrList& arBaseWallLinesM, TDPtrList& arBaseWallLinesE ) const { TBaseWallLine bwlThis; GetThisBaseWallLine(bwlThis); TDbBaseWall *pBaseWall = NULL; TBaseWallLine bwlThat; for (int i = 0; i < m_arAssocBWallIds.length(); i++) { acdbOpenObject(pBaseWall, m_arAssocBWallIds[i], AcDb::kForRead); if (pBaseWall != NULL) { pBaseWall->GetThisBaseWallLine(bwlThat); pBaseWall->close(); // 判断墙线融合方式 TBaseWallLine *pBWLine = new TBaseWallLine; pBWLine->SetLeftLine(bwlThat.GetLeftLine()); pBWLine->SetRightLine(bwlThat.GetRightLine()); pBWLine->SetWeight(bwlThat.GetWeight()); int nType = TBaseWallIntegrateTool::IsIntegrateAtTail(bwlThis, bwlThat); if (nType == 1) // 起始端融合 { arBaseWallLinesS.Append(pBWLine); } else if (nType == 2) // 终止端融合 { arBaseWallLinesE.Append(pBWLine); } else if (nType == 3) // 两端融合 { arBaseWallLinesS.Append(pBWLine); TBaseWallLine *pbWLineNew = new TBaseWallLine; pbWLineNew->SetLeftLine(bwlThat.GetLeftLine()); pbWLineNew->SetRightLine(bwlThat.GetRightLine()); pbWLineNew->SetWeight(bwlThat.GetWeight()); arBaseWallLinesE.Append(pbWLineNew); } else // 墙体内融合(非墙体起点终点) { arBaseWallLinesM.Append(pBWLine); } } } } void TDbBaseWall::GetAssocHoleline( TDPtrList &plHoles ) const { plHoles.Reset(); //TGGePoly2D poly; //TGGeCurveSegment seg; //TDbStruWallHole *pHole = NULL; //for (int i = 0; i < m_arHoleIds.length(); i++) //{ // acdbOpenObject(pHole, m_arHoleIds[i], AcDb::kForRead); // if (pHole != NULL) // { // poly.Reset(); // pHole->GetOutlinePoly2D(pHole->GetBottomElev(), poly, seg); // pHole->close(); // plHoles.Append(new TGGePoly2D(poly)); // } //} } AcDbFace* TDbBaseWall::GetXYAssocFace( bool bTopOrBottom ) const { return NULL; } void TDbBaseWall::recordGraphicModified()const { } double TDbBaseWall::GetBottomElev() const { assertReadEnabled(); AcGePoint3d ptE; GetAt(KEY_END, ptE); return ptE.z; } void TDbBaseWall::SetBottomElev( double dElev ) { assertWriteEnabled(); AcGePoint3d ptS, ptE; GetAt(KEY_START, ptS); GetAt(KEY_END, ptE); ptS.z = dElev; ptE.z = dElev; SetAt(KEY_START, ptS); SetAt(KEY_END, ptE); } void TDbBaseWall::GetSideCurve(TGGeCurveSegment &lCurve, TGGeCurveSegment &rCurve) const { assertReadEnabled(); TGGeCurveSegment cvCenter = GetCenterLine(); double dWidth = 0; GetTotalWidth(dWidth); lCurve = cvCenter.Offset(OFFSET_LEFT, dWidth*0.5, LS_FINITE); rCurve = cvCenter.Offset(OFFSET_RIGHT, dWidth*0.5, LS_FINITE); } Acad::ErrorStatus TDbBaseWall::DrawBaseWall2d(TGGiExplodeDrawBase &dc, TGGeVisibilityPoly2D poly, bool bLeft) const { // 根据可见性显示各段线段 TGGeLine line; TGGeArc arc; AcDb::Visibility eVal; TADSGePoint3d ptS, ptE; for(int i = 0; i < poly.Length(); i++) { int nrc = poly.Nth(i, line, arc, &eVal); if (nrc == LINE_SEGMENT && eVal == AcDb::kVisible) { dc << line; } else if (nrc == ARC_SEGMENT && eVal == AcDb::kVisible) { dc << arc; } } return Acad::eOk; } void TDbBaseWall::GetWallId(bool bStart, AcDbObjectId &idWall) const { TBaseWallLine bwlThis; GetThisBaseWallLine(bwlThis); TDbBaseWall *pBaseWall = NULL; TBaseWallLine bwlThat; for (int i = 0; i < m_arAssocBWallIds.length(); i++) { acdbOpenObject(pBaseWall, m_arAssocBWallIds[i], AcDb::kForRead); if (pBaseWall != NULL) { pBaseWall->GetThisBaseWallLine(bwlThat); pBaseWall->close(); // 判断墙线融合方式 TBaseWallLine *pBWLine = new TBaseWallLine; pBWLine->SetLeftLine(bwlThat.GetLeftLine()); pBWLine->SetRightLine(bwlThat.GetRightLine()); pBWLine->SetWeight(bwlThat.GetWeight()); int nType = TBaseWallIntegrateTool::IsIntegrateAtTail(bwlThis, bwlThat); if ((nType == 1 || nType == 3) && bStart) // 起始端融合 或 两端融合 { idWall = m_arAssocBWallIds[i]; break; } else if ((nType == 2 || nType == 3) && !bStart) // 终止端融合 或 两端融合 { idWall = m_arAssocBWallIds[i]; break; } } } } void TDbBaseWall::GetSegmentForSlab2d(const TGGePoly2D &polySlab, const TGGeCurveSegment &seg, std::vector &vecSeg1, std::vector &vecSeg2) const { TGGePoly2D poly(polySlab); poly.SetElevation(0.0); AcDbPolyline *pLine = static_cast(poly.AsAcDbCurve()); if (pLine == NULL) { return; } bool bLine = true; AcDbLine lineTemp; AcDbArc arcTemp; if (seg.Is(CURVE_ARC)) { TGGeArc arc; arc = seg.GetArc(); bLine = false; TADSGePoint3d ptCenter = arc.GetCenterPt(); arcTemp.setCenter(ptCenter.AsAcGePoint3d()); arcTemp.setStartAngle(arc.GetStarAngle()); arcTemp.setEndAngle(arc.GetEndAngle()); arcTemp.setRadius(arc.GetRadius()); } else if (seg.Is(CURVE_LINE)) { TGGeLine line; line = seg.GetLine(); line.StartPoint().z = 0.0; line.EndPoint().z = 0.0; lineTemp.setStartPoint(line.StartPoint()); lineTemp.setEndPoint(line.EndPoint()); } else { delete pLine; return; } // 是否有交点 AcGePoint3dArray ptArr; if (bLine) { pLine->intersectWith(&lineTemp, AcDb::kOnBothOperands, ptArr); } else { pLine->intersectWith(&arcTemp, AcDb::kOnBothOperands, ptArr); } int nNum = ptArr.length(); if (nNum > 1) // 可能存在重复点, 删除重复点 { AcGePoint3d pt; for (int i = 0; i < ptArr.length(); i++) { for (int j = i + 1; j < ptArr.length(); j++) { if ((ptArr[i]).distanceTo(ptArr[j]) < _DIST_SNAP) { ptArr.removeAt(j); j = i; } } } nNum = ptArr.length(); } if (nNum == 0) // 无交点 { if (bLine) { if (IsLineInPoly(poly, &lineTemp)) // 直线在poly外 { vecSeg1.push_back(seg); } else // 直线在poly内 { vecSeg2.push_back(seg); } } else { TADSGePoint3d ptS, ptE; arcTemp.getStartPoint(ptS); arcTemp.getEndPoint(ptE); AcDbLine line(ptS.AsAcGePoint3d(), ptE.AsAcGePoint3d()); if (IsLineInPoly(poly, &line)) // 直线在poly外 { vecSeg1.push_back(seg); } else // 直线在poly内 { vecSeg2.push_back(seg); } } } else if (nNum == 1) // 存在一个交点,有部分线段在poly2d { if (bLine) { TADSGePoint3d pt = poly.GetInsidePoint(); AcGePoint3d ptS = lineTemp.startPoint(), ptE = lineTemp.endPoint(); pt = ptArr[0]; if (!IsLineInPoly(poly, &lineTemp)) // 起点在poly内 { TGGeLine line1(TADSGePoint3d(ptS), pt); TGGeCurveSegment segTemp; segTemp = line1; vecSeg2.push_back(segTemp); // 虚线 TGGeLine line2(TADSGePoint3d(ptE), pt); segTemp = line2; vecSeg1.push_back(segTemp); } else { TGGeLine line1(TADSGePoint3d(ptE), pt); TGGeCurveSegment segTemp; segTemp = line1; vecSeg2.push_back(segTemp); // 虚线 TGGeLine line2(TADSGePoint3d(ptS), pt); segTemp = line2; vecSeg1.push_back(segTemp); } } else { TADSGePoint3d pt = poly.GetInsidePoint(); AcGePoint3d ptS, ptE; arcTemp.getStartPoint(ptS); arcTemp.getEndPoint(ptE); AcDbLine line(ptS, pt.AsAcGePoint3d()); pt = ptArr[0]; AcGePoint3d ptCenter = arcTemp.center(); AcGeVector3d vt1 = ptS - ptCenter; AcGeVector3d vt2 = ptArr[0] - ptCenter; AcGeVector3d vt3 = ptE - ptCenter; double dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis); double dAngle2 = vt2.angleTo(vt3, AcGeVector3d::kZAxis); if (!IsLineInPoly(poly, &line)) // 起点在poly内 { TGGeArc arc1(ptS, pt, dAngle1); TGGeCurveSegment segTemp; segTemp = arc1; vecSeg2.push_back(segTemp); TGGeArc arc2(pt, ptE, dAngle2); segTemp = arc2; vecSeg1.push_back(segTemp); } else { TGGeArc arc1(pt, ptE, dAngle2); TGGeCurveSegment segTemp; segTemp = arc1; vecSeg2.push_back(segTemp); TGGeArc arc2(ptS, pt, dAngle1); segTemp = arc2; vecSeg1.push_back(segTemp); } } } else if (nNum == 2) // 存在两个交点,线段被分成三分 { if (bLine) { TADSGePoint3d pt1 = ptArr[0], pt2 = ptArr[1]; TGGeLine line1(pt1, pt2); TGGeCurveSegment segTemp; segTemp = line1; vecSeg2.push_back(segTemp); // 虚线 // 根据两交点的顺序,生成相应线段 TADSGePoint3d pt3 = lineTemp.startPoint(), pt4 = lineTemp.endPoint(); if (pt1.Distance(pt3) < pt2.Distance(pt3)) { TGGeCurveSegment segTemp; if (pt1.Distance(pt3) > _DIST_SNAP) { TGGeLine line1(pt1, pt3); segTemp = line1; vecSeg1.push_back(segTemp); } if (pt2.Distance(pt4) > 0) { TGGeLine line1(pt2, pt4); segTemp = line1; vecSeg1.push_back(segTemp); } } else { TGGeCurveSegment segTemp; if (pt1.Distance(pt4) > _DIST_SNAP) { TGGeLine line1(pt1, pt4); segTemp = line1; vecSeg1.push_back(segTemp); } if (pt2.Distance(pt3) > _DIST_SNAP) { TGGeLine line1(pt2, pt3); segTemp = line1; vecSeg1.push_back(segTemp); } } } else { double dDist1 = 0.0, dDist2 = 0.0; arcTemp.getDistAtPoint(ptArr[0], dDist1); arcTemp.getDistAtPoint(ptArr[1], dDist2); AcGePoint3d ptS, ptE; arcTemp.getStartPoint(ptS); arcTemp.getEndPoint(ptE); if (dDist1 < dDist2) { AcGePoint3d ptCenter = arcTemp.center(); AcGeVector3d vt1 = ptS - ptCenter; AcGeVector3d vt2 = ptArr[0] - ptCenter; AcGeVector3d vt3 = ptArr[1] - ptCenter; AcGeVector3d vt4 = ptE - ptCenter; double dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis); double dAngle2 = vt2.angleTo(vt3, AcGeVector3d::kZAxis); double dAngle3 = vt3.angleTo(vt4, AcGeVector3d::kZAxis); TGGeCurveSegment segTemp; if (ptS.distanceTo(ptArr[0]) > _DIST_SNAP) { TGGeArc arc1(ptS, ptArr[0], dAngle1); segTemp = arc1; vecSeg1.push_back(segTemp); } TGGeArc arc2(ptArr[0], ptArr[1], dAngle2); segTemp = arc2; vecSeg2.push_back(segTemp); if (ptE.distanceTo(ptArr[1]) > _DIST_SNAP) { TGGeArc arc1(ptArr[1], ptE, dAngle3); segTemp = arc1; vecSeg1.push_back(segTemp); } } else { AcGePoint3d ptCenter = arcTemp.center(); AcGeVector3d vt1 = ptS - ptCenter; AcGeVector3d vt2 = ptArr[1] - ptCenter; AcGeVector3d vt3 = ptArr[0] - ptCenter; AcGeVector3d vt4 = ptE - ptCenter; double dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis); double dAngle2 = vt2.angleTo(vt3, AcGeVector3d::kZAxis); double dAngle3 = vt3.angleTo(vt4, AcGeVector3d::kZAxis); TGGeCurveSegment segTemp; if (ptS.distanceTo(ptArr[1]) > _DIST_SNAP) { TGGeArc arc1(ptS, ptArr[1], dAngle1); segTemp = arc1; vecSeg1.push_back(segTemp); } TGGeArc arc2(ptArr[1], ptArr[0], dAngle2); segTemp = arc2; vecSeg2.push_back(segTemp); if (ptE.distanceTo(ptArr[0]) > _DIST_SNAP) { TGGeArc arc1(ptArr[0], ptE, dAngle3); segTemp = arc1; vecSeg1.push_back(segTemp); } } } } delete pLine; } // 平面内的线无交点的情况下,线是否在poly内 bool TDbBaseWall::IsLineInPoly(TGGePoly2D &poly, AcDbLine *pLine) const { if (pLine == NULL) { return false; } bool bRet = true; XPoint pt1 = pLine->startPoint(); XPoint pt2 = pLine->endPoint(); if (((pt1 & poly) == PR_INSIDE) && ((pt2 & poly) == PR_INSIDE)) { bRet = false; } return bRet; } void TDbBaseWall::FiltrateSegment(std::vector &vecSeg1, std::vector &vecSeg2) const { // 删除重复线 FiltrateSegment(vecSeg1); FiltrateSegment(vecSeg2); // 删除与虚线重叠的实线部分 std::vector::iterator it; for (it = vecSeg2.begin(); it != vecSeg2.end(); it++) { FiltrateSegment(*it, vecSeg1); } } void TDbBaseWall::FiltrateSegment(const TGGeCurveSegment &seg, std::vector &vecSeg) const { CurveType type = seg.GetCurveType(); TGGeLine line; TGGeArc arc; TADSGePoint3d pt1, pt2, ptS, ptE; ptS = seg.StartPoint(); ptE = seg.EndPoint(); bool bModify = false; std::vector vecDel, vevNew; std::vector::iterator it; for(it = vecSeg.begin(); it != vecSeg.end(); it++) { bModify = false; if(it->GetLength() < _DIST_SNAP) { continue; } if (type == it->GetCurveType()) { if (type == CURVE_ARC) { arc = it->GetArc(); } else if (type == CURVE_LINE) { line = it->GetLine(); } else { continue; } if (type == CURVE_LINE) { line.SetLineFlag(1); AcGeVector3d vt1 = ptS - ptE, vt2 = line.StartPoint() - line.EndPoint(); bool bVal1 = fabs(ptS.Distance(line.StartPoint()) + ptS.Distance(line.EndPoint()) - line.GetLength())< _DIST_SNAP; bool bVal2 = fabs(ptE.Distance(line.StartPoint()) + ptE.Distance(line.EndPoint()) - line.GetLength())< _DIST_SNAP; if (vt1.isParallelTo(vt2) && (bVal1 || bVal2)) // 共线有交点 { if (ptS.Distance(line.StartPoint()) < _DIST_SNAP && ptE.Distance(line.EndPoint()) < _DIST_SNAP || ptS.Distance(line.EndPoint()) < _DIST_SNAP && ptE.Distance(line.StartPoint()) < _DIST_SNAP) // 重合 { bModify = true; } else if (bVal1 && bVal2) // 包含关系 { double dDist1 = ptS.Distance(line.StartPoint()); double dDist2 = ptE.Distance(line.StartPoint()); if (dDist1 < dDist2) { if (dDist1 > _DIST_SNAP) { TGGeLine lineTemp(ptS, line.StartPoint()); TGGeCurveSegment segTemp; segTemp = lineTemp; vevNew.push_back(segTemp); bModify = true; } if (ptE.Distance(line.EndPoint()) > _DIST_SNAP) { TGGeLine lineTemp(ptE, line.EndPoint()); TGGeCurveSegment segTemp; segTemp = lineTemp; vevNew.push_back(segTemp); bModify = true; } } else { if (dDist2 > _DIST_SNAP) { TGGeLine lineTemp(ptE, line.StartPoint()); TGGeCurveSegment segTemp; segTemp = lineTemp; vevNew.push_back(segTemp); bModify = true; } if (ptS.Distance(line.EndPoint()) > _DIST_SNAP) { TGGeLine lineTemp(ptS, line.EndPoint()); TGGeCurveSegment segTemp; segTemp = lineTemp; vevNew.push_back(segTemp); bModify = true; } } } else if (bVal1) { double dDist1 = ptE.Distance(line.StartPoint()); double dDist2 = ptE.Distance(line.EndPoint()); if (dDist1 < dDist2) { if (ptS.Distance(line.EndPoint()) > _DIST_SNAP) { TGGeLine lineTemp(ptS, line.EndPoint()); TGGeCurveSegment segTemp; segTemp = lineTemp; vevNew.push_back(segTemp); bModify = true; } } else { if (ptS.Distance(line.StartPoint()) > _DIST_SNAP) { TGGeLine lineTemp(ptS, line.StartPoint()); TGGeCurveSegment segTemp; segTemp = lineTemp; vevNew.push_back(segTemp); bModify = true; } } } else if (bVal2) { double dDist1 = ptS.Distance(line.StartPoint()); double dDist2 = ptS.Distance(line.EndPoint()); if (dDist1 < dDist2) { if (ptE.Distance(line.EndPoint()) > _DIST_SNAP) { TGGeLine lineTemp(ptE, line.EndPoint()); TGGeCurveSegment segTemp; segTemp = lineTemp; vevNew.push_back(segTemp); bModify = true; } } else { if (ptE.Distance(line.StartPoint()) > _DIST_SNAP) { TGGeLine lineTemp(ptE, line.StartPoint()); TGGeCurveSegment segTemp; segTemp = lineTemp; vevNew.push_back(segTemp); bModify = true; } } } } } else { TGGeArc arcSeg = seg.GetArc(); double dRadius = arcSeg.GetRadius(); int bVal1 = arc.PtOnArc(ptS); int bVal2 = arc.PtOnArc(ptE); if (fabs(dRadius - arc.GetRadius()) < _DIST_SNAP && (arc.GetCenterPt()).Distance(arcSeg.GetCenterPt()) < _DIST_SNAP && (bVal1 || bVal2)) // 共弧有交点 { TADSGePoint3d pt1, pt2, ptCenter; arc.GetStartPoint(pt1); arc.GetEndPoint(pt2); arc.Center(ptCenter); if (ptS.Distance(pt1) < _DIST_SNAP && ptE.Distance(pt2) < _DIST_SNAP || ptS.Distance(pt2) < _DIST_SNAP && ptE.Distance(pt1) < _DIST_SNAP) // 重合 { bModify = true; } else if (bVal1 && bVal1) // 虚线在实线内 { AcGeVector3d vt1 = pt1 - ptCenter; AcGeVector3d vt2 = ptS - ptCenter; AcGeVector3d vt3 = ptE - ptCenter; AcGeVector3d vt4 = pt2 - ptCenter; double dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis); double dAngle3 = vt3.angleTo(vt4, AcGeVector3d::kZAxis); TGGeCurveSegment segTemp; if (pt1.Distance(ptS) > _DIST_SNAP) { TGGeArc arcTemp(pt1, ptS, dAngle1); segTemp = arcTemp; vevNew.push_back(segTemp); bModify = true; } if (pt2.Distance(ptE) > _DIST_SNAP) { TGGeArc arcTemp(ptE, pt2, dAngle3); segTemp = arcTemp; vevNew.push_back(segTemp); bModify = true; } } else if (bVal1) // 虚线起点在实线上 { if (ptS.Distance(pt1) > _DIST_SNAP) { AcGeVector3d vt1 = pt1 - ptCenter; AcGeVector3d vt2 = ptS - ptCenter; double dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis); TGGeArc arcTemp(pt1, ptS, dAngle); TGGeCurveSegment segTemp; segTemp = arcTemp; vevNew.push_back(segTemp); bModify = true; } } else if (bVal2) // 虚线终点在实线上 { if (ptE.Distance(pt2) > _DIST_SNAP) { AcGeVector3d vt1 = ptE - ptCenter; AcGeVector3d vt2 = pt2 - ptCenter; double dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis); TGGeArc arcTemp(ptE, pt2, dAngle); TGGeCurveSegment segTemp; segTemp = arcTemp; vevNew.push_back(segTemp); bModify = true; } } } } if (bModify) { vecDel.push_back(*it); } } } for (it = vevNew.begin(); it != vevNew.end(); it++) { vecSeg.push_back(*it); } for (it = vecDel.begin(); it != vecDel.end(); it++) { vecSeg.erase(std::find(vecSeg.begin(), vecSeg.end(), *it)); } } void TDbBaseWall::FiltrateSegment(std::vector &vecSeg) const { std::vector::iterator it1, it2; TGGeArc arc1, arc2; TGGeLine line1, line2; TADSGePoint3d ptS1, ptE1, ptCenter1, ptS2, ptE2, ptCenter2; int nSize = 0; for (it1 = vecSeg.begin(); it1 != vecSeg.end(); nSize == vecSeg.size() ? it1++ : it1) { nSize = vecSeg.size(); // 记录修改前大小 it2 = it1; ++it2; for (; it2 != vecSeg.end(); it2++) { if ((*it1).Is(CURVE_ARC) && it2->Is(CURVE_ARC)) { arc1 = it1->GetArc(); arc2 = it2->GetArc(); double dRadius1 = arc1.GetRadius(); double dRadius2 = arc2.GetRadius(); arc1.Center(ptCenter1); arc2.Center(ptCenter2); arc1.GetStartPoint(ptS1); arc1.GetEndPoint(ptE1); arc2.GetStartPoint(ptS2); arc2.GetEndPoint(ptE2); if (fabs(dRadius1 - dRadius2) < _DIST_SNAP && ptCenter1.Distance(ptCenter2) < _DIST_SNAP) // 共圆 { if ( ptS1.Distance(ptS2) < _DIST_SNAP && ptE1.Distance(ptE2) < _DIST_SNAP || ptS1.Distance(ptE2) < _DIST_SNAP && ptE1.Distance(ptS2) < _DIST_SNAP) // 重合 { vecSeg.erase(it2); break; } int bVal1 = false, bVal2 = false, bVal3 = false, bVal4 = false; bVal1 = arc1.PtOnArc(ptS2); bVal2 = arc1.PtOnArc(ptE2); bVal3 = arc2.PtOnArc(ptS1); bVal4 = arc2.PtOnArc(ptE1); if (bVal1 && bVal2) { vecSeg.erase(it2); break;; } else if (bVal3 && bVal4) { *it1 = *it2; vecSeg.erase(it2); break; } else if (bVal1) { TGGeArc arc(ptS1, ptS2, ptE2); *it1 = arc; vecSeg.erase(it2); break; } else if (bVal2) { TGGeArc arc(ptS2, ptE2, ptE1); *it1 = arc; vecSeg.erase(it2); break; } else if (bVal3) { TGGeArc arc(ptS2, ptS1, ptE1); *it1 = arc; vecSeg.erase(it2); break; } else if (bVal4) { TGGeArc arc(ptS1, ptE1, ptE2); *it1 = arc; vecSeg.erase(it2); break; } } } else if ((*it1).Is(CURVE_LINE) && it2->Is(CURVE_LINE)) { line1 = it1->GetLine(); line2 = it2->GetLine(); ptS1 = line1.StartPoint(); ptE1 = line1.EndPoint(); ptS2 = line2.StartPoint(); ptE2 = line2.EndPoint(); if (ptS1.Distance(ptS2) < _DIST_SNAP && ptE1.Distance(ptE2) < _DIST_SNAP || ptS1.Distance(ptE2) < _DIST_SNAP && ptE1.Distance(ptS2) < _DIST_SNAP) // 重合 { vecSeg.erase(it2); break; } AcGeVector3d vt1 = ptE1 - ptS1, vt2 = ptE2 - ptS2; AcDbLine lineA(ptS1, ptE1), lineB(ptS2, ptE2); AcGePoint3d pt1; lineB.getClosestPointTo(ptS1, pt1, Adesk::kTrue); if (vt1.isParallelTo(vt2) && ptS1.Distance(pt1) < _DIST_SNAP) // 共线 { AcGePoint3d pt2, pt3, pt4; lineB.getClosestPointTo(ptS1, pt1); lineB.getClosestPointTo(ptE1, pt2); lineA.getClosestPointTo(ptS2, pt3); lineA.getClosestPointTo(ptE2, pt4); if (ptS1.Distance(pt1) < _DIST_SNAP || ptE1.Distance(pt2) < _DIST_SNAP || ptS2.Distance(pt3) < _DIST_SNAP || ptE2.Distance(pt4) < _DIST_SNAP) // 两直线存在交点 { double dDist1 = ptS1.Distance(ptE1); double dDist2 = ptS1.Distance(ptS2); double dDist3 = ptS1.Distance(ptE2); double dDist4 = ptE1.Distance(ptS2); double dDist5 = ptE1.Distance(ptE2); double dDist6 = ptS2.Distance(ptE2); std::vector vecDbl; vecDbl.push_back(dDist1); vecDbl.push_back(dDist2); vecDbl.push_back(dDist3); vecDbl.push_back(dDist4); vecDbl.push_back(dDist5); vecDbl.push_back(dDist6); double dMax = *(std::max_element(vecDbl.begin(), vecDbl.end())); if (fabs(dMax - dDist1) < _DIST_SNAP) { vecSeg.erase(it2); } else if (fabs(dMax - dDist2) < _DIST_SNAP) { vecSeg.erase(it2); (*it1).SetEndPoint(ptS2); } else if (fabs(dMax - dDist3) < _DIST_SNAP) { vecSeg.erase(it2); (*it1).SetEndPoint(ptE2); } else if (fabs(dMax - dDist4) < _DIST_SNAP) { vecSeg.erase(it2); (*it1).SetStartPoint(ptS2); } else if (fabs(dMax - dDist5) < _DIST_SNAP) { vecSeg.erase(it2); (*it1).SetStartPoint(ptE2); } else if (fabs(dMax - dDist6) < _DIST_SNAP) { vecSeg.erase(it2); (*it1).SetStartPoint(ptS2); (*it1).SetEndPoint(ptS2); } break; } } } } } } TGGeCurveSegment TDbBaseWall::GetCenterLine()const { AcGePoint3d ptS, ptE; GetAt(KEY_START, ptS); GetAt(KEY_END, ptE); double dBulge = 0.0; GetAt(KEY_BULGE, dBulge); return TGGeCurveSegment(ptS, ptE, dBulge); } // 取墙中心线的起点和终点,然后对这根线延伸1个长度 TGGeCurveSegment TDbBaseWall::GetLongBaseLine() const { // 转换cvBase TGGeCurveSegment cvBase = GetCenterLine(); if (!cvBase.Is(CURVE_LINE)) // 只处理直线的情况 { return cvBase; } // 将cvBase延伸一个墙体总宽度 double dWid = 0; GetTotalWidth(dWid); TADSGePointDir2d ptExtStart, ptExtEnd; cvBase.Polar(-dWid, ptExtStart, TRUE); cvBase.Polar(-dWid, ptExtEnd, FALSE); cvBase.SetPoints(ptExtStart, ptExtEnd); return cvBase; } // 获得墙体范围内的轴线或墙,梁 // 返回值: 位0x01--左轴线(墙或梁), 位0x02--右轴线(墙或梁) int TDbBaseWall::GetAxises(int nDivType,const TADSGePoint3d &ptAt, TEntitySet &lEntAxis, TEntitySet &rEntAxis) const { TPickEntSet ss(SS_FREE); //在获得墙体范围内的轴线时,采取扩大搜索范围的算法 TGGeCurveSegment segThis = GetLongBaseLine(); segThis.SetElevation(0.0); TADSGePointDir2d ptExtStart, ptExtEnd; segThis.Polar(-_AS_SYS_UNIT(g_nDistPrec), ptExtStart, TRUE); segThis.Polar(-_AS_SYS_UNIT(g_nDistPrec), ptExtEnd, FALSE); segThis.SetPoints(ptExtStart, ptExtEnd); TGGePoly2D poly; if (nDivType == 0 || nDivType == 3)//搜轴线直接用中心线搜 { segThis.AsPoly2D(poly); } else { double dWidth(0); GetTotalWidth(dWidth); TGGeCurveSegment cv = segThis; cv=segThis.Offset(OFFSET_RIGHT,dWidth*0.6,LS_FINITE); cv.AsPoly2D(poly); cv = segThis.Offset(OFFSET_LEFT,dWidth*0.6,LS_FINITE); poly.AppendNode(cv.GetEndPoint(),-cv.GetBulge()); poly.AppendNode(cv.GetStartPoint()); } TGGePoly poly1; poly.MapToPolygon(poly1); switch (nDivType) { case 0: //轴线等分加梁 case 3: //轴线等分插洞 if (ss.Get(_T("F"), TRBList(poly1.Fence()), NULL, TRBList(RTDXF0, _T("LINE,ARC,CIRCLE"), 8, LAY_AXIS, NULL)) != RTNORM) { return 0; } break; case 1: //等分梁 if (ss.Get(_T("cp"), TRBList(poly1.Polygon()), NULL, TRBList(RTDXF0, _T("ATS_STRUBEAM"), NULL)) != RTNORM) { return 0; } break; case 2: //等分墙 if (ss.Get(_T("cp"), TRBList(poly1.Polygon()), NULL, TRBList(RTDXF0, _T("ATS_WALL"), NULL)) != RTNORM) { return 0; } break; } int nRetFlag = 0; segThis.SetLineFlag(LS_FINITE); ads_real nDist = segThis.PathDistance(TADSGePoint3d(ptAt.x, ptAt.y)); ads_real nDistLeft = 0.0, nDistRight = segThis.GetLength(); long ssLen = ss.Length(); BOOL bIsArc = segThis.Is(CURVE_ARC); //当前是否为弧梁或墙 for (long i = 0; i < ssLen; i++) { TEntitySet ent = ss[i]; TGGeCurveSegment segAxis; // 根据等分类型获得轴线或墙中心线 switch (nDivType) { case 0: case 3: { TGGeCurveSegment cvAxis(ent, LS_FINITE); segAxis = cvAxis; } break; case 1: case 2: OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbBaseWall, pEnt); if (pEnt) { segAxis = pEnt->GetLongBaseLine(); } else { continue; } OPENOBJ_END(); break; } segAxis.SetElevation(0.0); if (bIsArc) { if (!segAxis.Is(CURVE_LINE)) { continue; } TGGeArc ar = segThis.GetArc(); double nDistTo = ar.GetCenterPt().Distance(&segAxis); if (nDistTo > _DIST_SNAP) { continue; } } // 求交 TADSGePoint3d ptInt[2]; int nInt = segThis.Intersection(segAxis, ptInt[0], ptInt[1]); if (!nInt) { continue; } TADSGePoint3d ptInters; if (nInt == 1) { ptInters = ptInt[0]; } else { ptInters = TGGeLine(ptInt[0], ptInt[1]).NearPoint(TADSGePoint3d(ptAt.x, ptAt.y)); } // 确定左右轴线 ads_real nDist0 = segThis.PathDistance(ptInters); if (nDist0 < nDist) { if (nDist0 > nDistLeft) { nRetFlag |= 0x01; nDistLeft = nDist0; lEntAxis = ent; } } else { if (nDist0 < nDistRight) { nRetFlag |= 0x02; nDistRight = nDist0; rEntAxis = ent; } } } return nRetFlag; } // 取得墙体等分的参数 // 返回值:RTNORM/RTERROR/RTCAN // [in]nDivType:等分类型:0,轴线等分加梁,1,净跨等分加梁,2,等分加墙,3,等分插洞; // [in]nOpWidth:插入对象的宽度;ptNew:插入点 // [out]segThis:等分线段;nOpeningCount:等分数目,仅插洞时有意义;nUnitDist:等分长度,仅插洞时有意义 // [out]pSet:插梁或墙时的边界对象,插洞时为空 int TDbBaseWall::GetIsoParameters(int nDivType, double nOpWidth, const TADSGePoint3d &ptNew, TGGeCurveSegment &segThis, int *nOpeningCount, double *nUnitDist, TEntitySet* pSet) const { int &nOpNum = *nOpeningCount; ads_real &nUnitLen = *nUnitDist; TGGeCurveSegment wall = GetCenterLine(); wall.SetLineFlag(LS_FINITE); TEntitySet lEntAxis, rEntAxis; AcGePoint3d ptLeft,ptRight; GetAt(KEY_START,ptLeft); GetAt(KEY_END,ptRight); TADSGePoint3d ptLimLeft = ptLeft, ptLimRight = ptRight; int nAxisNum = GetAxises(nDivType, ptNew, lEntAxis, rEntAxis); // 求左右界限点 // 获得墙体范围内的轴线时,采取扩大搜索范围的算法 segThis = GetLongBaseLine(); segThis.SetLineFlag(LS_FINITE); // 找到左侧轴线 if (nAxisNum & 0x01) { BOOL bOk = FALSE; TGGeCurveSegment segLeft; if (nDivType == 0 || nDivType == 3) //轴线等分加梁或插洞 { TGGeCurveSegment cvLeft(lEntAxis, LS_FINITE); segLeft = cvLeft; } else //净跨等分加梁或等分加墙 { TGGeCurveSegment cvLeft; OPENOBJ_BEGIN(lEntAxis, AcDb::kForRead, TDbBaseWall, pEnt); if (pEnt) { cvLeft = pEnt->GetCenterLine(); if(nDivType == 1) //梁净跨等分 { double dWidth = 0; pEnt->GetTotalWidth(dWidth); int nSide = cvLeft.OnWhichSide(ptNew); cvLeft = cvLeft.Offset(nSide, dWidth*0.5, cvLeft.GetLineFlag()); } segLeft = cvLeft; } OPENOBJ_END(); } segLeft.SetElevation(segThis.StartPoint().z); if (segThis.Intersection(segLeft, ptLimLeft, TADSGePoint3d()) != 1) { ptLimLeft = segThis.StartPoint(); } lEntAxis.Redraw(3); } // 找到右侧轴线 if (nAxisNum & 0x02) { BOOL bOk = FALSE; TGGeCurveSegment segRight; if (nDivType == 0 || nDivType == 3) //轴线等分加梁或插洞 { TGGeCurveSegment cvRight(rEntAxis, LS_FINITE); segRight = cvRight; } else //净跨等分加梁或等分加墙 { TGGeCurveSegment cvRight; OPENOBJ_BEGIN(rEntAxis, AcDb::kForRead, TDbBaseWall, pEnt); if (pEnt) { cvRight = pEnt->GetCenterLine(); if(nDivType == 1) //梁净跨等分 { double dWidth = 0; pEnt->GetTotalWidth(dWidth); int nSide = cvRight.OnWhichSide(ptNew); cvRight = cvRight.Offset(nSide, dWidth*0.5, cvRight.GetLineFlag()); } segRight = cvRight; } OPENOBJ_END(); } segRight.SetElevation(segThis.StartPoint().z); if (segThis.Intersection(segRight, ptLimRight, TADSGePoint3d()) != 1) { ptLimRight = segThis.EndPoint(); } rEntAxis.Redraw(3); } // 构造区间 segThis.SetPoints(ptLimLeft, ptLimRight); { int nMaxNum1 = TNumeric(segThis.GetLength() / nOpWidth).AsInt(); if (nOpNum > nMaxNum1 || nOpNum < 1) { nOpNum = 1; } CString strPrompt; if (nDivType == 3) { strPrompt.Format(_T("\n指定参考轴线[S]/洞口个数(1~%d)<%d>:"), nMaxNum1, nOpNum); } else if (nDivType == 0) { strPrompt.Format(_T("\n指定参考轴线[S]/选择作为另一边界的梁<退出>:")); } else if (nDivType == 1) { strPrompt.Format(_T("\n指定参考梁[S]/选择作为另一边界的梁<退出>:")); } else if (nDivType == 2) { strPrompt.Format(_T("\n指定参考墙[S]/选择作为另一边界的墙<退出>:")); } int nCode = 0; TEntitySet ent; TCHAR szKeyword[80] = _T(""); if(nDivType == 3) { INITGET_BEG(RSG_NONEG | RSG_NOZERO, _T("S")); nCode = ads_getint(strPrompt, &nOpNum); INITGET_END(); if (nCode == RTKWORD) { ads_getinput(szKeyword); } } else { CString strDxf(_T("ATS_STRUBEAM")); if(nDivType == 2) { strDxf = _T("ATS_WALL"); } TCHAR cKey; nCode = SelectEntity(strPrompt, ent, TRBList(acutBuildList(RTDXF0, strDxf, NULL)), _T("S"), cKey); szKeyword[0] = cKey; } // 默认轴线取消高亮 if (nAxisNum & 0x01) { lEntAxis.Redraw(4); } if (nAxisNum & 0x02) { rEntAxis.Redraw(4); } if (nCode == RTKWORD) { if (szKeyword[0] == _T('S')) { TEntitySet ent1, ent2; ads_real nDist1 = 0.0, nDist2 = 0.0; ads_real nDistPick = segThis.PathDistance(ptNew); TADSGePointDir2d pt1, pt2; int nFlag = 0; if (nDivType == 0 || nDivType == 3) { TRBList mask(RTDXF0, _T("LINE,ARC,CIRCLE"), 8, LAY_AXIS, NULL); if (ent1.FilterSelect(_T("\n第一根轴线:"), mask) == RTCAN) { return RTCAN; } } else if (nDivType == 1) { TRBList mask(RTDXF0, _T("ATS_STRUBEAM"), NULL); if (ent1.FilterSelect(_T("\n第一个参考梁:"), mask) == RTCAN) { return RTCAN; } } else if (nDivType == 2) { TRBList mask(RTDXF0, _T("ATS_WALL"), NULL); if (ent1.FilterSelect(_T("\n第一个参考墙:"), mask) == RTCAN) { return RTCAN; } } double dWidthL = 0,dWidthR = 0; if (!(!ent1)) { ent1.Redraw(3); TGGeCurveSegment cv, cv1 = wall; if(nDivType == 0 || nDivType == 3) { TGGeCurveSegment cv2(ent1, LS_FINITE); cv = cv2; } else { OPENOBJ_BEGIN(ent1, AcDb::kForRead, TDbBaseWall, pEnt); if (pEnt) { cv = pEnt->GetCenterLine(); if(nDivType == 1) //梁净跨等分 { pEnt->GetTotalWidth(dWidthL); } } OPENOBJ_END(); } if (cv1.Is(CURVE_LINE)) { cv1.SetLineFlag(LS_INFINITE); } if (cv.Is(CURVE_LINE)) { cv.SetLineFlag(LS_INFINITE); } cv.SetElevation(cv1.StartPoint().z); if (cv1.Intersection(cv, pt1, TADSGePoint3d()) == 1) { nDist1 = cv1.PathDistance(pt1); nFlag |= 0x01; } } if (nDivType == 0 || nDivType == 3) { TRBList mask(RTDXF0, _T("LINE,ARC,CIRCLE"), 8, LAY_AXIS, NULL); if (ent2.FilterSelect(_T("\n第二根轴线:"), mask) == RTCAN) { if (!!ent1) { ent1.Redraw(4); } return RTCAN; } } else if (nDivType == 1) { TRBList mask(RTDXF0, _T("ATS_STRUBEAM"), NULL); if (ent2.FilterSelect(_T("\n第二个参考梁:"), mask) == RTCAN) { if (!!ent1) { ent1.Redraw(4); } return RTCAN; } } else if (nDivType == 2) { TRBList mask(RTDXF0, _T("ATS_WALL"), NULL); if (ent2.FilterSelect(_T("\n第二个参考墙:"), mask) == RTCAN) { if (!!ent1) { ent1.Redraw(4); } return RTCAN; } } if (!(!ent2)) { ent2.Redraw(3); TGGeCurveSegment cv, cv1 = wall; if(nDivType == 0 || nDivType == 3) { TGGeCurveSegment cv2(ent2, LS_FINITE); cv = cv2; } else { OPENOBJ_BEGIN(ent2, AcDb::kForRead, TDbBaseWall, pEnt); if (pEnt) { cv = pEnt->GetCenterLine(); if(nDivType == 1) //梁净跨等分 { pEnt->GetTotalWidth(dWidthR); } } OPENOBJ_END(); } if (cv1.Is(CURVE_LINE)) { cv1.SetLineFlag(LS_INFINITE); } if (cv.Is(CURVE_LINE)) { cv.SetLineFlag(LS_INFINITE); } cv.SetElevation(cv1.StartPoint().z); if (cv1.Intersection(cv, pt2, TADSGePoint3d()) == 1) { nDist2 = cv1.PathDistance(pt2); nFlag |= 0x02; } } if ((nFlag & 0x01) && (nFlag & 0x02)) { if (nDist1 < nDist2) { segThis.SetPoints(pt1, pt2); if (nDivType == 1) //梁净跨等分 { segThis.Polar(dWidthL*0.5, pt1, TRUE); segThis.Polar(dWidthR*0.5, pt2, FALSE); segThis.SetPoints(pt1, pt2); } } else { segThis.SetPoints(pt2, pt1); if (nDivType == 1) //梁净跨等分 { segThis.Polar(dWidthR*0.5, pt2, TRUE); segThis.Polar(dWidthL*0.5, pt1, FALSE); segThis.SetPoints(pt2, pt1); } } } else { if (nFlag & 0x01) { if (nDistPick < nDist1) { segThis.SetPoints(pt1, ptLimRight); if (nDivType == 1) //梁净跨等分 { segThis.Polar(dWidthL*0.5, pt1, TRUE); segThis.SetPoints(pt1, ptLimRight); } } else { segThis.SetPoints(ptLimLeft, pt1); if (nDivType == 1) //梁净跨等分 { segThis.Polar(dWidthL*0.5, pt1, FALSE); segThis.SetPoints(ptLimLeft, pt1); } } } else if (nFlag & 0x02) { if (nDistPick < nDist2) { segThis.SetPoints(pt2, ptLimRight); if (nDivType == 1) //梁净跨等分 { segThis.Polar(dWidthR*0.5, pt2, TRUE); segThis.SetPoints(pt2, ptLimRight); } } else { segThis.SetPoints(ptLimLeft, pt2); if (nDivType == 1) //梁净跨等分 { segThis.Polar(dWidthR*0.5, pt2, FALSE); segThis.SetPoints(ptLimLeft, pt2); } } } } if (nDivType == 3) { if (!!ent1) { ent1.Redraw(4); } if (!!ent2) { ent2.Redraw(4); } int nMaxNum = int(segThis.GetLength() / nOpWidth); if (nMaxNum < 1) { adsout << _T("\n点取位置不能插洞口!"); return RTERROR; } adsout << _T("\n洞口个数(1~") << nMaxNum << _T(")<") << nOpNum << _T(">: "); ads_initget(RSG_NONEG | RSG_NOZERO, NULL); if (ads_getint(_T(""), &nOpNum) == RTCAN || nOpNum > nMaxNum) { return RTCAN; } } else { // 取消高亮 if (!!ent1) { ent1.Redraw(4); } if (!!ent2) { ent2.Redraw(4); } CString strDxf(_T("ATS_STRUBEAM")); if(nDivType == 2) { strPrompt.Format(_T("\n选择作为另一边界的墙<退出>:")); strDxf = _T("ATS_WALL"); } else { strPrompt.Format(_T("\n选择作为另一边界的梁<退出>:")); } nCode = SelectEntity(strPrompt, ent, TRBList(acutBuildList(RTDXF0, strDxf, NULL))); if (nCode == RTNORM) { *pSet = ent; } else { return nCode; } } } } else { if (nDivType == 3) //插洞 { if (nCode == RTCAN) { return nCode; } else if (nOpNum > nMaxNum1) { adsout << _T("\n不能插入指定个数的洞口!"); return RTERROR; } } else { if (nCode == RTNORM) { *pSet = ent; } else { return nCode; } } } } ads_real nCurveLen = segThis.GetLength(); nUnitLen = nCurveLen / nOpNum; //单元长度 return RTNORM; } void TDbBaseWall::GetTotalWidth(double &dWidth)const { } // 获得总高度 void TDbBaseWall::GetTotalHeight(double &dHeight)const { } // 夹点消息后,更新自己边界 void TDbBaseWall::UpdateMeOnGripMsg(TAssocMsg assocMsg) { //不是夹点消息直接返回 if (assocMsg.GetMethod() != TAssocMsg::kMovegrippoint) { return; } assertWriteEnabled(); TGGeCurveSegment cvBase = GetCenterLine(); //形心线 if (!cvBase.Is(CURVE_LINE)) //仅处理直线情况 { return; } int nLength = m_arAssocBWallIds.length(); if (nLength < 0) { return; } double dElevS = cvBase.GetStartPoint().z; double dElevE = cvBase.GetEndPoint().z; AcGeVector3d vtOffset = assocMsg.GetOffset(); AcGePoint3d ptTarget = assocMsg.GetTarget(); TADSGePoint3d pt = ptTarget; cvBase.SetElevation(0); TADSGePoint3d ptStart = cvBase.GetStartPoint(); TADSGePoint3d ptEnd = cvBase.GetEndPoint(); ptStart -= vtOffset; ptEnd -= vtOffset; TGGeCurveSegment cvSrc(ptStart, ptEnd, 0); double dDir = cvBase.TGGeLine::Direction(); double dPrec = sin(PI/36); //同向精度5° bool bMod = false; //记录是否中心线进行了延长处理 //找出与偏移方向斜交或平行的梁(垂直时梁不需要延伸) for (int i = 0; i < nLength; i++) { OPENOBJ_BEGIN(m_arAssocBWallIds[i], AcDb::kForRead, TDbBaseWall, pEnt); if (pEnt) { TGGeCurveSegment cvCL = pEnt->GetCenterLine(); if (!cvCL.Is(CURVE_LINE)) { continue; } TVector3D vt3d = cvCL.GetEndPoint() - cvCL.GetStartPoint(); AcGeVector3d vtCL = vt3d.AsAcGeVector3d(); double dDirCL = cvCL.TGGeLine::Direction(); bool bStart = false, bEnd = false; //当前修改的端点标志 cvCL.SetElevation(0); if (fabs(vtCL.dotProduct(vtOffset)) < _DIST_SNAP) { continue; //垂直 } if (vtOffset.isParallelTo(vtCL)) //平行 { } else //斜交 { cvSrc.Intersection(cvCL, pt, TADSGePoint3d()); int nPos = (pt&cvSrc); if (nPos == PR_ONPT1) //起点 { bStart = true; } else if (nPos == PR_ONPT2) //终点 { bEnd = true; } } cvCL.SetLineFlag(LS_INFINITE); cvBase.SetLineFlag(LS_INFINITE); TADSGePoint3d ptInter; cvBase.Intersection(cvCL, ptInter, TADSGePoint3d()); cvBase.SetLineFlag(LS_FINITE); if (bStart) //修改起点 { bMod = true; cvBase.SetStartPoint(ptInter); } else if (bEnd) //修改终点 { bMod = true; cvBase.SetEndPoint(ptInter); } else if ((ptInter&cvBase) == PR_EXTEND) //延长线上点 { bMod = true; if (ptInter.Distance2d(cvBase.GetStartPoint()) < ptInter.Distance2d(cvBase.GetEndPoint())) //延长起始点 { cvBase.SetStartPoint(ptInter); } else { cvBase.SetEndPoint(ptInter); } } } OPENOBJ_END(); } // 处理关联普通板 pt.z = 0; nLength = m_arSlabIds.length(); for (i = 0; i < nLength; i++) { OPENOBJ_BEGIN(m_arSlabIds[i], AcDb::kForRead, TDbStruFloorSlab, pEnt); if (pEnt) { int nType = 0; GetAt(KEY_KIND, nType); if (nType != 0) //仅处理普通板 { continue; } TGGePoly2D polySrc; pEnt->GetOutline(polySrc); TGGePoly2D poly = polySrc; poly.SetElevation(0); int nPos = poly.HitTestOnCurve(pt); if (nPos < 0) //选中边 { int nLen = poly.TotalSegments(); int nPre = -nPos; int nNext = -nPos; if (nPre == 1) { nPre = nLen-1; } else { nPre = nPre-2; } if (nNext == nLen) { nNext = 0; } TGGeCurveSegment cvPre; TGGeCurveSegment cvNext; poly.Nth(nPre, cvPre); poly.Nth(nNext, cvNext); cvPre.SetLineFlag(LS_INFINITE); cvNext.SetLineFlag(LS_INFINITE); cvBase.SetLineFlag(LS_INFINITE); //求交点 TADSGePoint3d ptVert; TADSGePoint3d ptInter1,ptInter2; int nNum = cvBase.Intersection(cvPre, ptInter1, ptInter2); if (nNum == 1) { ptVert = *polySrc[-nPos-1]; ptVert.x = ptInter1.x; ptVert.y = ptInter1.y; *polySrc[-nPos-1] = ptVert; } else if (nNum == 2) { ptVert = *polySrc[-nPos-1]; if (ptVert.Distance2d(ptInter1) < ptVert.Distance2d(ptInter2)) { ptVert.x = ptInter1.x; ptVert.y = ptInter1.y; } else { ptVert.x = ptInter2.x; ptVert.y = ptInter2.y; } *polySrc[-nPos-1] = ptVert; } if (-nPos == nLen) { nPos = 0; } else { nPos = -nPos; } nNum = cvBase.Intersection(cvNext, ptInter1, ptInter2); if (nNum == 1) { ptVert = *polySrc[nPos]; ptVert.x = ptInter1.x; ptVert.y = ptInter1.y; *polySrc[nPos] = ptVert; } else if (nNum == 2) { ptVert = *polySrc[nPos]; if (ptVert.Distance2d(ptInter1) < ptVert.Distance2d(ptInter2)) { ptVert.x = ptInter1.x; ptVert.y = ptInter1.y; } else { ptVert.x = ptInter2.x; ptVert.y = ptInter2.y; } *polySrc[nPos] = ptVert; } //调整楼板 if(pEnt->upgradeOpen() == Acad::eOk) { pEnt->SetOutlinePoly(polySrc); pEnt->downgradeOpen(); } } } OPENOBJ_END(); } //中心线有修改 if (bMod) { //恢复标高 ptStart = cvBase.GetStartPoint(); ptEnd = cvBase.GetEndPoint(); ptStart.z = dElevS; ptEnd.z = dElevE; SetAt(KEY_START, ptStart.AsAcGePoint3d()); SetAt(KEY_END, ptEnd.AsAcGePoint3d()); } } // 抽象墙外框线 void TDbBaseWall::GetPoly2D(TGGePoly2D &poly2d) const { } Adesk::Boolean TDbBaseWall::BreakAt(const TADSGePoint3d &ptLoc1, const TGGePoly2D *pPolyColu) { AcGePoint3d ptS,ptE; GetAt(KEY_START, ptS); GetAt(KEY_END, ptE); //首先判断ptLoc是否在墙基范围内 TADSGePoint3d ptLoc = ptLoc1; double nElev = ptS.z; ptLoc.z = nElev; TGGeCurveSegment cvCenter = GetCenterLine(); TADSGePoint3d ptProject; if (cvCenter.ProjectToMe(ptLoc, ptProject) != RTNORM) { return Adesk::kFalse; } TADSGePoint3d ptStart = ptS; TADSGePoint3d ptEnd = ptE; if (pPolyColu) { TGGePoly2D polyColu = *pPolyColu; polyColu.SetElevation(nElev); if ((ptStart & polyColu) != PR_OUTSIDE || (ptEnd & polyColu) != PR_OUTSIDE) { return Adesk::kFalse; } } else { if (ptLoc.Distance2d(ptProject) > _AS_SYS_UNIT(g_nDistPrec)) { return Adesk::kFalse; } } { if ((ptProject & cvCenter) != PR_INSIDE) { return Adesk::kFalse; } if (ptStart.Distance2d(ptProject) < _AS_SYS_UNIT(g_nDistPrec) || ptEnd.Distance2d(ptProject) < _AS_SYS_UNIT(g_nDistPrec)) { return Adesk::kFalse; } } AcDbObjectIdArray holeIds; GetAssocRelation(ASSOC_HOLE, holeIds); //判断位置是否在洞内 Adesk::Boolean bInHole = Adesk::kFalse; /*int nIdCount = holeIds.length(); for (int j = 0; j < nIdCount; j++) { AcDbObjectId id = holeIds[j]; OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbStruWallHole, pEnt); if (pEnt) { TGGePoly2D poly2d(1); pEnt->GetOutlinePoly2D(0.0, poly2d, TGGeCurveSegment()); if ((ptProject & poly2d) == PR_INSIDE) { bInHole = Adesk::kTrue; break; } } OPENOBJ_END(); }*/ Adesk::Boolean bResult; if (!bInHole) //位置不在门窗之内 { TGGeCurveSegment segFirst = cvCenter, segSecond = cvCenter; segFirst.SetPoints(ptStart, ptProject); segSecond.SetPoints(ptProject, ptEnd); // 两段的长度合理 if (segFirst.GetLength() > g_nMinLenWall && segSecond.GetLength() > g_nMinLenWall) { Acad::ErrorStatus es = upgradeOpen(); if (!(es == Acad::eOk || es == Acad::eWasOpenForWrite)) { return Adesk::kFalse; } assertWriteEnabled(); g_bModifyAgain = false; //打断后需重新建立关联 bool bAdd = false; double dWidth=0; GetTotalWidth(dWidth); //调整端点,有小短墙时不创建新对象 if (ptStart.Distance2d(ptProject) > dWidth) { SetAt(KEY_START, AcGePoint3d(ptStart)); SetAt(KEY_END, AcGePoint3d(ptProject)); SetAt(KEY_BULGE, segFirst.GetBulge()); } else { if (ptEnd.Distance2d(ptProject) > dWidth) { SetAt(KEY_START, AcGePoint3d(ptProject)); SetAt(KEY_END, AcGePoint3d(ptEnd)); SetAt(KEY_BULGE, segSecond.GetBulge()); bAdd = true; } } bResult = Adesk::kTrue; downgradeOpen(); TAssocMsg assocMsg; assocMsg.SetMethod(TAssocMsg::kAppend); assocMsg.SetAssocId(objectId()); AddMsg(assocMsg); AcDbObjectIdArray arIds; GetAssocRelation(ASSOC_XY, arIds); for(int i = 0; i < arIds.length(); i++) { TAssocMsg assocMsg; assocMsg.SetMethod(TAssocMsg::kEdit); assocMsg.SetAssocId(arIds[i]); AddMsg(assocMsg); } if ((!bAdd) && (ptEnd.Distance2d(ptProject) > dWidth)) { g_bModifyAgain = true; //打断后需重新建立关联 TDbBaseWall *pWall = NULL; pWall = (TDbBaseWall *)clone(); if (pWall) { TPushMemVar pushVar(g_bMonitorDbAction, TRUE); pWall->CopyPropertiesFrom(this, 0); pWall->SetAt(KEY_START, AcGePoint3d(ptProject)); pWall->SetAt(KEY_END, AcGePoint3d(ptEnd)); pWall->SetAt(KEY_BULGE, segSecond.GetBulge()); pWall->AddToMSpace(Adesk::kTrue); } } } } else { bResult = Adesk::kFalse; } return bResult; } //获得端点可以合并的连接墙 //bStart:true,起始端,false,终止端 //idAssoc:连接墙的ID //返回值:1,成功获得连接墙, 0,不成功 BOOL TDbBaseWall::GetAssocWall(bool bStart, AcDbObjectId& idAssoc) { idAssoc.setNull(); if (m_arColumnIds.length() > 1) { //柱子个数大于1时,墙两端都有柱子,此时墙体不发生合并 return FALSE; } if (m_arAssocBWallIds.length() < 1) { return FALSE; } AcGePoint3d ptStart; if (bStart) { GetAt(KEY_START, ptStart); } else { GetAt(KEY_END, ptStart); } if (m_arColumnIds.length() == 1) { OPENOBJ_BEGIN(m_arColumnIds[0], AcDb::kForRead, TDbColumn, pEnt); if (pEnt) { TGGePoly2D polyout; pEnt->GetOutline(polyout); TADSGePoint3d pt(ptStart); if (polyout.Length() > 0 ) { pt.z = polyout[0]->z; } if ((pt & polyout) != PR_OUTSIDE) { //端点在柱子里,不合并 return FALSE; } } OPENOBJ_END(); } double dDistS = 0, dDistE = 0; for (int i = 0; i < m_arAssocBWallIds.length(); i++) { OPENOBJ_BEGIN(m_arAssocBWallIds[i], AcDb::kForRead, TDbBaseWall, pEnt); if (pEnt) { AcGePoint3d ptS,ptE; pEnt->GetAt(KEY_START, ptS); pEnt->GetAt(KEY_END, ptE); dDistS = ptStart.distanceTo(ptS); dDistE = ptStart.distanceTo(ptE); if (dDistE < _DIST_SNAP || dDistS < _DIST_SNAP) { if (idAssoc.isNull()) { idAssoc = m_arAssocBWallIds[i]; } else { //端点处有多个墙时不合并 return FALSE; } } } OPENOBJ_END(); } if (idAssoc.isNull()) { return FALSE; } return TRUE; } BOOL TDbBaseWall::CanMerge(AcDbObjectId idWall) { return FALSE; } BOOL TDbBaseWall::MergeWith(AcDbObjectId idWall) { TGGeCurveSegment segCenter, segCenterOther; OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbBaseWall, pEnt); if (pEnt) { segCenterOther = pEnt->GetCenterLine(); } else { return FALSE; } OPENOBJ_END(); segCenter = GetCenterLine(); int bLineThis = segCenter.Is(CURVE_LINE), bLineOther = segCenterOther.Is(CURVE_LINE); if (bLineThis != bLineOther) { //直线和弧线不合并 return FALSE; } if (bLineThis) { if (!IsSameDrt(segCenter.TGGeLine::Direction(), segCenterOther.TGGeLine::Direction(), _angSnap)) { //不平行的不合并 return FALSE; } } else { TGGeArc arc1 = segCenter.GetArc(), arc2 = segCenterOther.GetArc(); if (!(fabs(arc1.GetRadius() - arc2.GetRadius()) < _DIST_SNAP && arc1.GetCenterPt() == arc2.GetCenterPt())) { //不是同心圆的不合并 return FALSE; } } //比较属性 if (!CanMerge(idWall)) { return FALSE; } int nPosFlag = 0; if (segCenter.GetStartPoint() == segCenterOther.GetStartPoint()) { nPosFlag = 1; //合并两个起点 } else if (segCenter.GetStartPoint() == segCenterOther.GetEndPoint()) { nPosFlag = 2; //合并自己的起点和另外的终点 } else if (segCenter.GetEndPoint() == segCenterOther.GetEndPoint()) { nPosFlag = 3; //合并两个终点 } else if (segCenter.GetEndPoint() == segCenterOther.GetStartPoint()) { nPosFlag = 4; //合并自己的终点和另外的起点 } if (!nPosFlag) { return FALSE; } BOOL bCanMerge = FALSE; TGGeCurveSegment seg; //曲线类型相同 if (bLineThis) { if (nPosFlag == 4) { seg.SetPoints(segCenter.StartPoint(), segCenterOther.EndPoint()); bCanMerge = TRUE; } else if (nPosFlag == 2) { seg.SetPoints(segCenterOther.StartPoint(), segCenter.EndPoint()); bCanMerge = TRUE; } else if (nPosFlag == 1) { seg.SetPoints(segCenterOther.EndPoint(), segCenter.EndPoint()); bCanMerge = TRUE; } else if (nPosFlag == 3) { seg.SetPoints(segCenter.StartPoint(), segCenterOther.StartPoint()); bCanMerge = TRUE; } } else { //TGGeArc arc1 = segCenter.GetArc(), // arc2 = segCenterOther.GetArc(); if (nPosFlag == 4) { if (segCenter.GetStartPoint() == segCenterOther.GetEndPoint()) { return FALSE; } seg = segCenter; seg.SetPoints(segCenter.StartPoint(), segCenterOther.EndPoint()); bCanMerge = TRUE; } else if (nPosFlag == 2) { if (segCenterOther.GetStartPoint() == segCenter.GetEndPoint()) { return FALSE; } seg = segCenter; seg.SetPoints(segCenterOther.StartPoint(), segCenter.EndPoint()); bCanMerge = TRUE; } } if (bCanMerge) { Acad::ErrorStatus es = upgradeOpen(); if (es == Acad::eOk) { SetAt(KEY_START, seg.StartPoint().AsAcGePoint3d()); SetAt(KEY_END,seg.EndPoint().AsAcGePoint3d()); SetAt(KEY_BULGE, seg.GetBulge()); OPENOBJ_BEGIN(idWall, AcDb::kForWrite, TDbBaseWall, pEnt); if (pEnt) { AcDbObjectIdArray arIds; pEnt->GetAssocRelation(ASSOC_ALL, arIds); arIds.remove(objectId()); pEnt->RemoveAssocRelation(objectId()); for (int i=0;iRemoveAssocRelation(arIds[i]); TAssocMsg assocMsg; assocMsg.SetMethod(TAssocMsg::kEdit); assocMsg.SetAssocId(arIds[i]); AddMsg(assocMsg); } pEnt->erase(); } OPENOBJ_END(); return TRUE; } } return FALSE; } // 裁剪梁的基础数组操作 void TDbBaseWall::SetBaseIds(const AcDbObjectIdArray& ids) { assertWriteEnabled(); m_arAssocZIds.setLogicalLength(0); m_arAssocZIds = ids; } void TDbBaseWall::GetBaseIds(AcDbObjectIdArray& ids) { assertReadEnabled(); ids.setLogicalLength(0); ids = m_arAssocZIds; } void TDbBaseWall::RemoveBaseIds(const AcDbObjectId& id) { assertWriteEnabled(); m_arAssocZIds.remove(id); } int TDbBaseWall::GetFirstVersion()const { return 10; } bool TDbBaseWall::IsModelEntity() const { return true; } void InitBaseWall(bool bTrue) { if (bTrue) { TDbBaseWall::rxInit(); #if (BASEWALL_AS_OBJ == 1) acrxBuildClassHierarchy(); TDbBaseWall::InitMatchProtocol(TRUE); #endif } else { #if (BASEWALL_AS_OBJ == 1) TDbBaseWall::InitMatchProtocol(FALSE); #endif deleteAcRxClass(TDbBaseWall::desc()); } } #endif