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

528 lines
16 KiB
C++

#include "StdAfx.h"
// 加入一墙体作为隔板
AcDbObjectId AddWallAsClapboard(const XPoint &ptStart1, const XPoint &ptEnd1, double nHeight,double width=12.5)
{
AcDbObjectId idRet;
XCurveSegment curve(ptStart1, ptEnd1, 0.0);
XPoint vt=ptEnd1-ptStart1;
vt.Normalize();
XPoint ptMin, ptMax;
curve.GetExtend(ptMin, ptMax);
ptMin.x -= _AS_SYS_UNIT(g_nDistPrec); ptMin.y -= _AS_SYS_UNIT(g_nDistPrec);
ptMax.x += _AS_SYS_UNIT(g_nDistPrec); ptMax.y += _AS_SYS_UNIT(g_nDistPrec);
TDbWall *pWall=new TDbWall(ptStart1, ptEnd1);
pWall->SetHeight(nHeight);
pWall->SetUsageFlag(TWallData::kApartment);
pWall->SetStyle(TWallData::kDivider);
pWall->SetWidth(0, width);
pWall->SetWidth(1, width);
XPoly2D poly;
pWall->GetOutlinePoly(0,poly,FALSE);
RBList rbMask=ads_buildlist(RTDXF0, _T("ATS_WALL"), NULL);
PickSet ssCrossWalls(SS_FREE|SS_CREATE), ssAllWalls(SS_FREE);
XSortedVertexList lstVertexes(curve.StartPoint(), curve.EndPoint(), curve.GetBulge());
if(GetSafeSelection(ssAllWalls, 1, ptMin, ptMax, _T("ATS_WALL"))==Acad::eOk) {
long ssLen=ssAllWalls.Length();
//事先判断能否穿越墙体
for(long i=0; i<ssLen; i++) {
Entity ent=ssAllWalls[i];
XDbObject obj(ent, AcDb::kForRead);
if(!obj) continue;
TDbWall *pWall1=TDbWall::cast(obj.m_pObject);
if(!pWall1) continue;
//modified by whl on 051125
//int nPos=pWall->PosRelationWith(curve);
//if(nPos==3) { //重合
// return idRet;
//}
XPoint vt1=pWall1->EndPoint()-pWall1->StartPoint();
vt1.Normalize();
if(vt.AsAcGeVector2d().isParallelTo(vt1.AsAcGeVector2d()))
{
XPoly2D poly1;
pWall1->GetOutlinePoly(0,poly1,TRUE);
DList<XPoly2D> res;
TchSubExport::Intersect(poly,poly1,res);
if(res.Length()>0)
{
delete pWall;
return idRet;
}
}
}
}
pWall->AddToMSpace(Adesk::kFalse);
idRet=pWall->objectId();
pWall->close();
return idRet;
}
int InsertClapDoor(const XPoint &ptLoc, double nWidth, const AcDbObjectId &idWall)
{
const TCHAR *pszDoor2d=_T("TCHSYS(APDOOR2D)"), *pszDoor3d=_T("TCHSYS(APDOOR3D)");
XString szDoor2d(256), szDoor3d(256);
if(LoadDwbBlock(pszDoor2d, szDoor2d)!=RTNORM ||
LoadDwbBlock(pszDoor3d, szDoor3d)!=RTNORM)
return RTERROR;
AcDbObjectId idStyle2d=InitBlock(szDoor2d);
AcDbObjectId idStyle3d=InitBlock(szDoor3d);
TDbOpening *pOpening=new TDbOpening(idWall, idStyle2d, idStyle3d);
pOpening->InitHardPointerId();
pOpening->m_ptLocation = ptLoc;
pOpening->SetWidth(nWidth);
pOpening->SetHeight(1800);
pOpening->SetThickness(25);
pOpening->SetKind(TOpeningData::OP_DOOR);
pOpening->m_nOpStyle |= OPS_LVTRY;
pOpening->m_nIdStyle2d=idStyle2d;
pOpening->m_nIdStyle3d=idStyle3d;
// sg add 110401,增加隔断门设置
pOpening->SetSubKind(_T("隔断门"));
//pOpening->setLayer(InitLayer(LAY_SANIWARE, FALSE));
pOpening->setLayer(InitLayer(LAY_LATRINE, FALSE));//modified by whl on 0060517
AddToModelSpace(pOpening, Adesk::kFalse);
XDbObject objWall(idWall, AcDb::kForWrite);
ASSERT(!!objWall);
TDbWall *pWall=TDbWall::cast(objWall.m_pObject);
ASSERT(pWall);
pWall->InsertOpening(pOpening);
pOpening->m_nQuadrant=3; // Add this line 2000/3/7 by ZJQ
pOpening->close();
return RTNORM;
}
// 取最近墙的边线和法向
int GetNearestWallSide(const XPoint &ptPick, XCurveSegment &seg, double *nNormal)
{
PickSet ssWall(SS_FREE);
RBList rbMask=ads_buildlist(RTDXF0, _T("ATS_WALL"),NULL);
if(ssWall.Get(_T("X"), NULL, NULL, rbMask)!=RTNORM)
return RTERROR;
Entity entNearest;
ads_real nMinDist=0.0;
long nWallNum=ssWall.Length();
for(long i=0; i<nWallNum; i++) {
Entity entWall=ssWall[i];
XDbObject obj(entWall, AcDb::kForRead);
TDbWall *pWall=TDbWall::cast(obj.m_pObject);
if(!pWall) continue;
XPoint ptProject;
if(pWall->ProjectToMe(ptPick, ptProject)!=RTNORM || (ptProject&(*pWall))!=PR_INSIDE)
continue;
ptProject.z = ptPick.z; //忽略Z坐标
ads_real nDist=ads_distance(ptPick, ptProject);
if(!entNearest) {
nMinDist = nDist;
entNearest = entWall;
} else if(nDist<nMinDist) {
nMinDist = nDist;
entNearest = entWall;
}
}
if(!entNearest)
return RTERROR;
XDbObject objWall(entNearest, AcDb::kForRead);
TDbWall *pNearestWall=TDbWall::cast(objWall.m_pObject);
if(!pNearestWall)
return RTERROR;
int bSide=pNearestWall->OnWhichSide(ptPick);
seg=pNearestWall->GetRelativeSideCurve(bSide, pNearestWall->StartPoint(), 0.0, TRUE);
XPoint ptOnBase, ptOnSide;
if(pNearestWall->ProjectToMe(ptPick, ptOnBase)!=RTNORM ||
seg.ProjectToMe(ptPick, ptOnSide)!=RTNORM) {
return RTERROR;
}
*nNormal=ads_angle(ptOnBase, ptOnSide);
return RTNORM;
}
// 绘制隔板
int DrawClapBoard()
{
InitLayer(LAY_SANIWARE);
InitLayer(LAY_LATRINE);
XPoint ptStart, ptEnd;
adsout << _T("\n输入一直线来选洁具!");
if(ads_getpoint(NULL, _T("\n起点: "), ptStart)!=RTNORM ||
ads_getpoint(ptStart, _T("\n终点: "), ptEnd)!=RTNORM)
return RTERROR;
RBList rbFence=ads_buildlist(RT3DPOINT, &ptStart, RT3DPOINT, &ptEnd, NULL);
RBList rbMask=ads_buildlist(RTDXF0, _T("INSERT,AEC_BLOCK_INSERT"), 8, LAY_SANIWARE, NULL);
PickSet ss(SS_FREE);
if(ss.Get(_T("F"), rbFence, NULL, rbMask)!=RTNORM)
return RTERROR;
long lCount=ss.Length();
if(lCount<1)
return RTERROR;
ptStart=Ucs2Wcs(ptStart);
ptEnd=Ucs2Wcs(ptEnd);
double nDist=800, nBoardWidth=25;
XCurveSegment segSide;
double nNormalAngle=0.0;
XPoint ptMidLine;
ptMidLine = XLine(ptStart, ptEnd).MidPoint();
if(GetNearestWallSide(ptMidLine, segSide, &nNormalAngle)!=RTNORM)
return RTERROR;
static double nLength=400, nHeight=800;
if(lCount==1) {
if(GetDist(_T("\n隔板间距"), nDist, RSG_NONEG|RSG_NOZERO)==RTCAN)
return RTERROR;
Entity ent=ss[0L];
XPoint ptInsert;
double nRot=0;
ent.GetData(10, &ptInsert);
ent.GetData(50, &nRot);
if(GetDist(_T("\n隔板长度"), nLength, RSG_NONEG|RSG_NOZERO)==RTCAN)
return RTERROR;
segSide.ProjectToMe(XPoint(ptInsert), ptInsert);
XPoint ptStart1, ptStart2, ptEnd1, ptEnd2;
ads_polar(ptInsert, nRot-PI, nDist/2.0, ptStart1);
ads_polar(ptInsert, nRot, nDist/2.0, ptStart2);
ads_polar(ptStart1, nRot-PI/2.0, nLength, ptEnd1);
ads_polar(ptStart2, nRot-PI/2.0, nLength, ptEnd2);
ptStart1.z=ptEnd1.z=ptStart2.z=ptEnd2.z=400;
AddWallAsClapboard(ptStart1, ptEnd1, nHeight);
AddWallAsClapboard(ptStart2, ptEnd2, nHeight);
} else {
PointList lstSortPoints(ptStart, ptEnd);
XCurveSegment lnPick(ptStart, ptEnd, 0.0);
double nNormalDrt=0.0;
for(long i=0L; i<lCount; i++) {
Entity ent=ss[i];
XPoint ptInsert;
double nRot=0.0;
ent.GetData(10, &ptInsert);
ent.GetData(50, &nRot);
if(lnPick.ProjectToMe(XPoint(ptInsert), ptInsert)!=RTNORM)
continue;
if(lstSortPoints.Insert(ptInsert)==RTNORM) {
nNormalDrt=nRot;
//add by whl on 060120
OPENOBJ_BEGIN(ent,AcDb::kForRead,AcDbBlockReference,pBlk);
if(pBlk!=NULL)
{
if(pBlk->scaleFactors().sy<0)
nNormalDrt+=PI;
if(pBlk->scaleFactors().sx<0)
nNormalDrt+=PI;
}
OPENOBJ_END();
}
}
nNormalDrt = CT_std_angle(nNormalDrt-PI/2.0);
XPoint qtStart, qtEnd;
if(segSide.ProjectToMe(ptStart, qtStart)!=RTNORM ||
segSide.ProjectToMe(ptEnd, qtEnd)!=RTNORM)
return RTERROR;
double nDrt=ads_angle(qtStart, qtEnd); //布置隔板的方向
if(lstSortPoints.Length()<4) {
adsout << _T("\n点取位置不合适!");
return RTERROR;
}
if(GetDist(_T("\n隔板长度"), nLength, RSG_NONEG|RSG_NOZERO)==RTCAN)
return RTERROR;
nDist=lstSortPoints[1]->Distance(*lstSortPoints[2]);
XPoint ptFirstStart, ptFirstEnd; //第一个隔板的位置
ads_polar(*lstSortPoints[1], nDrt-PI, nDist/2.0, ptFirstStart);
segSide.ProjectToMe(XPoint(ptFirstStart), ptFirstStart);
ads_polar(ptFirstStart, nNormalDrt, nLength, ptFirstEnd);
ptFirstStart.z=ptFirstEnd.z=400;
AddWallAsClapboard(ptFirstStart, ptFirstEnd, nHeight);
for(int n=1; n<lstSortPoints.Length()-2; n++) {
XPoint ptStart1, ptEnd1, ptStart2;
ptStart1=*lstSortPoints[n];
ptStart2=*lstSortPoints[n+1];
XPoint ptMidStart, ptMidEnd;
ptMidStart = XLine(ptStart1, ptStart2).MidPoint();
segSide.ProjectToMe(XPoint(ptMidStart), ptMidStart);
ads_polar(ptMidStart, nNormalDrt, nLength, ptMidEnd);
ptMidStart.z=ptMidEnd.z=400;
AddWallAsClapboard(ptMidStart, ptMidEnd, nHeight);
nDist = ads_distance(ptStart1, ptStart2);
}
// 最后一个隔板
XPoint ptLastStart, ptLastEnd;
ads_polar(*lstSortPoints[lstSortPoints.Length()-2], nDrt, nDist/2.0, ptLastStart);
segSide.ProjectToMe(XPoint(ptLastStart), ptLastStart);
ads_polar(ptLastStart, nNormalDrt, nLength, ptLastEnd);
ptLastStart.z=ptLastEnd.z=400;
AddWallAsClapboard(ptLastStart, ptLastEnd, nHeight);
}
return RTNORM;
}
// 绘制隔断
int DrawApartBoard()
{
InitLayer(LAY_SANIWARE);
InitLayer(LAY_LATRINE);
XPoint ptStart, ptEnd;
adsout << _T("\n输入一直线来选洁具!");
if(ads_getpoint(NULL, _T("\n起点: "), ptStart)!=RTNORM ||
ads_getpoint(ptStart, _T("\n终点: "), ptEnd)!=RTNORM)
return RTERROR;
RBList rbFence=ads_buildlist(RT3DPOINT, &ptStart, RT3DPOINT, &ptEnd, NULL);
RBList rbMask=ads_buildlist(RTDXF0, _T("INSERT,AEC_BLOCK_INSERT"), 8, LAY_SANIWARE, NULL);
PickSet ss(SS_FREE);
if(ss.Get(_T("F"), rbFence, NULL, rbMask)!=RTNORM)
return RTERROR;
long lCount=ss.Length();
if(lCount<1)
return RTERROR;
ptStart=Ucs2Wcs(ptStart);
ptEnd=Ucs2Wcs(ptEnd);
double nDist=800, nBoardWidth=25;
XCurveSegment segSide;
double nNormalAngle=0.0;
XPoint ptMidLine;
ptMidLine = XLine(ptStart, ptEnd).MidPoint();
if(GetNearestWallSide(ptMidLine, segSide, &nNormalAngle)!=RTNORM)
return RTERROR;
static double nLength=1200, nDoorWidth=600, nHeight=1800;
if(lCount==1) {
if(GetDist(_T("\n隔断间距"), nDist, RSG_NONEG|RSG_NOZERO)==RTCAN)
return RTERROR;
Entity ent=ss[0L];
XPoint ptInsert;
double nRot=0;
ent.GetData(10, &ptInsert);
ent.GetData(50, &nRot);
if(GetDist(_T("\n隔断长度"), nLength, RSG_NONEG|RSG_NOZERO)==RTCAN)
return RTERROR;
if(GetDist(_T("\n隔断门宽"), nDoorWidth, RSG_NONEG|RSG_NOZERO)==RTCAN)
return RTERROR;
segSide.ProjectToMe(XPoint(ptInsert), ptInsert);
XPoint ptStart1, ptStart2, ptEnd1, ptEnd2;
ads_polar(ptInsert, nRot-PI, nDist/2.0, ptStart1);
ads_polar(ptInsert, nRot, nDist/2.0, ptStart2);
ads_polar(ptStart1, nRot-PI/2.0, nLength, ptEnd1);
ads_polar(ptStart2, nRot-PI/2.0, nLength, ptEnd2);
ptStart1.z=ptEnd1.z=ptStart2.z=ptEnd2.z=400;
AddWallAsClapboard(ptStart1, ptEnd1, nHeight);
AddWallAsClapboard(ptStart2, ptEnd2, nHeight);
AcDbObjectId idWall=AddWallAsClapboard(ptEnd1, ptEnd2, nHeight);
XPoint ptDoor;
ptDoor = XLine(ptEnd1, ptEnd2).MidPoint();
if(!!idWall)
InsertClapDoor(ptDoor, nDoorWidth, idWall);
} else {
PointList lstSortPoints(ptStart, ptEnd);
XCurveSegment lnPick(ptStart, ptEnd, 0.0);
double nNormalDrt=0.0;
for(long i=0L; i<lCount; i++) {
Entity ent=ss[i];
XPoint ptInsert;
double nRot=0.0;
ent.GetData(10, &ptInsert);
ent.GetData(50, &nRot);
if(lnPick.ProjectToMe(XPoint(ptInsert), ptInsert)!=RTNORM)
continue;
if(lstSortPoints.Insert(ptInsert)==RTNORM)
{
nNormalDrt=nRot;
//add by whl on 060120
OPENOBJ_BEGIN(ent,AcDb::kForRead,AcDbBlockReference,pBlk);
if(pBlk!=NULL)
{
if(pBlk->scaleFactors().sy<0)
nNormalDrt+=PI;
if(pBlk->scaleFactors().sx<0)
nNormalDrt+=PI;
}
OPENOBJ_END();
}
}
nNormalDrt = CT_std_angle(nNormalDrt-PI/2.0);
XPoint qtStart, qtEnd;
if(segSide.ProjectToMe(ptStart, qtStart)!=RTNORM ||
segSide.ProjectToMe(ptEnd, qtEnd)!=RTNORM)
return RTERROR;
double nDrt=ads_angle(qtStart, qtEnd); //布置隔板的方向
if(lstSortPoints.Length()<4) {
adsout << _T("\n点取位置不合适!");
return RTERROR;
}
if(GetDist(_T("\n隔板长度"), nLength, RSG_NONEG|RSG_NOZERO)==RTCAN)
return RTERROR;
if(GetDist(_T("\n隔断门宽"), nDoorWidth, RSG_NONEG|RSG_NOZERO)==RTCAN)
return RTERROR;
nDist=lstSortPoints[1]->Distance(*lstSortPoints[2]);
XPoint ptFirstStart, ptFirstEnd; //第一个隔板的位置
ads_polar(*lstSortPoints[1], nDrt-PI, nDist/2.0, ptFirstStart);
segSide.ProjectToMe(XPoint(ptFirstStart), ptFirstStart);
ads_polar(ptFirstStart, nNormalDrt, nLength, ptFirstEnd);
ptFirstStart.z=ptFirstEnd.z=400;
AddWallAsClapboard(ptFirstStart, ptFirstEnd, nHeight);
for(int n=1; n<lstSortPoints.Length()-2; n++) {
XPoint ptStart1, ptEnd1, ptStart2;
ptStart1=*lstSortPoints[n];
ptStart2=*lstSortPoints[n+1];
XPoint ptMidStart, ptMidEnd;
ptMidStart = XLine(ptStart1, ptStart2).MidPoint();
segSide.ProjectToMe(XPoint(ptMidStart), ptMidStart);
ads_polar(ptMidStart, nNormalDrt, nLength, ptMidEnd);
ptMidStart.z=ptMidEnd.z=ptFirstEnd.z=400;
AddWallAsClapboard(ptMidStart, ptMidEnd, nHeight);
AcDbObjectId idWall=AddWallAsClapboard(ptFirstEnd, ptMidEnd, nHeight);
XPoint ptDoor;
ptDoor = XLine(ptFirstEnd, ptMidEnd).MidPoint();
if(!!idWall)
InsertClapDoor(ptDoor, nDoorWidth, idWall);
nDist = ads_distance(ptStart1, ptStart2);
ptFirstStart=ptMidStart;
ptFirstEnd=ptMidEnd;
}
// 最后一个隔板
XPoint ptLastStart, ptLastEnd;
ads_polar(*lstSortPoints[lstSortPoints.Length()-2], nDrt, nDist/2.0, ptLastStart);
segSide.ProjectToMe(XPoint(ptLastStart), ptLastStart);
ads_polar(ptLastStart, nNormalDrt, nLength, ptLastEnd);
ptLastStart.z=ptLastEnd.z=ptFirstEnd.z=400;
AddWallAsClapboard(ptLastStart, ptLastEnd, nHeight);
AcDbObjectId idWall=AddWallAsClapboard(ptFirstEnd, ptLastEnd, nHeight);
XPoint ptDoor;
ptDoor = XLine(ptFirstEnd, ptLastEnd).MidPoint();
if(!!idWall)
InsertClapDoor(ptDoor, nDoorWidth, idWall);
}
return RTNORM;
}
int CallBlkArg()
{
return 1;
}
int CallBlkMan()
{
return 1;
}
int CreateDbfFile()
{
FieldInfo fields[4];
fields[0] = FieldInfo(_T("kind"), _T('C'), 64);
fields[1] = FieldInfo(_T("item"), _T('C'), 64);
fields[2] = FieldInfo(_T("drawing"), _T('C'), 32);
CodeBase db, dbOld;
CString sKind, sItem, sDrawing; //类别,名称,内部图名
XDbfTable *pTable = db.Create(_T("d:\\blocklib.dbf"), fields, 4);
XDbfTable *table = dbOld.Open(_T("D:\\tch5\\DDLIB\\DDBL.dbf"));
if(pTable)
{
if(table)
{
table->MoveFirst();
while(!table->IsEOF())
{
GET_FIELD(table, _T("kind"), sKind);
GET_FIELD(table, _T("item"), sItem);
GET_FIELD(table, _T("drawing"), sDrawing);
pTable->AppendBegin();
SET_FIELD(pTable, _T("kind"), (LPCTSTR)sKind);
SET_FIELD(pTable, _T("item"), (LPCTSTR)sItem);
SET_FIELD(pTable, _T("drawing"), (LPCTSTR)sDrawing);
pTable->AppendEnd();
table->MoveNext();
}
}
}
else
{
adsout << _T("Fail!");
}
return RTNORM;
}
int CreateDbf1()
{
FieldInfo fields[6];
fields[0]=FieldInfo(_T("name"), _T('C'), 32);
fields[1]=FieldInfo(_T("fill"), _T('N'), 1);
fields[2]=FieldInfo(_T("color"), _T('N'), 3);
fields[3]=FieldInfo(_T("priority"), _T('N'), 1);
fields[4]=FieldInfo(_T("lweight"), _T('N'), 5, 2);
CodeBase db;
XDbfTable *pTable=db.Create(_T("d:\\tch5\\sys\\compstyl.dbf"), fields, 6);
if(pTable)
{
pTable->AppendBegin();
SET_FIELD(pTable, _T("name"), _T("钢筋混凝土墙"));
SET_FIELD(pTable, _T("fill"), 1);
SET_FIELD(pTable, _T("color"), 5);
SET_FIELD(pTable, _T("priority"), 2);
SET_FIELD(pTable, _T("lweight"), 0.5);
pTable->AppendEnd();
pTable->AppendBegin();
SET_FIELD(pTable, _T("name"), _T("砖墙"));
SET_FIELD(pTable, _T("fill"), 0);
SET_FIELD(pTable, _T("color"), 256);
SET_FIELD(pTable, _T("priority"), 1);
SET_FIELD(pTable, _T("lweight"), 0.5);
pTable->AppendEnd();
pTable->AppendBegin();
SET_FIELD(pTable, _T("name"), _T("隔墙"));
SET_FIELD(pTable, _T("fill"), 0);
SET_FIELD(pTable, _T("color"), 256);
SET_FIELD(pTable, _T("priority"), 0);
SET_FIELD(pTable, _T("lweight"), 0.25);
pTable->AppendEnd();
pTable->AppendBegin();
SET_FIELD(pTable, _T("name"), _T("玻璃幕墙"));
SET_FIELD(pTable, _T("fill"), 0);
SET_FIELD(pTable, _T("color"), 4);
SET_FIELD(pTable, _T("priority"), 3);
SET_FIELD(pTable, _T("lweight"), 0);
pTable->AppendEnd();
adsout << _T("OK!");
}
else
{
adsout << _T("Fail!");
}
return RTNORM;
}