Files
envi-code/SourceCode/Code2026/CoreLibrary/AecDbWall.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

8331 lines
179 KiB
C++

#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<AecDbXOpening> pClnOpening(idPairOpening.value(), AcDb::kForWrite);
if (pClnOpening.openStatus() == Acad::eOk)
{
if (pClnWall->id().isValid())
pClnOpening->SetAt(KEY_IDCNT1, pClnWall->id());
}
AcDbObjectPointer<AecDbX3dPartEntity> 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<AecDbXOpening> 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 = &cir;
}
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<Point2d> convex_hull(std::vector<Point2d> 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 = &cir;
}
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 = &cir;
}
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<Point2d> 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<Point2d> 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<AecInterface>& 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<AecInterface> arInfs;
GetInterface(arInfs);
if (nIndex > -1 && nIndex < arInfs.length())
{
inf = arInfs.at(nIndex);
return true;
}
return false;
}
int AecDbXWall::GetInterfaceCount() const
{
assertReadEnabled();
AcArray<AecInterface> 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<AecInterface> 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<AcDbEntity *> &ar
, const std::map<AcDbEntity *, AcArray<AcDbEntity *>> &preAr
, AcArray<AcDbEntity *> &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<AcDbEntity*>& 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<CString> 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<double>(_T("墙体厚度"), pData, KEY_SIZE1);
properties.findAndSet<double>(_T("墙体总高度"), pData, KEY_SIZE2);
properties.findAndSet<double>(_T("底部标高"), pData, PIPE_EL);
properties.findAndSet<CString>(_T("墙体材质"), pData, KEY_MATERIAL);
properties.findAndSet<double>(_T("中线对齐左厚"), pData, KEY_L);
properties.findAndSet<double>(_T("墙体底部厚度"), pData, KEY_SIZE3);
properties.findAndSet<double>(_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;
}