Files
envi-code/SourceCode/Code2026/CoreLibrary/AcDbX3dSolid.cpp
T
2026-09-28 15:28:50 +08:00

5597 lines
121 KiB
C++

#include "stdafx.h"
#include <math.h>
#include "MFCDbDwgFiler.h"
#include "AcDbX3dSolid.h"
#include "AecDbEarthWorm.h"
#include "AecDbPortRoom.h"
#include "AecDb3dRoadAxisLine.h"
#include "AecDbEwPipeBase.h"
#include "AcGiExplodeDraw.h"
#include <vector>
#include <algorithm>
#include "KTCADUtilityEx.h"
#include "AecDbShEarthWorm.h"
#include "dbextrudedsurf.h"
#include "GiDrawUtility.h"
#include "CoreTools.h"
#include "geometry2json.h"
#include "SubDMesh.h"
#pragma pack(1)
#define REGION_SPLITE _T("@region@")
extern Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt,AcDbDatabase* pDb = NULL,bool bClose = true);
extern void transfromRegion(AcDbRegion *pRegion, const AcGePoint3d &ptOnRegion, const AcGeVector3d &vtNormal, const AcGePoint3d &ptOnPlan);
Adesk::UInt32 AcDbX3dSolid::kCurrentVersionNumber = 4;
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;
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_PTR(pEnt);
}
}
}
namespace
{
AcGePoint3d getRegionOrigin(AcDbRegion *pReg)
{
if (!pReg) return AcGePoint3d::kOrigin;
AcDbExtents ext;
pReg->getGeomExtents(ext);
return CoreTools::MidPt(ext.minPoint(), ext.maxPoint());
}
// 绘制池底四角素砼 三棱锥体
bool triangularPyramid2Buffer(
const AcGePoint3d &pt0 // 锥顶点
, const AcGePoint3d &pt1 // 三角面第一点
, const AcGePoint3d &pt2 // 三角面第二点
, const AcGePoint3d &pt3 // 三角面第三点
, void *&pOutBuffer
, Adesk::UInt32 &nOutLen )
{
nOutLen = 4 * sizeof(SubDMesh::Pnt);
byte *pBuffer = new byte[nOutLen];
::memset(pBuffer, 0, nOutLen);
SubDMesh::Pnt pnts[4] = { 0, };
SubDMesh::fillPnt(pt0, pnts[0]);
SubDMesh::fillPnt(pt1, pnts[1]);
SubDMesh::fillPnt(pt2, pnts[2]);
SubDMesh::fillPnt(pt3, pnts[3]);
::memcpy(pBuffer,pnts, nOutLen);
pOutBuffer = pBuffer;
return true;
}
bool buffer2TriangularPyramid(
AcGePoint3d &pt0
, AcGePoint3d &pt1
, AcGePoint3d &pt2
, AcGePoint3d &pt3
, void *pBuffer )
{
if (!pBuffer) return false;
SubDMesh::Pnt pnts[4] = { 0, };
::memcpy(pnts, pBuffer, 4 * sizeof(SubDMesh::Pnt));
SubDMesh::fillPt(pnts[0], pt0);
SubDMesh::fillPt(pnts[1], pt1);
SubDMesh::fillPt(pnts[2], pt2);
SubDMesh::fillPt(pnts[3], pt3);
return true;
}
}
bool FormatScriptFromSection(CString& sScr,STSection* pSection)
{
CString sFullPath = FilePath::GetSysDir();
sFullPath.MakeLower();
sFullPath += _T("\\DGJM.sat");
CString sRegionScrp = _T("");
CString sLine;
AcDbVoidPtrArray arBodyPtrs;
arBodyPtrs.append(pSection->pReg);
if ( Acad::eOk == AcDbBody::acisOut(sFullPath,arBodyPtrs) )
{
CFile file;
if (file.Open(sFullPath,CFile::modeRead))
{
ULONGLONG dwFileLength = file.GetLength();
char* pszTxt = new char[dwFileLength];
file.Read(pszTxt,(UINT)dwFileLength);
sRegionScrp = pszTxt;
delete [] pszTxt;
file.Close();
}
}
CString sElPt;
sElPt.Format(_T("<ELAGN:%.6f,%.6f,%.6f,%.6f,%.6f,%.6f>"),pSection->pt.x,pSection->pt.y,pSection->dThick[0],pSection->dThick[2],pSection->dThick[3],pSection->dThick[4]);
sRegionScrp += sElPt;
sScr = sRegionScrp;
return true;
}
STSection* FormatSTSectionFromScript(const CString& sScr)
{
CString sFullPath = FilePath::GetSysDir();
sFullPath.MakeLower();
sFullPath += _T("\\DGJM.sat");
CString sScrT;
int nPos = sScr.Find(_T("<ELAGN:"));
if (nPos != -1)
{
sScrT = sScr.Mid(0,nPos);
}
STSection* pSection = new STSection;
CString sX,sY;
CString sPt = sScr.Mid(nPos);
sPt.TrimLeft(_T("<ELAGN:"));
sPt.TrimRight(_T(">"));
nPos = sPt.Find(_T(','));
if (nPos != -1)
{
CStringArray arInfo;
CoreTools::SplitStrintToArray(sPt,arInfo,_T(','));
if (arInfo.GetSize() >= 2)
{
sX = arInfo.GetAt(0);
sY = arInfo.GetAt(1);
pSection->pt.set(_ttof(sX),_ttof(sY),0.0);
if (arInfo.GetSize() >= 6)
{
pSection->dThick[0] = _ttof(arInfo.GetAt(2));
pSection->dThick[1] = _ttof(arInfo.GetAt(3));
pSection->dThick[2] = _ttof(arInfo.GetAt(4));
pSection->dThick[3] = _ttof(arInfo.GetAt(5));
}
}
}
CStdioFile file;
if (file.Open(sFullPath,CFile::modeCreate |CFile::modeWrite ))
{
file.WriteString(sScrT);
file.Close();
}
AcDbVoidPtrArray arBodyPtrs;
if ( Acad::eOk == AcDbBody::acisIn(sFullPath,arBodyPtrs) )
{
if (arBodyPtrs.length() > 0)
{
AcDbEntity* pEnt = (AcDbEntity*)arBodyPtrs.first();
AcDbRegion* pRegion = AcDbRegion::cast(pEnt);
if (pRegion != NULL)
{
pSection->pReg = pRegion;
}
}
}
return pSection;
}
AcDbX3dSolid::AcDbX3dSolid(void)
{
m_ptOrg.set(0,0,0);
m_vtMove.set(0,0,0);
memset(m_dAxisRotats,0,sizeof(double) * MAX_AXISROTATS);
m_pSolidDraw = NULL;
m_pSolid = NULL;
#if ARX > 17
m_pSubDMesh = NULL;
m_pSubDMeshDraw = NULL;
#endif
m_sszPoint2ds = _T("-1");
m_dH = 0.0;
m_dT = 0.0;
m_dW = 0.0;
m_sScr = _T("");
m_dLen = 0.0;
memset(m_fStair,0,sizeof(float) * 3);
m_nSatLen = 0;
m_pSatBuffer = NULL;
m_nKind = 0;
}
AcDbX3dSolid::AcDbX3dSolid(const AcDbX3dSolid& xSolid)
{
m_eType = xSolid.m_eType; //类型
m_vtZ = xSolid.m_vtZ; //放置方向向量
m_arSizes.append(xSolid.m_arSizes); //参数
m_ptOrg = xSolid.m_ptOrg; //中心点
m_sszPoint2ds = xSolid.m_sszPoint2ds;//
m_dH = xSolid.m_dH; //
m_dT = xSolid.m_dT; //
m_dW = xSolid.m_dW; //
m_sScr = xSolid.m_sScr; //管廊段脚本
m_dLen = xSolid.m_dLen;
m_vtLast = xSolid.m_vtLast; //管廊段上向量,管线 其他使用
m_vtNext = xSolid.m_vtNext; //管廊段下向量,管线 其他使用
m_ptFr = xSolid.m_ptFr;
m_ptTo = xSolid.m_ptTo;
m_vtDirx = xSolid.m_vtDirx;
m_vtDirXY = xSolid.m_vtDirXY;
memcpy(m_fStair,xSolid.m_fStair,sizeof(float) * 3);
m_nKind = xSolid.m_nKind; //类型
//变换部分
m_vtMove = xSolid.m_vtMove; //总移动
m_arAxisVector.append(xSolid.m_arAxisVector); //轴向向量
memcpy(m_dAxisRotats,xSolid.m_dAxisRotats,sizeof(double) *MAX_AXISROTATS );
m_nSatLen = xSolid.m_nSatLen;
if (m_nSatLen)
{
m_pSatBuffer = new byte[m_nSatLen];
::memset(m_pSatBuffer, 0, m_nSatLen);
memcpy(m_pSatBuffer, xSolid.m_pSatBuffer, m_nSatLen);
}
m_pSolid = NULL;
m_pSolidDraw = NULL;
#if ARX > 17
m_pSubDMesh = NULL;
m_pSubDMeshDraw = NULL;
#endif
ReCreate();
}
AcDbX3dSolid::~AcDbX3dSolid(void)
{
if (m_pSolidDraw != NULL)
{
m_pSolidDraw->erase();
m_pSolidDraw->close();
DELETE_PTR(m_pSolidDraw);
}
if (m_pSolid != NULL)
{
m_pSolid->erase();
m_pSolid->close();
DELETE_PTR(m_pSolid);
}
#if ARX > 17
if (m_pSubDMesh != NULL)
{
m_pSubDMesh->erase();
m_pSubDMesh->close();
DELETE_PTR(m_pSubDMesh);
}
m_pSubDMesh2Ds.removeAll();
if (m_pSubDMeshDraw != NULL)
{
m_pSubDMeshDraw->erase();
m_pSubDMeshDraw->close();
DELETE_PTR(m_pSubDMeshDraw);
}
#endif
}
bool AcDbX3dSolid::Create(AcDbX3dSolid::Primitive eType,const AcGePoint3d& ptOrg,const AcGeVector3d& vtZ,int n,...)
{
AcArray<double> arSizes;
int i = 0;
double val = 0.0;
va_list vl;
va_start(vl,n);
for ( i = 0; i < n; i++ )
{
val = va_arg(vl,double);
arSizes.append(val);
}
va_end(vl);
m_arSizes.removeAll();
m_arSizes.append(arSizes);
m_vtZ = vtZ;
AcGePoint2d pt;
switch(eType)
{
case AcDbX3dSolid::kBox:
{
if (arSizes.length() >= 3)
{
m_pSolid = new AcDb3dSolid;
if ( Acad::eOk == m_pSolid->createBox(arSizes.at(X),arSizes.at(Y),arSizes.at(Z)) )
{
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
AcGePlane plan(ptOrg,vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
//二维
return true;
}
else
{
DELETE_PTR(m_pSolid);
return false;
}
}
break;
}
case AcDbX3dSolid::kCylinder:
{
if (arSizes.length() >= 2)
{
m_pSolid = new AcDb3dSolid;
if ( Acad::eOk == m_pSolid->createFrustum(arSizes.at(Y),arSizes.at(X),arSizes.at(X),arSizes.at(X)) )
{
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
AcGePlane plan(ptOrg,vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
return true;
}
else
{
DELETE_PTR(m_pSolid);
return false;
}
}
break;
}
case AcDbX3dSolid::kCone:
{
if (arSizes.length() >= 3)
{
m_pSolid = new AcDb3dSolid;
if ( Acad::eOk == m_pSolid->createFrustum(arSizes.at(Z),arSizes.at(X),arSizes.at(X),arSizes.at(Y)) )
{
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
AcGePlane plan(ptOrg,vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
return true;
}
else
{
DELETE_PTR(m_pSolid);
return false;
}
}
break;
}
case AcDbX3dSolid::kQPyramid://四方台
{
//LxWxHxAng
if (arSizes.length() >= 4)
{
AcDbLine ln1,ln2,ln3,ln4;
AcGePoint3d pt1,pt2;
pt1.set(-arSizes.at(X) / 2.0,-arSizes.at(Y) / 2.0,0);
pt2.set(arSizes.at(X) / 2.0,-arSizes.at(Y) / 2.0,0);
ln1.setStartPoint(pt1);
ln1.setEndPoint(pt2);
pt1 = pt2;
double dX = arSizes.at(Z) * cos(arSizes.last() ) / sin(arSizes.last());
pt2.x -= dX;
pt2.z += arSizes.at(Z);
ln2.setStartPoint(pt1);
ln2.setEndPoint(pt2);
pt1 = pt2;
pt2.x -= (arSizes.at(X) - dX * 2.0 );
ln3.setStartPoint(pt1);
ln3.setEndPoint(pt2);
pt1 = pt2;
pt2.set(-arSizes.at(X) / 2.0,-arSizes.at(Y) / 2.0,0);
ln4.setStartPoint(pt1);
ln4.setEndPoint(pt2);
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
arCurPtrs.append(&ln1);
arCurPtrs.append(&ln2);
arCurPtrs.append(&ln3);
arCurPtrs.append(&ln4);
AcDbRegion* pRegion = NULL;
if ( Acad::eOk == AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs) )
{
pRegion = (AcDbRegion*)arRegPtrs.first();
m_pSolid = new AcDb3dSolid;
pt1.set(0,-arSizes.at(Y) / 2.0,0);
pt2.set(0,arSizes.at(Y) / 2.0,0);
AcDbLine lnPath(pt1,pt2);
if (pt1.distanceTo(pt2) > 1.e-3)//大于1mm
{
if ( Acad::eOk != m_pSolid->extrudeAlongPath(pRegion,&lnPath) )
{
DELETE_PTR(m_pSolid);
DELETE_PTR(pRegion);
return false;
}
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
AcGePlane plan(ptOrg,vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
DELETE_PTR(pRegion);
return true;
}
}
}
break;
}
case AcDbX3dSolid::kWPyramid://LxWxHxAng1XAng2
{
if (arSizes.length() >= 5)
{
AcDbLine ln1,ln2,ln3,ln4;
AcGePoint3d pt1,pt2;
pt1.set(-arSizes.at(X) / 2.0,-arSizes.at(Y) / 2.0,0);
pt2.set(arSizes.at(X) / 2.0,-arSizes.at(Y) / 2.0,0);
ln1.setStartPoint(pt1);
ln1.setEndPoint(pt2);
double dA1 = arSizes.at(arSizes.length() - 2);
double dA2 = arSizes.last();
pt1 = pt2;
double dX = arSizes.at(Z) * cos(dA1 ) / sin(dA1);
double dX2 = arSizes.at(Z) * cos(dA2 ) / sin(dA2);
pt2.x -= dX2;
pt2.z += arSizes.at(Z);
ln2.setStartPoint(pt1);
ln2.setEndPoint(pt2);
pt1 = pt2;
pt2.x -= (arSizes.at(X) - dX - dX2 );
ln3.setStartPoint(pt1);
ln3.setEndPoint(pt2);
pt1 = pt2;
pt2.set(-arSizes.at(X) / 2.0,-arSizes.at(Y) / 2.0,0);
ln4.setStartPoint(pt1);
ln4.setEndPoint(pt2);
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
arCurPtrs.append(&ln1);
arCurPtrs.append(&ln2);
arCurPtrs.append(&ln3);
arCurPtrs.append(&ln4);
AcDbRegion* pRegion = NULL;
if ( Acad::eOk == AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs) )
{
pRegion = (AcDbRegion*)arRegPtrs.first();
m_pSolid = new AcDb3dSolid;
pt1.set(0,-arSizes.at(Y) / 2.0,0);
pt2.set(0,arSizes.at(Y) / 2.0,0);
AcDbLine lnPath(pt1,pt2);
if (pt1.distanceTo(pt2) > 1.e-3)//大于1mm
{
if ( Acad::eOk != m_pSolid->extrudeAlongPath(pRegion,&lnPath) )
{
DELETE_PTR(m_pSolid);
DELETE_PTR(pRegion);
return false;
}
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
AcGePlane plan(ptOrg,vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
DELETE_PTR(pRegion);
return true;
}
}
}
break;
}
case AcDbX3dSolid::kRectTube:
{
//L,W,t,H 长宽,厚度
if (arSizes.length() >= 4)
{
m_pSolid = new AcDb3dSolid;
if ( Acad::eOk == m_pSolid->createBox(arSizes.at(X),arSizes.at(Y),arSizes.at(3)) )
{
AcDb3dSolid* pSolidI = new AcDb3dSolid;
if ( Acad::eOk == pSolidI->createBox(arSizes.at(X) - 2 * arSizes.at(Z),arSizes.at(Y) - 2 * arSizes.at(Z),arSizes.at(3)) )
{
if (Acad::eOk == m_pSolid->booleanOper(AcDb::kBoolSubtract,pSolidI) )
{
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
AcGePlane plan(ptOrg,vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
return true;
}
else
{
DELETE_PTR(m_pSolid);
DELETE_PTR(pSolidI);
return false;
}
}
else
{
DELETE_PTR(m_pSolid);
DELETE_PTR(pSolidI);
return false;
}
}
else
{
DELETE_PTR(m_pSolid);
return false;
}
}
break;
}
case AcDbX3dSolid::kPipe:
{
//r,t,H
if (arSizes.length() >= 3)
{
AcGeVector3d vtZ1 = vtZ;
vtZ1.normalize();
AcGePoint3d ptCen = ptOrg - vtZ1 * 0.5 * arSizes.at(Z);
AcDbCircle cir1;
cir1.setCenter(ptCen);
cir1.setRadius(arSizes.at(X));
cir1.setNormal(vtZ1);
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
arCurPtrs.append(&cir1);
Acad::ErrorStatus es = AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs);
if (arRegPtrs.length() == 0)
{
return false;
}
AcDbRegion* pRegI = (AcDbRegion*)arRegPtrs.first();
if (pRegI != NULL)
{
arRegPtrs.removeAll();
cir1.setRadius(arSizes.at(X) - arSizes.at(Y));
es = AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs);
if (arRegPtrs.length() == 0)
{
return false;
}
AcDbRegion* pRegII = (AcDbRegion*)arRegPtrs.first();
es = pRegI->booleanOper(AcDb::kBoolSubtract,pRegII);
AcDbLine ln(ptCen,ptCen + vtZ1 * arSizes.at(Z));
m_pSolid = new AcDb3dSolid;
es = m_pSolid->extrudeAlongPath(pRegI,&ln);
if (es == Acad::eOk)
{
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg = ptOrg;
}
else
{
DELETE_PTR(m_pSolid);
}
DELETE_PTR(pRegI);
}
}
break;
}
case kTorus:
{
if (arSizes.length() >= 2)
{
m_pSolid = new AcDb3dSolid;
if ( Acad::eOk == m_pSolid->createTorus(arSizes.at(X),arSizes.at(Y) ) )
{
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
AcGePlane plan(ptOrg,vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
return true;
}
else
{
DELETE_PTR(m_pSolid);
return false;
}
}
break;
}
case kDrum:
{
if (arSizes.length() < 5) return false;
double dL1(arSizes[1]), dL2(arSizes[2]), dR(arSizes[0]), dSAngle(arSizes[3]), dEAngle(arSizes[4]);
double alpha1(asin(dL1/dR)), alpha2(asin(dL2/dR));
double dD1(dR * cos(alpha1)), dD2(dR * cos(alpha2));
AcDbVoidPtrArray ar, arRegs;
AcGePoint3d pt(AcGePoint3d::kOrigin)
, pt1(pt + AcGeVector3d::kZAxis * dL1)
, pt2(pt - AcGeVector3d::kZAxis * dL2)
, pt3(pt2 + AcGeVector3d::kXAxis * dD2)
, pt4(pt1 + AcGeVector3d::kXAxis * dD1);
AcDbLine ln12(pt1, pt2);
AcDbLine ln14(pt1, pt4);
AcDbLine ln23(pt2, pt3);
AcDbArc arc(pt, -AcGeVector3d::kYAxis, dR, 2 * PI - alpha2, alpha1);
ar.append(&ln12);
ar.append(&ln14);
ar.append(&ln23);
ar.append(&arc);
if (AcDbRegion::createFromCurves(ar, arRegs) != Acad::eOk)
{
for (int i = 0; i < ar.length(); ++i)
{
//CoreTools::AddToModelSpace((AcDbEntity*)(((AcDbEntity*)ar[i])->clone()));
}
deleteArrayVoidPtrs< AcDbEntity>(arRegs);
return false;
}
AcDbRegion *pReg((AcDbRegion*)((AcDbRegion*)arRegs[0])->clone());
deleteArrayVoidPtrs< AcDbEntity>(arRegs);
AcDbRevolveOptions op;
m_pSolid = new AcDb3dSolid;
if (m_pSolid->createRevolvedSolid(pReg, pt2, AcGeVector3d::kZAxis, (dEAngle - dSAngle), dSAngle, op) != Acad::eOk)
{
//CoreTools::AddToModelSpace((AcDbEntity*)(pReg->clone()));
DELETE_PTR(pReg);
DELETE_PTR(m_pSolid);
return false;
}
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0, 0, 0);
AcGePlane plan(ptOrg, vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0; i < m_arAxisVector.length(); i++)
{
AcGeVector3d &vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
DELETE_PTR(pReg);
return true;
}
break;
case kSpere:
{
if (arSizes.length() < 1) return false;
m_pSolid = new AcDb3dSolid;
if (m_pSolid->createSphere(arSizes[0]) != Acad::eOk)
{
DELETE_PTR(m_pSolid);
return false;
}
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0, 0, 0);
AcGePlane plan(ptOrg, vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0; i < m_arAxisVector.length(); i++)
{
AcGeVector3d &vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
return true;
}
break;
case kWedge:
{
// 3个double
if (arSizes.length() < 3) return false;
double dA(arSizes.at(0)), dB(arSizes.at(1)), dT(arSizes.at(2));
m_pSolid = new AcDb3dSolid;
if (m_pSolid->createWedge(dA, dB, dT) != Acad::eOk)
{
DELETE_PTR(m_pSolid);
return false;
}
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0, 0, 0);
AcGePlane plan(ptOrg, vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0; i < m_arAxisVector.length(); i++)
{
AcGeVector3d &vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
return true;
}
break;
case kPyramid:
{
if (arSizes.length() < 6) return false;
double dTx(arSizes[0]), dTy(arSizes[1]), dBx(arSizes[2]), dBy(arSizes[3]), dH(arSizes[4]), dF(arSizes[5]);
m_pSolid = (AcDb3dSolid*)GiDrawUtility::DrawPyramid(AcGePoint3d::kOrigin , AcGeVector3d::kZAxis
, dTx, dTy, dBx, dBy, dH, dF);
if (!m_pSolid)
{
DELETE_PTR(m_pSolid);
return false;
}
m_eType = eType;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0, 0, 0);
AcGePlane plan(ptOrg, vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0; i < m_arAxisVector.length(); i++)
{
AcGeVector3d &vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptOrg;
return true;
}
break;
default:
break;
}
return false;
}
bool AcDbX3dSolid::CreateFrom3JS(double dUnitScale
, const AcGeVector3d &vtMove
, const AcGePoint3dArray & pts2d
, const AcGePoint3dArray & pts
, const AcArray<Adesk::Int32>& faces)
{
#if ARX > 17
m_eType = kFrom3JS;
m_nSatLen = 0;
if (m_pSatBuffer)
delete[] m_pSatBuffer;
m_pSubDMesh = new AcDbSubDMesh;
if (m_pSubDMesh->setSubDMesh(pts, faces, 0) != Acad::eOk)
{
DELETE_PTR(m_pSubDMesh);
return false;
}
m_dH = dUnitScale;
//外部默认毫米单位->米单位
AcGeMatrix3d xScale;
xScale.setToScaling(dUnitScale);
m_pSubDMesh->transformBy(xScale);
// 先移动
AcGeMatrix3d mat;
mat.setToTranslation(vtMove);
m_pSubDMesh->transformBy(mat);
AcGePoint3dArray _ps;
m_pSubDMesh->getVertices(_ps);
AcGePoint3dArray _ps2d(pts2d);
for (int i = 0; i < _ps2d.length(); ++i)
{
_ps2d[i].transformBy(xScale);
_ps2d[i].transformBy(mat);
}
m_pSubDMesh2Ds.removeAll();
for (int i = 0; i < _ps2d.length() - 1; i += 2)
m_pSubDMesh2Ds.append(AcGeLineSeg3d(_ps2d[i], _ps2d[i + 1]));
return SubDMesh::subDMesh2Buffer(faces, _ps, _ps2d, m_pSatBuffer, m_nSatLen);
#endif
return false;
}
#if ARX > 17
void AcDbX3dSolid::UpdateSubDMeshData()
{
m_nSatLen = 0;
if (m_pSatBuffer)
delete[] m_pSatBuffer;
if (!m_pSubDMesh || m_pSubDMesh2Ds.isEmpty()) return;
AcArray<Adesk::Int32> faces;
m_pSubDMesh->getFaceArray(faces);
AcGePoint3dArray pts, pts2d;
m_pSubDMesh->getVertices(pts);
for (size_t i = 0; i < m_pSubDMesh2Ds.length(); ++i)
{
AcGeLineSeg3d &ln(m_pSubDMesh2Ds[(int)i]);
pts2d.append(ln.startPoint());
pts2d.append(ln.endPoint());
}
SubDMesh::subDMesh2Buffer(faces, pts, pts2d, m_pSatBuffer, m_nSatLen);
}
bool AcDbX3dSolid::CreateSubDMeshByMemory()
{
if (!m_nSatLen || !m_pSatBuffer || m_pSubDMesh) return false;
AcGePoint3dArray pts(0), pts2d(0);
AcArray<Adesk::Int32> faces(0);
if (!SubDMesh::Buffer2SubDMesh(m_pSatBuffer, m_nSatLen, faces, pts, pts2d)) return false;
m_pSubDMesh = new AcDbSubDMesh;
if (m_pSubDMesh->setSubDMesh(pts, faces, 0) != Acad::eOk)
{
DELETE_PTR(m_pSubDMesh);
return false;
}
m_pSubDMesh2Ds.removeAll();
for (int i = 0; i < pts2d.length() - 1; i += 2)
{
m_pSubDMesh2Ds.append(AcGeLineSeg3d(pts2d[i], pts2d[i + 1]));
}
return true;
}
#endif
bool AcDbX3dSolid::CreateExtrude(const AcGePoint3d& ptOrg,const AcGeVector3d& vtZ,LPCTSTR pszPoint2ds,double dH,double dT,BOOL bOpenTop)
{
if (pszPoint2ds == NULL)
return false;
m_sszPoint2ds = pszPoint2ds;
m_dH = dH;
m_dT = dT;
m_vtZ = vtZ;
m_nKind = bOpenTop;
CString sPlane,sTemp;
CString sAll = pszPoint2ds;
int nPos = sAll.Find(_T("plane="));
if (nPos != -1)
{
sPlane = sAll.Mid(nPos);
sTemp = sAll.Mid(0,nPos);
sAll = sTemp;
}
CStringArray arXYs;
CoreTools::SplitStrintToArray(sAll,arXYs,_T(','));
CString sLast = _T("");
if (arXYs.GetSize() > 0)
{
sLast = arXYs.GetAt(arXYs.GetSize() - 1);
if (sLast.Find(_T('[')) != -1)
{
arXYs.RemoveAt(arXYs.GetSize() - 1);
sLast.TrimLeft(_T('['));
sLast.TrimRight(_T(']'));
}
}
CString sX,sYB,sBulge,sY;
double dBulge = 0.0;
int nFind = -1;
AcGePoint2d pt;
AcDbPolyline pl;
pl.setNormal(vtZ);
for (int i = 0;i < arXYs.GetSize() / 2 ;i++)
{
sX = arXYs.GetAt(2 * i);
sYB = arXYs.GetAt(2 * i + 1);
sY = sYB;
dBulge = 0.0;
nFind = sYB.Find( _T('@') );
if (nFind != -1)
{
sBulge = sYB.Mid(nFind + 1);
dBulge = _ttof(sBulge);
sY = sYB.Mid(0,nFind);
}
pt.set(_ttof(sX),_ttof(sY));
pl.addVertexAt(i,pt,dBulge);
}
AcGePlane plan;
plan.set(ptOrg,vtZ);
AcGePoint3d ptOnPlan;
ptOnPlan = plan.closestPointTo(AcGePoint3d::kOrigin);
//vtOrg bug 但不能修改,影响以前的造族成果
AcGeVector3d vtOrg = AcGePoint3d::kOrigin - ptOnPlan;
double dEl = vtOrg.length();
if (vtOrg.dotProduct(vtZ) < 1.e-10)//<0
dEl *= -1.0;
AcGeVector3d vtNorm = vtZ;
if (!sLast.IsEmpty())
{
CStringArray arValsT;
CoreTools::SplitStrintToArray(sLast, arValsT, _T(';'));
if (arValsT.GetSize() >= 4)
{
dEl = _ttof(arValsT.GetAt(0));
vtNorm.set(_ttof(arValsT.GetAt(1)), _ttof(arValsT.GetAt(2)), _ttof(arValsT.GetAt(3)));
}
}
if (!sPlane.IsEmpty())
{
sPlane.TrimLeft(_T("plane="));
sPlane.TrimLeft(_T('('));
sPlane.TrimRight(_T(')'));
CStringArray arVals;
CoreTools::SplitStrintToArray(sPlane,arVals,_T(','));
if (arVals.GetSize() >= 4)
{
vtNorm.set(_ttof(arVals.GetAt(0)),_ttof(arVals.GetAt(1)),_ttof(arVals.GetAt(2)));
dEl = _ttof(arVals.GetAt(3));
pl.setNormal(vtNorm);
pl.setElevation(dEl);//???
pl.setClosed(Adesk::kTrue);
}
}
else
{
pl.setElevation(dEl);//???
pl.setNormal(vtNorm);
pl.setClosed(Adesk::kTrue);
}
AcDbVoidPtrArray arPls;
AcDbPolyline* pPlI1 = NULL;
AcDbPolyline* pPlI2 = NULL;
AcDbPolyline* pPlI = NULL;
if (dT > 1.e-6)
{
pl.getOffsetCurves(dT * -1.0,arPls);
if (arPls.length() > 0)
{
pPlI1 = (AcDbPolyline*)arPls.first();
pPlI1->setClosed(Adesk::kTrue);
}
arPls.removeAll();
pl.getOffsetCurves(dT * 1.0,arPls);
if (arPls.length() > 0)
{
pPlI2 = (AcDbPolyline*)arPls.first();
pPlI2->setClosed(Adesk::kTrue);
}
if (pPlI1 == NULL || pPlI2 == NULL)
{
//acedAlert(_T("选择的房子外轮廓线不支持偏移一个墙厚,请用poly命令重新绘制轮廓线!"));
acedAlert(_T("内部计算闭合线偏移失败!"));
return false;
}
double dAr1 = 0.0,dAr2 = 0.0;
pPlI1->getArea(dAr1);
pPlI2->getArea(dAr2);
if (dAr1 > dAr2)
{
pPlI = pPlI2;
DELETE_PTR(pPlI1);
}
else
{
pPlI = pPlI1;
DELETE_PTR(pPlI2);
}
if (pPlI == NULL)
{
acedAlert(_T("内部计算闭合线偏移失败!"));
return false;
}
}
AcDbVoidPtrArray arPlO,arRegPtrs;
arPlO.append(&pl);
Acad::ErrorStatus es1,es2;
if ( Acad::eOk == AcDbRegion::createFromCurves(arPlO,arRegPtrs) )
{
if (pPlI != NULL)
{
arPlO.removeAll();
arPlO.append(pPlI);
if ( Acad::eOk == AcDbRegion::createFromCurves(arPlO,arRegPtrs) )
{
if (arRegPtrs.length() >= 2)
{
AcDbRegion* pRegO = (AcDbRegion* )arRegPtrs.first();
AcDbRegion* pRegI = (AcDbRegion* )arRegPtrs.last();
AcDbLine ln;
AcGePoint3d ptEnd;
ln.setStartPoint( ptOrg );
ptEnd = ptOrg + vtZ * dH;
ln.setEndPoint( ptEnd );
AcDb3dSolid* pSolidO = new AcDb3dSolid;
es1 = pSolidO->extrudeAlongPath(pRegO,&ln);
if (bOpenTop)
{
ptEnd = ptOrg + vtZ * dH;
}
else
{
ptEnd = ptOrg + vtZ * (dH - dT);
}
ln.setEndPoint(ptEnd);
AcDb3dSolid* pSolidI = new AcDb3dSolid;
es2 = pSolidI->extrudeAlongPath(pRegI,&ln);
if ( es1 == Acad::eOk && es2 == Acad::eOk)
{
if (Acad::eOk == ( es1 = pSolidO->booleanOper(AcDb::kBoolSubtract,pSolidI) ) )
{
m_pSolid = pSolidO;
m_eType = AcDbX3dSolid::kExtrude;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg = ptOrg;
DELETE_PTR(pPlI);
DELETE_PTR(pRegI);
DELETE_PTR(pRegO);
return true;
}
}
DELETE_PTR(pRegI);
DELETE_PTR(pRegO);
}
}
DELETE_PTR(pPlI);
}
else
{
if (arRegPtrs.length() == 1)
{
AcDbRegion* pRegO = (AcDbRegion* )arRegPtrs.first();
AcDbLine ln;
AcGePoint3d ptEnd;
ln.setStartPoint( ptOrg );
ptEnd = ptOrg + vtZ * dH;
ln.setEndPoint( ptEnd );
AcDb3dSolid* pSolidO = new AcDb3dSolid;
es1 = pSolidO->extrudeAlongPath(pRegO,&ln);
//TEST
/*AcDb3dSolid* pCln = (AcDb3dSolid* )pSolidO->clone();
pCln->setColorIndex(1);
AddToModelSpace(pCln);
*/
m_pSolid = pSolidO;
m_eType = AcDbX3dSolid::kExtrude;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg = ptOrg;
DELETE_PTR(pRegO);
return true;
}
}
}
return false;
}
bool AcDbX3dSolid::CreateExtrude(const AcDbRegion* pRegion,const AcDbLine& lnPath,double dTapAngle/* = 0.0*/)
{
if (pRegion == NULL)
return false;
Acad::ErrorStatus es;
AcDb3dSolid* pSolid = new AcDb3dSolid;
AcDbRegion *pReg((AcDbRegion*)pRegion->clone());
if (Acad::eOk == (es = pSolid->extrudeAlongPath(pReg, &lnPath, dTapAngle)))
{
DELETE_PTR(m_pSolid);
m_pSolid = pSolid;
m_ptFr = lnPath.startPoint();
m_ptTo = lnPath.endPoint();
m_dH = m_ptFr.distanceTo(m_ptTo);
m_vtZ = (m_ptTo - m_ptFr).normalize();
m_dW = dTapAngle;
m_eType = AcDbX3dSolid::kExtrude2;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg = m_ptFr;
CoreTools::RegionToString(pReg,m_sScr);
}
else
{
//#ifdef _DEBUG_WAS_DEFINED
// CoreTools::CloneAndAddToModelSpace(pRegion);
// CoreTools::CloneAndAddToModelSpace(&lnPath);
//#endif
DELETE_PTR(pSolid);
}
DELETE_PTR(pReg);
if (pSolid) return true;
return false;
}
bool AcDbX3dSolid::CreateConePipe(const AcDbRegion* pRegionOut,const AcDbRegion* pRegionIn,const AcDbLine& lnPath,double dTapAngle,double dThick)
{
if (pRegionOut == NULL || pRegionIn == NULL)
return false;
// AddToModelSpace((AcDbEntity*)pRegionOut->clone());
// AddToModelSpace((AcDbEntity*)lnPath.clone());
Acad::ErrorStatus es;
AcDb3dSolid* pSolid = new AcDb3dSolid;
if ( Acad::eOk == (es = pSolid->extrudeAlongPath(pRegionOut,&lnPath,dTapAngle) ) )
{
if (m_pSolid != NULL)
delete m_pSolid;
m_pSolid = NULL;
AcGeVector3d vtDir = lnPath.endPoint() - lnPath.startPoint();
double dLen = vtDir.length();
vtDir.normalize();
AcGePoint3d ptTo = lnPath.startPoint() + vtDir * (dLen - dThick);
AcDbLine ln;
ln.setStartPoint(lnPath.startPoint());
ln.setEndPoint(ptTo);
AcDb3dSolid* pSolidIn = new AcDb3dSolid;
if ( Acad::eOk == (es = pSolidIn->extrudeAlongPath(pRegionIn,&ln,dTapAngle) ) )
{
if ( Acad::eOk == (es = pSolid->booleanOper(AcDb::kBoolSubtract,pSolidIn) ) )
{
m_pSolid = pSolid;
m_ptFr = lnPath.startPoint();
m_ptTo = lnPath.endPoint();
m_dH = m_ptFr.distanceTo(m_ptTo);
m_vtZ = m_ptTo - m_ptFr;
m_dW = dTapAngle;
m_dT = dThick;
m_eType = AcDbX3dSolid::kConePipe;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg = m_ptFr;
CString sScr1;
CoreTools::RegionToString(pRegionOut,sScr1);
CString sScr2;
CoreTools::RegionToString(pRegionIn,sScr2);
m_sScr.Format(_T("%s|%s"),sScr1,sScr2);
return true;
}
else
{
delete pSolidIn;
}
}
}
delete pSolid;
return false;
}
bool AcDbX3dSolid::CreateFenceExtrude(const AcGePoint3d& ptOrg,const AcGePoint3d* pPoints,int nPoints,const AcGeVector3d& vtZ,double dH)
{
if (pPoints == NULL)
return false;
if (nPoints <= 2)
return false;
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
AcDbLine* pLn = NULL;
for (int i = 0;i < nPoints - 1;i++)
{
pLn = new AcDbLine;
pLn->setStartPoint(pPoints[i]);
pLn->setEndPoint(pPoints[i+1]);
arCurPtrs.append(pLn);
}
if (pPoints[nPoints - 1].distanceTo(pPoints[0]) > 1.e-6)
{
pLn = new AcDbLine;
pLn->setStartPoint(pPoints[nPoints - 1]);
pLn->setEndPoint(pPoints[0]);
arCurPtrs.append(pLn);
}
bool bSuccess = false;
Acad::ErrorStatus es;
if ( Acad::eOk == ( es = AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs) ) )
{
if ( !arRegPtrs.isEmpty())
{
AcDbRegion* pRegion = NULL;
pRegion = (AcDbRegion*)arRegPtrs.first();
if (pRegion != NULL)
{
AcDbLine lnPath;
lnPath.setStartPoint(pPoints[0]);
lnPath.setEndPoint(pPoints[0] + vtZ * dH);
AcDb3dSolid* pSolid = new AcDb3dSolid;
if ( Acad::eOk == (es = pSolid->extrudeAlongPath(pRegion,&lnPath) ) )
{
if (m_pSolid != NULL)
delete m_pSolid;
m_dH = dH;
m_vtZ = vtZ;
m_pSolid = pSolid;
m_eType = AcDbX3dSolid::kFenceExtrude;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg = ptOrg;
m_nSatLen = sizeof(AcGePoint3d) * nPoints;
m_pSatBuffer = new AcGePoint3d[nPoints];
memcpy(m_pSatBuffer,pPoints,m_nSatLen);
}
delete pRegion;
}
}
}
FreeBuffer(0,arCurPtrs);
return bSuccess;
}
bool AcDbX3dSolid::CreateTriangularPyramid(const AcGePoint3d & pt0
, const AcGePoint3d & pt1
, const AcGePoint3d & pt2
, const AcGePoint3d & pt3)
{
// 先把数据保存上
triangularPyramid2Buffer(pt0, pt1, pt2, pt3, m_pSatBuffer, m_nSatLen);
AcGePlane plan(pt1, pt2, pt3);
AcGePoint3d ptClosest = plan.closestPointTo(pt0);
AcDbCircle cir(pt0, AcGeVector3d(ptClosest - pt0), .0001);
AcDbRegion *pReg1 = CoreTools::createRegion(&cir);
if (!pReg1) return false;
AcDbLine line1(pt1, pt2);
AcDbLine line2(pt2, pt3);
AcDbLine line3(pt3, pt1);
AcDbVoidPtrArray ar;
ar.append(&line1);
ar.append(&line2);
ar.append(&line3);
AcDbRegion *pReg2 = CoreTools::createRegion(ar);
if (!pReg2) return false;
AcDbLine tmpLine(pt0, ptClosest);
AcDbEntity *pEnt = GiDrawUtility::DrawLoft(pReg1, pReg2, &tmpLine);
if (pEnt)
{
m_pSolid = (AcDb3dSolid*)pEnt;
m_eType = kTriPyramid;
}
DELETE_PTR(pReg1);
DELETE_PTR(pReg2);
return false;
}
AcDb3dPolyline* create3DPolyline(const AcGePoint3d *pBuffer, int len)
{
AcDb3dPolyline *p = new AcDb3dPolyline;
if (!p) return NULL;
for (int i = 0; i < len; ++i)
{
AcDb3dPolylineVertex *pV = new AcDb3dPolylineVertex(pBuffer[i]);
p->appendVertex(pV);
}
return p;
}
AcDb3dSolid* AcDbX3dSolid::CreateLoftSolid(const AcGePoint3d& ptOrg,AcDbPolyline& pl,int nShape,double dW,double dH,double dT,double dT2,double dT3,int nF,double dE0,double dE1,AcGeVector3d& vtCut1,AcGeVector3d& vtCut2)
{
AcArray<AcDbEntity*> crossSectionCurves,guideCurves;
AcDb3dSolid* pSolidAll = NULL;
AcDbEntity* pPath = NULL;
AcGeVector3d vtCut;
AcGePoint3dArray arFitPts;
AcDbCurve* pPl = &pl;
if (pPl != NULL)
{
double dAng = 0.0,dWbk = dW,dTBk = dT;
double dSta = 0.0,dEnd = 0.0,dStep = 0.0,dPam = 0.0,dEl = 0.0;
pPl->getStartParam(dSta);
pPl->getEndParam(dEnd);
dStep = (dEnd - dSta) / nF;
double dElStep = (dE1 - dE0) / nF;
AcGePoint3d ptSta;
pl.getStartPoint(ptSta);
if (ptSta.distanceTo(ptOrg) < 1.e-2)
{
}
else
{
dElStep = (dE0 - dE1) / nF;
}
AcGePoint3d ptGe[5],ptOn;
for (int i = 0;i <= nF;i++)
{
dPam = dSta + i * dStep;
pPl->getPointAtParam(dPam,ptOn);
dEl = dE0 + i * dElStep;
if ( i > 0 && i < nF)
{
dW = dWbk;
dT = dTBk;
pPl->getFirstDeriv(dPam,vtCut);
vtCut.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtCut.normalize();
}
else
{
pPl->getFirstDeriv(dPam,vtCut);
vtCut.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtCut.normalize();
if (i == 0)
{
//有侧宽放大或缩小
dAng = vtCut1.angleTo(vtCut);
if (fabs(cos(dAng)) > 1.e-6)
{
dW = dWbk / fabs( cos(dAng) );
dT = dTBk / fabs( cos(dAng) );
}
vtCut = vtCut1;
vtCut.normalize();
}
else if (i == nF )
{
dAng = vtCut2.angleTo(vtCut);
if (fabs(cos(dAng)) > 1.e-6)
{
dW = dWbk / fabs( cos(dAng) );
dT = dTBk / fabs( cos(dAng) );
}
vtCut = vtCut2;
vtCut.normalize();
}
}
ptGe[0] = ptOn;
ptGe[0].z += dEl;
arFitPts.append(ptGe[0]);
ptGe[0] -= 0.5 * dH * AcGeVector3d::kZAxis;
ptGe[0] += dT2 * AcGeVector3d::kZAxis;//顶部壁厚
ptGe[0] -= 0.5 * dW * vtCut;
ptGe[0] += dT * vtCut;//两侧壁厚
ptGe[1] = ptGe[0];
ptGe[1] += (dH - dT2 - dT3) * AcGeVector3d::kZAxis;
ptGe[2] = ptGe[1];
ptGe[2] += (dW - 2.0 * dT ) * vtCut;
ptGe[3] = ptGe[2];
ptGe[3] -= (dH - dT2 - dT3) * AcGeVector3d::kZAxis;
ptGe[4] = ptGe[0];
if (nShape == 0)
{
AcDbRegion* pReg = AecDbEarthWorm::CreatePolygonRegionOnly(ptGe,5);
if (pReg != NULL)
{
crossSectionCurves.append(pReg);
//TEST
//AddToModelSpace((AcDbEntity*)pReg->clone());
}
}
else
{
AcDbVoidPtrArray arCurPtr,arRegPtr;
if ( i > 0 && i < nF)
{
AcDbCircle* pCir = new AcDbCircle;
pCir->setCenter(arFitPts.last());
pCir->setRadius(0.5 * dW);
AcGeVector3d vtNorm = vtCut;
vtNorm.rotateBy(-PI / 2.0,AcGeVector3d::kZAxis);
pCir->setNormal(vtNorm);
arCurPtr.append(pCir);
}
else//两头可能是椭圆
{
AcGeVector3d vtMaj = vtCut;
vtMaj.normalize();
vtMaj *= dW;
double dRat = dH / dW;
AcGeVector3d vtNorm = vtCut;
vtNorm.rotateBy(-PI / 2.0,AcGeVector3d::kZAxis);
AcDbEllipse* pEl = new AcDbEllipse(arFitPts.last(),vtNorm,vtMaj,dRat);
arCurPtr.append(pEl);
}
AcDbRegion::createFromCurves(arCurPtr,arRegPtr);
if (!arRegPtr.isEmpty())
{
AcDbRegion* pReg = (AcDbRegion*)arRegPtr.first();
crossSectionCurves.append(pReg);
//TEST
//AddToModelSpace((AcDbEntity*)pReg->clone());
}
}
}
if (!crossSectionCurves.isEmpty())
{
AcDbLoftOptions op;
op.setRuled(true);
//AcDbSpline *pGuideSpline = new AcDbSpline(arFitPts);
Acad::ErrorStatus es;
pSolidAll = new AcDb3dSolid;
//if ( Acad::eOk == (es = pSolidAll->createLoftedSolid(crossSectionCurves,guideCurves,pGuideSpline,op) ) )
if (Acad::eOk == (es = pSolidAll->createLoftedSolid(crossSectionCurves, guideCurves, NULL, op)))
{
//pSolidAll->setColorIndex(1);
//AddToModelSpace(pSolidAll);
}
else
{
acutPrintf(_T("\n创建螺旋拉伸体失败,光滑度太密,切面相交:%d"),es);
//DELETE_PTR(pGuideSpline);
for (int k = 0;k < crossSectionCurves.length();k++)
{
pPath = crossSectionCurves.at(k);
DELETE_PTR(pPath);
}
return NULL;
}
if (arFitPts.length() > 0)
{
AcDb3dPolyline* p3dPl = create3DPolyline(arFitPts.asArrayPtr(),arFitPts.length());
if (p3dPl != NULL)
{
p3dPl->setColorIndex(kRed);
//先旋转
AcGeMatrix3d xRote;
for (int ii = 0;ii < m_arAxisVector.length();ii++)
{
if (fabs(m_dAxisRotats[ii]) > 1.e-10)
{
xRote.setToRotation(m_dAxisRotats[ii],m_arAxisVector.at(ii),m_ptOrg);
p3dPl->transformBy(xRote);
}
}
AcGeMatrix3d xMove;
xMove.setToTranslation(m_vtMove);
p3dPl->transformBy(xMove);
//TEST
//AddToModelSpace(p3dPl);
}
}
//DELETE_PTR(pGuideSpline);
for (int k = 0;k < crossSectionCurves.length();k++)
{
pPath = crossSectionCurves.at(k);
DELETE_PTR(pPath);
}
}
}
return pSolidAll;
}
bool AcDbX3dSolid::CreateTydf(const AcGePoint3d &ptPos,
const AcGeVector3d &vtMove,
const double &dTr,
const double &dBx,
const double &dBy,
const double &dH,
const double &dxOffset,
BOOL bIsTfdy)
{
AcDb3dSolid* pSolid = (AcDb3dSolid*)GiDrawUtility::DrawTydf(ptPos,vtMove,dTr,dBx,dBy,dH,dxOffset,bIsTfdy);
if (pSolid != NULL)
{
m_ptOrg = ptPos;
m_vtZ = vtMove;
m_dT = dTr;
m_dW = dBx;
m_dLen = dBy;
m_dH = dH;
m_fStair[0] = (float)dxOffset;
m_eType = kTydf;
m_pSolid = pSolid;
m_nKind = bIsTfdy;
return true;
}
return false;
}
AcDb3dSolid* AcDbX3dSolid::CreatePathSolid(const AcGePoint3d& ptOrg,AcDbPolyline& pl,int nShape,double dW,double dH,double dT,double dT2,double dT3,double dE0,double dE1,AcGeVector3d& vtCut1,AcGeVector3d& vtCut2)
{
AcGePoint3d ptGe[5],ptOn;
pl.getStartPoint(ptOn);
AcGeVector3d vtNorm;
pl.getFirstDeriv(ptOn,vtNorm);
vtNorm.normalize();
AcGeVector3d vtSta = vtNorm;
vtSta.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
ptGe[0] = ptOn;
ptGe[0].z += dE1;
ptGe[0] -= 0.5 * dH * AcGeVector3d::kZAxis;
ptGe[0] += dT2 * AcGeVector3d::kZAxis;//顶部壁厚
ptGe[0] -= 0.5 * dW * vtSta;
ptGe[0] += dT * vtSta;//两侧壁厚
ptGe[1] = ptGe[0];
ptGe[1] += (dH - dT2 - dT3) * AcGeVector3d::kZAxis;
ptGe[2] = ptGe[1];
ptGe[2] += (dW - 2.0 * dT ) * vtSta;
ptGe[3] = ptGe[2];
ptGe[3] -= (dH - dT2 - dT3) * AcGeVector3d::kZAxis;
ptGe[4] = ptGe[0];
AcDbRegion* pReg = NULL;
if (nShape == 0)
{
pReg = AecDbEarthWorm::CreatePolygonRegionOnly(ptGe,5);
if (pReg != NULL)
{
//TEST
//AddToModelSpace((AcDbEntity*)pReg->clone());
}
}
else
{
AcDbVoidPtrArray arCurPtr,arRegPtr;
AcDbCircle* pCir = new AcDbCircle;
pCir->setCenter(ptOn);
pCir->setRadius(0.5 * dW - dT);
pCir->setNormal(vtNorm);
arCurPtr.append(pCir);
AcDbRegion::createFromCurves(arCurPtr,arRegPtr);
if (!arRegPtr.isEmpty())
{
pReg = (AcDbRegion*)arRegPtr.first();
//TEST
//AddToModelSpace((AcDbEntity*)pReg->clone());
}
DELETE_PTR(pCir);
}
AcDb3dSolid* pSolidAll = NULL;
if (pReg != NULL)
{
pSolidAll = new AcDb3dSolid;
if ( Acad::eOk != pSolidAll->extrudeAlongPath(pReg,&pl) )
{
DELETE_PTR(pSolidAll);
return pSolidAll;
}
AcGeVector3d vtNorm1;
AcDb3dSolid* pNegHalfSolid = NULL;
AcGePlane plan;
if (!vtCut1.isZeroLength())
{
vtNorm1 = vtCut1;
vtNorm1.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
if (vtNorm1.dotProduct(vtNorm) < -1.e-10)
vtNorm1.negate();
plan.set(ptOn,vtNorm1);
pSolidAll->getSlice(plan,Adesk::kFalse,pNegHalfSolid);
}
AcGeVector3d vtEnd;
AcGePoint3d ptEnd;
pl.getEndPoint(ptEnd);
pl.getFirstDeriv(ptEnd,vtEnd);
//AcDbRay* pRay = new AcDbRay;
//pRay->setBasePoint(ptEnd);
//pRay->setUnitDir(vtEnd);
//pRay->setColorIndex(kRed);
//AddToModelSpace(pRay);
if (!vtCut2.isZeroLength())
{
vtNorm1 = vtCut2;
vtNorm1.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
if (vtNorm1.dotProduct(vtEnd) > 1.e-10)
vtNorm1.negate();
plan.set(ptEnd,vtNorm1);
pSolidAll->getSlice(plan,Adesk::kFalse,pNegHalfSolid);
}
DELETE_PTR(pReg);
}
return pSolidAll;
}
bool AcDbX3dSolid::CreatePipe(const AcGePoint3d& ptOrg,LPCTSTR pszPath,int nShape,double dW,double dH,double dT,double dT2,double dT3,AcGeVector3d& vtCut1,AcGeVector3d& vtCut2)
{
m_ptOrg = ptOrg;
m_dH = dH;
m_dT = dT;
m_dW = dW;
m_fStair[0] = 0.0f;
m_fStair[1] = 0.0f;
m_nKind = 0;
m_vtLast = vtCut1;
m_vtNext = vtCut2;
m_arSizes.removeAll();
m_arSizes.append(dT2);
m_arSizes.append(dT3);
m_sszPoint2ds.Format(_T("%s@%d"),pszPath,nShape);
m_eType = AcDbX3dSolid::kPathPipe;
CStringArray arXYs;
CoreTools::SplitStrintToArray(pszPath,arXYs,_T(','));
CString sX,sYB,sBulge,sY;
double dBulge = 0.0;
int nFind = -1;
AcGePoint2d pt;
AcDbPolyline pl;
pl.setNormal(AcGeVector3d::kZAxis);
for (int i = 0;i < arXYs.GetSize() / 2 ;i++)
{
sX = arXYs.GetAt(2 * i);
sYB = arXYs.GetAt(2 * i + 1);
sY = sYB;
dBulge = 0.0;
nFind = sYB.Find( _T('@') );
if (nFind != -1)
{
sBulge = sYB.Mid(nFind + 1);
dBulge = _ttof(sBulge);
sY = sYB.Mid(0,nFind);
}
pt.set(_ttof(sX),_ttof(sY));
pl.addVertexAt(i,pt,dBulge);
}
//
AcDb3dSolid* pSolidOutSide = CreatePathSolid(ptOrg,pl,nShape,dW,dH,0,0,0,0.0,0.0,vtCut1,vtCut2);
if (dT > 1.e-3)
{
AcDb3dSolid* pSolidInside = CreatePathSolid(ptOrg,pl,nShape,dW,dH,dT,dT2,dT3,0.0,0.0,vtCut1,vtCut2);
if (pSolidOutSide != NULL && pSolidInside != NULL)
{
Acad::ErrorStatus es;
es = pSolidOutSide->booleanOper(AcDb::kBoolSubtract,pSolidInside);
if (es != Acad::eOk)
{
acutPrintf(_T("\n创建拉伸体失败:%d"),es);
DELETE_PTR(pSolidOutSide);
DELETE_PTR(pSolidInside);
return false;
}
}
}
if (pSolidOutSide != NULL)
{
m_pSolid = pSolidOutSide;
}
return m_pSolid != NULL ? true : false;
}
bool AcDbX3dSolid::CreateSlicePipe(const AcDbRegion* pRegion,const AcDbLine& lnPath,const AcGePoint3d& ptPlanOrg,const AcGeVector3d& vtPlanNormal)
{
m_ptOrg = ptPlanOrg;
m_vtZ = vtPlanNormal;
m_ptFr = lnPath.startPoint();
m_ptTo = lnPath.endPoint();
Acad::ErrorStatus es;
AcDb3dSolid* pSolid = new AcDb3dSolid;
if ( Acad::eOk == (es = pSolid->extrudeAlongPath(pRegion,&lnPath) ) )
{
//TEST
AddToModelSpace((AcDbEntity*)pSolid->clone());
AcGePlane plan;
plan.set(ptPlanOrg,vtPlanNormal);
AcDb3dSolid* pNegHalfSolid = NULL;
es = pSolid->getSlice(plan,Adesk::kFalse,pNegHalfSolid);
if ( Acad::eOk == es )
{
m_pSolid = pSolid;
m_eType = kSlicePipe;
CoreTools::RegionToString(pRegion,m_sScr);
return true;
}
}
return false;
}
//水池用
bool AcDbX3dSolid::CreateIntersect(const AcDbRegion* pRegion,const AcDbLine& lnPath,const AcGePoint3d& ptOrg,AcDbCurve* pFenceCrv,const AcGeVector3d& vtExDir)
{
//投影到方向线上
AcGeVector3d vtDirOnPlan = lnPath.endPoint() - lnPath.startPoint();
AcDb3dSolid *pSolid = new AcDb3dSolid();
Acad::ErrorStatus es = pSolid->extrudeAlongPath(pRegion, &lnPath);
if (es != Acad::eOk)
{
delete pSolid;
acutPrintf(_T("\n%d:拉伸错误。"), es);
return false;
}
//TEST
//AddToModelSpace((AcDbEntity*)pSolid->clone());
double dL = vtDirOnPlan.length();
AcDbLine lnEx;
AcGePoint3d pt1,pt2;
pt1 = ptOrg - vtExDir * dL;
pt2 = ptOrg + vtExDir * dL;
lnEx.setStartPoint(pt1);
lnEx.setEndPoint(pt2);
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
arCurPtrs.append(pFenceCrv);
es = AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs);
if (arRegPtrs.isEmpty())
{
delete pSolid;
acutPrintf(_T("\n%d:围栏面域错误!"), es);
return false;
}
AcDbRegion* pFenceReg = (AcDbRegion*)arRegPtrs.first();
AcGeVector3d vtMove = pt1 - ptOrg;
AcGeMatrix3d xformM;
xformM.setToTranslation(vtMove);
pFenceReg->transformBy(xformM);
AcDb3dSolid* pSolid2 = new AcDb3dSolid;
es = pSolid2->extrudeAlongPath(pFenceReg, &lnEx);
if (es != Acad::eOk)
{
delete pSolid;
delete pFenceReg;
delete pSolid2;
acutPrintf(_T("\n%d:拉伸错误!"), es);
return false;
}
//TEST
//AddToModelSpace((AcDbEntity*)pSolid2->clone());
if ( Acad::eOk == (es = pSolid->booleanOper(AcDb::kBoolIntersect,pSolid2) ) )
{
m_pSolid = pSolid;
}
else
{
delete pFenceReg;
delete pSolid;
delete pSolid2;
return false;
}
//序列化数据
m_eType = kIntersect;
m_ptOrg = ptOrg;
m_ptFr = lnPath.startPoint();
m_ptTo = lnPath.endPoint();
m_vtZ = vtExDir;
CString sScr1;
CoreTools::RegionToString(pRegion,sScr1);
CString sScr2;
CoreTools::CurveToString(pFenceCrv,sScr2);
m_sScr.Format(_T("%s|%s"),sScr1,sScr2);
return true;
}
bool AcDbX3dSolid::CreateSliceSolid(const AcDbCurve* pPlFenceTop,const AcDbLine& lnPath,const AcGePoint3d& ptOrg,const AcDbRegion* pRegionWall,double dWallHeight,const AcGeVector3d& vtExDir)
{
if (pPlFenceTop == NULL)
return false;
if (pRegionWall == NULL)
return false;
AcDbLine lnEx;
AcGePoint3d pt1,pt2;
pt1 = ptOrg + dWallHeight * vtExDir;
pt2 = ptOrg - dWallHeight * vtExDir;
lnEx.setStartPoint(pt1);
lnEx.setEndPoint(pt2);
Acad::ErrorStatus es;
AcDb3dSolid* pSolid = new AcDb3dSolid;
if ( Acad::eOk == (es = pSolid->extrudeAlongPath(pRegionWall, &lnEx) ) )
{
//TEST
//AddToModelSpace((AcDbEntity*)pSolid->clone());
AcGeVector3d vtDir = lnPath.endPoint() - lnPath.startPoint();
AcDbSweepOptions sweepOptions;
AcDbExtrudedSurface extSur;
if ( Acad::eOk == (es = extSur.createExtrudedSurface((AcDbEntity*)pPlFenceTop,vtDir,sweepOptions) ) )
{
//TEST
//AddToModelSpace((AcDbEntity*)extSur.clone());
//保留fencetop法向方向的结果
AcDb3dSolid* pNegHalifSolid = NULL;
if ( Acad::eOk == (es = pSolid->getSlice(&extSur,false,pNegHalifSolid) ) )
{
m_eType = kSliceSolid;
m_pSolid = pSolid;
m_ptFr = lnPath.startPoint();
m_ptTo = lnPath.endPoint();
m_ptOrg = ptOrg;
m_vtZ = vtExDir;
m_dH = dWallHeight;
CString sSrc1;
CoreTools::RegionToString(pRegionWall,sSrc1);
CString sScr2;
CoreTools::CurveToString(pPlFenceTop,sScr2);
m_sScr.Format(_T("%s|%s"),sSrc1,sScr2);
//TEST
//AddToModelSpace(pSolid);
return true;
}
}
}
delete pSolid;
return false;
}
bool AcDbX3dSolid::CreateRevolve(const AcDbRegion* pRegion,const AcGePoint3d& ptOrg,const AcGeVector3d& vtAxis,double dSweepAngle)
{
if (pRegion == NULL)
return false;
Acad::ErrorStatus es;
AcDb3dSolid* pSolid = new AcDb3dSolid;
if (Acad::eOk == (es = pSolid->revolve(pRegion,ptOrg,vtAxis,dSweepAngle)))
{
m_pSolid = pSolid;
m_eType = kRevolve;
CoreTools::RegionToString(pRegion,m_sScr);
m_ptOrg = ptOrg;
m_vtZ = vtAxis;
m_dW = dSweepAngle;
return true;
}
else
{
DELETE_PTR(pSolid);
}
return false;
}
bool AcDbX3dSolid::CreateRevolve2(AcDbRegion * pRegion
, const AcGePoint3d & ptOrg
, const AcGeVector3d & vtAxis
, double dSweepAngle
, double dStartAngle)
{
if (!pRegion) return false;
AcDbRegion *pReg = (AcDbRegion*)pRegion->clone();
AcDbRevolveOptions op;
AcDb3dSolid* pSolid = new AcDb3dSolid;
if (Acad::eOk == pSolid->createRevolvedSolid(pReg, ptOrg, vtAxis, dSweepAngle, dStartAngle, op))
{
DELETE_PTR(m_pSolid);
m_pSolid = pSolid;
m_eType = kRevolve2;
CoreTools::RegionToString(pRegion,m_sScr);
m_ptOrg = ptOrg;
m_vtZ = vtAxis;
m_dW = dSweepAngle;
m_dT = dStartAngle;
}
else
{
DELETE_PTR(pSolid);
}
DELETE_PTR(pReg);
if (pSolid) return true;
return false;
}
bool AcDbX3dSolid::CreatePathExtrude(const AcGePoint3d& ptOrg,LPCTSTR pszPath,int nShape,int nF,double dW,double dH,double dT,double dT2,double dT3,double dE0,double dE1,AcGeVector3d& vtCut1,AcGeVector3d& vtCut2)
{
if (pszPath == NULL)
return false;
m_ptOrg = ptOrg;
m_dH = dH;
m_dT = dT;
m_dW = dW;
m_fStair[0] = (float)dE0;
m_fStair[1] = (float)dE1;
m_nKind = nF;
m_vtLast = vtCut1;
m_vtNext = vtCut2;
m_arSizes.removeAll();
m_arSizes.append(dT2);
m_arSizes.append(dT3);
m_sszPoint2ds.Format(_T("%s@%d"),pszPath,nShape);
m_eType = kExtrudePath;
CStringArray arXYs;
CoreTools::SplitStrintToArray(pszPath,arXYs,_T(','));
CString sX,sYB,sBulge,sY;
double dBulge = 0.0;
int nFind = -1;
AcGePoint2d pt;
AcDbPolyline pl;
pl.setNormal(AcGeVector3d::kZAxis);
for (int i = 0;i < arXYs.GetSize() / 2 ;i++)
{
sX = arXYs.GetAt(2 * i);
sYB = arXYs.GetAt(2 * i + 1);
sY = sYB;
dBulge = 0.0;
nFind = sYB.Find( _T('@') );
if (nFind != -1)
{
sBulge = sYB.Mid(nFind + 1);
dBulge = _ttof(sBulge);
sY = sYB.Mid(0,nFind);
}
pt.set(_ttof(sX),_ttof(sY));
pl.addVertexAt(i,pt,dBulge);
}
AcDb3dSolid* pSolidOutSide = CreateLoftSolid(ptOrg,pl,nShape,dW,dH,0,0,0,nF,dE0,dE1,vtCut1,vtCut2);
if (dT > 1.e-3)
{
AcDb3dSolid* pSolidInside = CreateLoftSolid(ptOrg,pl,nShape,dW,dH,dT,dT2,dT3,nF,dE0,dE1,vtCut1,vtCut2);
if (pSolidOutSide != NULL && pSolidInside != NULL)
{
Acad::ErrorStatus es;
es = pSolidOutSide->booleanOper(AcDb::kBoolSubtract,pSolidInside);
if (es != Acad::eOk)
{
acutPrintf(_T("\n创建螺旋拉伸体失败:%d"),es);
DELETE_PTR(pSolidOutSide);
DELETE_PTR(pSolidInside);
return false;
}
}
}
if (pSolidOutSide != NULL)
{
m_pSolid = pSolidOutSide;
}
return m_pSolid != NULL ? true : false;
}
bool AcDbX3dSolid::CreateEarthWorm(const AcGePoint3d& ptOrg,const AcGeVector3d& vtZ,LPCTSTR pszScr,double dLen,const AcGeVector3d& vtLast,const AcGeVector3d& vtNext)
{
if (pszScr == NULL)
return false;
m_vtZ = vtZ;
m_sScr = pszScr;
m_dLen = dLen;
m_vtLast = vtLast;
m_vtNext = vtNext;
//_T("RECT:3900x3600|2900x3600|400x300|EXT:...");//EXT为扩充字段
AecDbEarthWorm dbEW;
dbEW.SetCrossSectionScr(pszScr);
//dbEW.SetChamferInter(0.0);
AcGePoint2d ptSize = dbEW.GetSize();
AcGePoint3d ptSta = ptOrg - vtZ * dLen * 0.5;
AcGePoint3d ptEnd = ptOrg + vtZ * dLen * 0.5;
AcGeLineSeg3d ln(ptSta,ptEnd);
AcDbRegion* pRegion = NULL;
AcDb3dSolid* pEwSolid = dbEW.CreateEarthWorm3DSeg(ln,pRegion);
if (pEwSolid != NULL)
{
//if (!vtLast.isParallelTo(vtZ))
{
AcDbRegion* pRegin1 = (AcDbRegion*)pRegion->clone();
pEwSolid = AecDbEarthWorm::ConnectLastOrNext(pEwSolid,ln,pRegin1,vtLast,ptSize.y,0);
DELETE_PTR(pRegin1);
}
//if (!vtNext.isParallelTo(vtZ))
{
AcDbRegion* pRegin2 = (AcDbRegion*)pRegion->clone();
pEwSolid = AecDbEarthWorm::ConnectLastOrNext(pEwSolid,ln,pRegin2,vtNext,ptSize.y,1);
DELETE_PTR(pRegin2);
}
m_pSolid = pEwSolid;
m_eType = AcDbX3dSolid::kEarthWorm;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
m_ptOrg = ptOrg;
DELETE_PTR(pRegion);
return true;
}
return false;
}
bool AcDbX3dSolid::CreateSHEarthWorm(const AcGePoint3d& ptOrg,const AcGeVector3d& vtZ,STSection* pSection,double dLen,const AcGeVector3d& vtLast,const AcGeVector3d& vtNext)
{
m_vtZ = vtZ;
FormatScriptFromSection(m_sScr,pSection);
m_dLen = dLen;
m_vtLast = vtLast;
m_vtNext = vtNext;
AecDbShEarthWorm dbEW;
AcGePoint3d ptEnd = ptOrg - vtZ * 0.5 * dLen;
AcGePoint3d ptSta = ptOrg + vtZ * 0.5 * dLen;
AcDbLine ln(ptSta,ptEnd);
AecDb3dRoadAxisLine* pRoadLn = new AecDb3dRoadAxisLine;
pRoadLn->AppendCurveSeg(&ln);
dbEW.GetSpecialtyData()->SetAt(KEY_2DSTYLE, 2);
dbEW.SetSection(pSection->pReg, pSection->pt);
dbEW.SetBaseCurve(pRoadLn);
dbEW.GetSpecialtyData()->SetAt(KEY_THICKT1,AS_MUNIT(pSection->dThick[0]));
dbEW.GetSpecialtyData()->SetAt(KEY_THICKT2,AS_MUNIT(pSection->dThick[1]));
dbEW.GetSpecialtyData()->SetAt(KEY_THICKT4,AS_MUNIT(pSection->dThick[2]));
dbEW.GetSpecialtyData()->SetAt(KEY_THICKT5,AS_MUNIT(pSection->dThick[3]));
AcDb3dSolid* pEwSolid = dbEW.GetCreatPipe3dSolid();
if (pEwSolid != NULL)
{
m_pSolid = pEwSolid;
m_eType = AcDbX3dSolid::kSHEarthWorm;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
m_ptOrg = ptOrg;
return true;
}
return false;
}
bool AcDbX3dSolid::CreateEarthWorm(const AcGePoint3d& ptSta,const AcGePoint3d& ptMid,const AcGePoint3d& ptEnd,LPCTSTR pszScr,const AcGeVector3d& vtLast,const AcGeVector3d& vtNext)
{
return false;
}
bool AcDbX3dSolid::CreateElbow(const AcGePoint3d& ptMid,const AcGeVector3d& vtMaj,const AcGeVector3d& vtMin,double dSweepAngle,double dR,double dRatio)
{
m_vtLast = vtMaj;
m_vtLast.normalize();
m_vtNext = vtMin;
m_vtNext.normalize();
AcGeVector3d vtNorm = vtMaj.crossProduct(m_vtNext);
AcGePoint3d ptFr;
AcDbArc* pArcElbow = KTCADUtilityEx::FormatArc(vtMaj,vtMin,ptMid,ptFr,dSweepAngle,dR,dRatio);
if (pArcElbow == NULL)
return false;
AcDbCircle cir;
cir.setCenter(ptFr);
cir.setNormal(vtMaj);
cir.setRadius(dR);
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
arCurPtrs.append(&cir);
Acad::ErrorStatus es = AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs);
if (arRegPtrs.length() == 0)
{
return false;
}
AcDbRegion* pRegI = (AcDbRegion*)arRegPtrs.first();
if (pRegI != NULL)
{
AcDb3dSolid* pSolidI = new AcDb3dSolid;
es = pSolidI->extrudeAlongPath(pRegI,pArcElbow);
if (es == Acad::eOk)
{
m_ptOrg = ptMid;
m_arSizes.removeAll();
m_arSizes.append(dR);
m_arSizes.append(dRatio);
m_arSizes.append(dSweepAngle);
m_pSolid = pSolidI;
DELETE_PTR(pRegI);
m_eType = AcDbX3dSolid::kElbow;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
AcGePlane plan(ptMid,vtNorm);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
DELETE_PTR(pArcElbow);
return true;
}
DELETE_PTR(pRegI);
}
return false;
}
bool AcDbX3dSolid::CreateTee(const AcGePoint3d& ptMid,const AcGeVector3d& vtMaj,const AcGeVector3d& vtMin,double dR,double dL,double dt)
{
m_vtLast = vtMaj;
m_vtNext = vtMin;
m_vtLast.normalize();
m_vtNext.normalize();
if (!vtMaj.isPerpendicularTo(vtMin))
{
return false;
}
AcGePoint3d ptFr = ptMid - dL * m_vtLast;
AcDbCircle cir;
cir.setCenter(ptFr);
cir.setNormal(vtMaj);
cir.setRadius(dR);
AcDbLine ln;
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
arCurPtrs.append(&cir);
Acad::ErrorStatus es = AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs);
if (arRegPtrs.length() == 0)
{
return false;
}
AcDb3dSolid* pSolidAll = NULL;
AcDb3dSolid* pSolidI = NULL;
AcDbRegion* pRegI = (AcDbRegion*)arRegPtrs.first();
if (pRegI != NULL)
{
pSolidI = new AcDb3dSolid;
ln.setStartPoint(ptFr);
ln.setEndPoint(ptFr + m_vtLast * dL);
es = pSolidI->extrudeAlongPath(pRegI,&ln);
if (es != Acad::eOk)
{
DELETE_PTR(pRegI);
return false;
}
pSolidAll = pSolidI;
DELETE_PTR(pRegI);
}
arRegPtrs.removeAll();
cir.setCenter(ptMid);
cir.setNormal(vtMin);
cir.setRadius(dR);
es = AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs);
if (arRegPtrs.length() == 0)
{
DELETE_PTR(pSolidAll);
return false;
}
pRegI = (AcDbRegion*)arRegPtrs.first();
if (pRegI != NULL)
{
ln.setStartPoint(ptMid);
ln.setEndPoint(ptMid + m_vtNext * dt);
pSolidI = new AcDb3dSolid;
es = pSolidI->extrudeAlongPath(pRegI,&ln);
if (es != Acad::eOk)
{
DELETE_PTR(pRegI);
return false;
}
DELETE_PTR(pRegI);
es = pSolidAll->booleanOper(AcDb::kBoolUnite,pSolidI);
if (Acad::eOk == es)
{
m_ptOrg = ptMid;
m_pSolid = pSolidAll;
m_arSizes.removeAll();
m_arSizes.append(dR);
m_arSizes.append(dL);
m_arSizes.append(dt);
m_eType = AcDbX3dSolid::kTee;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
AcGeVector3d vtNorm = vtMin.crossProduct(vtMaj);
AcGePlane plan(ptMid,vtNorm);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
return true;
}
}
return false;
}
bool AcDbX3dSolid::CreateCross(const AcGePoint3d& ptMid,const AcGeVector3d& vtMaj,const AcGeVector3d& vtMin,double dR,double dL)
{
m_vtLast = vtMaj;
m_vtNext = vtMin;
m_vtLast.normalize();
m_vtNext.normalize();
if (!vtMaj.isPerpendicularTo(vtMin))
{
return false;
}
AcGePoint3d ptFr = ptMid - dL * m_vtLast;
AcDbCircle cir;
cir.setCenter(ptFr);
cir.setNormal(vtMaj);
cir.setRadius(dR);
AcDbLine ln;
AcDbVoidPtrArray arCurPtrs,arRegPtrs;
arCurPtrs.append(&cir);
Acad::ErrorStatus es = AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs);
if (arRegPtrs.length() == 0)
{
return false;
}
AcDb3dSolid* pSolidAll = NULL;
AcDb3dSolid* pSolidI = NULL;
AcDbRegion* pRegI = (AcDbRegion*)arRegPtrs.first();
if (pRegI != NULL)
{
pSolidI = new AcDb3dSolid;
ln.setStartPoint(ptFr);
ln.setEndPoint(ptFr + m_vtLast * dL);
es = pSolidI->extrudeAlongPath(pRegI,&ln);
if (es != Acad::eOk)
{
DELETE_PTR(pRegI);
return false;
}
pSolidAll = pSolidI;
DELETE_PTR(pRegI);
}
ptFr = ptMid - m_vtNext * 0.5 * dL;
arRegPtrs.removeAll();
cir.setCenter(ptFr);
cir.setNormal(vtMin);
cir.setRadius(dR);
es = AcDbRegion::createFromCurves(arCurPtrs,arRegPtrs);
if (arRegPtrs.length() == 0)
{
DELETE_PTR(pSolidAll);
return false;
}
pRegI = (AcDbRegion*)arRegPtrs.first();
if (pRegI != NULL)
{
ln.setStartPoint(ptFr);
ln.setEndPoint(ptFr + m_vtNext * dL);
pSolidI = new AcDb3dSolid;
es = pSolidI->extrudeAlongPath(pRegI,&ln);
if (es != Acad::eOk)
{
DELETE_PTR(pRegI);
return false;
}
DELETE_PTR(pRegI);
es = pSolidAll->booleanOper(AcDb::kBoolUnite,pSolidI);
if (Acad::eOk == es)
{
m_ptOrg = ptMid;
m_pSolid = pSolidAll;
m_arSizes.removeAll();
m_arSizes.append(dR);
m_arSizes.append(dL);
m_eType = AcDbX3dSolid::kCross;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
AcGeVector3d vtNorm = vtMin.crossProduct(vtMaj);
AcGePlane plan(ptMid,vtNorm);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
return true;
}
}
return false;
}
bool AcDbX3dSolid::CreateReducer(const AcGePoint3d& ptMid,const AcGeVector3d& vtMaj,double dR,double dr,double dL)
{
m_vtLast = vtMaj;
m_vtNext = vtMaj;
m_vtLast.normalize();
m_vtNext.normalize();
AcArray<double> arSizes;
arSizes.append(dR);
arSizes.append(dL);
arSizes.append(dr);
m_pSolid = new AcDb3dSolid;
if ( Acad::eOk == m_pSolid->createFrustum(arSizes.at(Y),arSizes.at(X),arSizes.at(X),arSizes.at(Z)) )
{
m_eType = AcDbX3dSolid::kReducer;
m_arSizes.removeAll();
m_arSizes.append(dR);
m_arSizes.append(dL);
m_arSizes.append(dr);
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
AcGePlane plan(ptMid,vtMaj);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < m_arAxisVector.length();i++)
{
AcGeVector3d& vt = m_arAxisVector.at(i);
vt.transformBy(xform);
}
m_pSolid->transformBy(xform);
m_ptOrg = ptMid;
return true;
}
else
{
DELETE_PTR(m_pSolid);
m_pSolid = NULL;
return false;
}
return false;
}
typedef struct SolidVol
{
AcDb3dSolid* pSolid;
double dVol;
}SOLIDVOL;
bool SortByVol(SolidVol& sv1,SolidVol& sv2)
{
if (sv1.dVol - sv2.dVol < 1.e-3)
return false;
return true;
}
void Sort3dSolidByVol(AcDbVoidPtrArray& arPtr)
{
double dVol = 0.0,momInertia[3],prodInertia[3],prinMoments[3],radiiGyration[3];
AcGePoint3d ptCen;
AcGeVector3d prinAxes[3];
AcDbExtents extents;
SolidVol sv;
std::vector<SolidVol> vtSolids;
for (int ii = 0;ii < arPtr.length();ii++)
{
AcDbEntity* p3DEnt = (AcDbEntity*)arPtr.at(ii);
if (p3DEnt != NULL)
{
AcDb3dSolid* pSolid = AcDb3dSolid::cast(p3DEnt);
if (pSolid != NULL)
{
//然后变换到0,0,0点
pSolid->getMassProp(dVol,ptCen,momInertia,prodInertia,prinMoments,prinAxes,radiiGyration,extents);
sv.dVol = dVol;
sv.pSolid = pSolid;
vtSolids.push_back(sv);
}
AcDbBody* pBody = AcDbBody::cast(p3DEnt);
if (pBody != NULL)
{
AcDb3dSolid* pSolidT = new AcDb3dSolid;
#if ARX>18
pSolidT->setASMBody(pBody);
#else
pSolidT->setBody(pBody);
#endif
//然后变换到0,0,0点
pSolidT->getMassProp(dVol,ptCen,momInertia,prodInertia,prinMoments,prinAxes,radiiGyration,extents);
sv.dVol = dVol;
sv.pSolid = pSolidT;
vtSolids.push_back(sv);
}
}
}
std::sort(vtSolids.begin(),vtSolids.end(),SortByVol);
arPtr.removeAll();//清空
for (int i = 0;i < vtSolids.size();i++)
{
arPtr.append(vtSolids.at(i).pSolid);
}
}
bool AcDbX3dSolid::CreateFromSat(LPCTSTR pszSatFile,double dUnitScale)
{
m_dH = dUnitScale;
m_eType = AcDbX3dSolid::kFromSat;
if (m_pSatBuffer == NULL && m_nSatLen == 0)
{
//read
if (pszSatFile != NULL)
{
TRY
{
CFile file1;
if (file1.Open(pszSatFile,CFile::modeRead | CFile::typeBinary))
{
m_nSatLen = (Adesk::UInt32)file1.GetLength();
m_pSatBuffer = new byte[m_nSatLen];
file1.Read(m_pSatBuffer,m_nSatLen);
file1.Close();
}
}
CATCH (CMemoryException, e)
{
}
END_CATCH
}
}
if (m_pSatBuffer != NULL && m_nSatLen > 0)
{
//保存临时文件
TCHAR szfileName[MAX_PATH],szFullPath[MAX_PATH];
GetModuleFileName(_hdllInstance,szfileName,MAX_PATH);
TCHAR drive[_MAX_DRIVE] = _T(""),
dir[_MAX_DIR] = _T(""),
fname[_MAX_FNAME] = _T(""),
ext[_MAX_EXT] = _T("");
//e:\,program files\autodesk\,myarx,exe
_tsplitpath(szfileName, drive, dir, fname, ext);
_tcscpy(szFullPath, drive);
_tcscat(szFullPath, dir);
CString sFullPath = szFullPath;
sFullPath.TrimRight(_T('\\'));
//上一级目录
int nPos = sFullPath.ReverseFind(_T('\\'));
CString sPath = sFullPath.Mid(0,nPos + 1);
sFullPath = sPath + _T("temp\\temp.sat");
CFile file;
if (file.Open(sFullPath,CFile::modeCreate|CFile::modeWrite))
{
file.Write(m_pSatBuffer,m_nSatLen);
file.Close();
Acad::ErrorStatus es;
AcDbVoidPtrArray arPtr;
AcDbBody::acisIn(sFullPath,arPtr);
//按照体积从大到小排序
Sort3dSolidByVol(arPtr);
AcDb3dSolid* pSolidAll = NULL;
AcDb3dSolid* pSolidAllBk = NULL;
if (arPtr.length() > 0)
{
for (int ii = 0;ii < arPtr.length();ii++)
{
AcDbEntity* p3DEnt = (AcDbEntity*)arPtr.at(ii);
if (p3DEnt != NULL)
{
AcDb3dSolid* pSolid = AcDb3dSolid::cast(p3DEnt);
if (pSolid != NULL)
{
if (pSolidAll == NULL)
{
pSolidAll = pSolid;
}
else
{
pSolidAllBk = (AcDb3dSolid*)pSolidAll->clone();
es = pSolidAll->booleanOper(AcDb::kBoolUnite,pSolid);
if (es != Acad::eOk)
{
pSolidAll = pSolidAllBk;
}
else
{
DELETE_PTR(pSolidAllBk);
}
}
}
AcDbBody* pBody = AcDbBody::cast(p3DEnt);
if (pBody != NULL)
{
AcDb3dSolid* pSolidT = new AcDb3dSolid;
#if ARX>18
es = pSolidT->setASMBody(pBody);
#else
es = pSolidT->setBody(pBody);
#endif
if (es == Acad::eOk)
{
if (pSolidAll == NULL)
{
pSolidAll = pSolidT;
}
else
{
pSolidAllBk = (AcDb3dSolid*)pSolidAll->clone();
es = pSolidAll->booleanOper(AcDb::kBoolUnite,pSolidT);
if (es != Acad::eOk)
{
pSolidAll = pSolidAllBk;
}
else
{
DELETE_PTR(pSolidAllBk);
}
}
}
}
}
}
if (pSolidAll != NULL)
{
double dVol = 0.0,momInertia[3],prodInertia[3],prinMoments[3],radiiGyration[3];
AcGePoint3d ptCen;
AcGeVector3d prinAxes[3];
AcDbExtents extents;
//然后变换到0,0,0点
pSolidAll->getMassProp(dVol,ptCen,momInertia,prodInertia,prinMoments,prinAxes,radiiGyration,extents);
AcGeVector3d vtMove = ptCen.asVector();
vtMove.negate();
AcGeMatrix3d xform;
xform.setToTranslation(vtMove);
pSolidAll->transformBy(xform);
//外部默认毫米单位->米单位
xform.setToScaling(dUnitScale);
pSolidAll->transformBy(xform);
m_pSolid = pSolidAll;
return true;
}
}
}
}
return false;
}
bool AcDbX3dSolid::CreateLoftReducer(LPCTSTR pszarTopPts,LPCTSTR pszarBomPts,double dBomEl,double dH,double dThick,double dBomThick)
{
m_eType = AcDbX3dSolid::kLoftReducer;
m_dH = dH;
m_dW = dBomEl;
m_dT = dThick;
m_dLen = dBomThick;
CStringArray arXYs;
CoreTools::SplitStrintToArray(pszarTopPts,arXYs,_T(','));
CString sX,sYB,sBulge,sY;
double dBulge = 0.0;
int nFind = -1;
AcGePoint2d pt,ptFr,ptTo;
//Bom
AcDbPolyline* pPlTop = new AcDbPolyline;
pPlTop->setNormal(AcGeVector3d::kZAxis);
for (int i = 0;i < arXYs.GetSize() / 2 ;i++)
{
sX = arXYs.GetAt(2 * i);
sYB = arXYs.GetAt(2 * i + 1);
sY = sYB;
dBulge = 0.0;
nFind = sYB.Find( _T('@') );
if (nFind != -1)
{
sBulge = sYB.Mid(nFind + 1);
dBulge = _ttof(sBulge);
sY = sYB.Mid(0,nFind);
}
if (i == 0) ptFr = pt;
pt.set(_ttof(sX),_ttof(sY));
pPlTop->addVertexAt(i,pt,dBulge);
}
pPlTop->setClosed(Adesk::kTrue);
pPlTop->setElevation(dBomEl + dH);
AcArray<AcDbEntity*> crossSectionCurves,guideCurves;
crossSectionCurves.append(pPlTop);
//Top
arXYs.RemoveAll();
CoreTools::SplitStrintToArray(pszarBomPts,arXYs,_T(','));
AcDbPolyline* pPlBom = new AcDbPolyline;
pPlBom->setNormal(AcGeVector3d::kZAxis);
for (int i = 0;i < arXYs.GetSize() / 2 ;i++)
{
sX = arXYs.GetAt(2 * i);
sYB = arXYs.GetAt(2 * i + 1);
sY = sYB;
dBulge = 0.0;
nFind = sYB.Find( _T('@') );
if (nFind != -1)
{
sBulge = sYB.Mid(nFind + 1);
dBulge = _ttof(sBulge);
sY = sYB.Mid(0,nFind);
}
if (i == 0) ptTo = pt;
pt.set(_ttof(sX),_ttof(sY));
pPlBom->addVertexAt(i,pt,dBulge);
}
pPlBom->setClosed(Adesk::kTrue);
pPlBom->setElevation(dBomEl);//
crossSectionCurves.append(pPlBom);
m_sszPoint2ds = pszarBomPts;
m_sszPoint2ds += _T("|");
m_sszPoint2ds += pszarTopPts;
AcDbEntity* pPath = NULL;
AcDbLoftOptions op;
op.setRuled(true);
CString strRegions(_T(""));
Acad::ErrorStatus es;
AcDb3dSolid* pSolidIn = new AcDb3dSolid;//内部
if (Acad::eOk == (es = pSolidIn->createLoftedSolid(crossSectionCurves, guideCurves, NULL, op)))
{
// 如果成功,将两个截面取出保存,方便导出到json
{
for (int i(0); i < crossSectionCurves.length(); ++i)
{
AcDbPolyline *pL((AcDbPolyline*)crossSectionCurves[i]);
if (!pL) continue;
CString str;
if (CoreTools::PolylineToString(pL, str, false))
{
strRegions += str;
strRegions += TCHAR(0x00c1);
}
}
m_nSatLen = sizeof(TCHAR) * strRegions.GetLength();
m_pSatBuffer = new TCHAR[m_nSatLen];
::memset(m_pSatBuffer, 0, m_nSatLen);
::memcpy(m_pSatBuffer, strRegions.GetBuffer(), m_nSatLen);
}
//外部,放大厚度
AcDbVoidPtrArray arBomCurPtrs,arTopCurPtrs;
if (dThick > 1.e-6)
{
double dA1 = 0;
double dA2 = 0;
pPlBom->getOffsetCurves(-dThick,arBomCurPtrs);
if (arBomCurPtrs.length() == 1 )
{
AcDbEntity* pEntBom = (AcDbEntity* )arBomCurPtrs.first();
AcDbPolyline* pPlBom2 = AcDbPolyline::cast(pEntBom);
dA1 = 0;
pPlBom->getArea(dA1);
dA2 = 0;
if (pPlBom2 != NULL )
{
pPlBom2->getArea(dA2);
if (fabs(dA2) < fabs(dA1) )
{
delete pPlBom2;
arBomCurPtrs.removeAll();
pPlBom->getOffsetCurves(dThick,arBomCurPtrs);
}
}
}
pPlTop->getOffsetCurves(-dThick,arTopCurPtrs);
if ( arTopCurPtrs.length() == 1)
{
AcDbEntity* pEntTop = (AcDbEntity* )arTopCurPtrs.first();
AcDbPolyline* pPlTop2 = AcDbPolyline::cast(pEntTop);
dA1 = 0;
pPlTop->getArea(dA1);
dA2 = 0;
if (pPlTop2 != NULL)
{
pPlTop2->getArea(dA2);
if (fabs(dA2) < fabs(dA1) )
{
delete pPlTop2;
arTopCurPtrs.removeAll();
pPlTop->getOffsetCurves(dThick,arTopCurPtrs);
}
}
}
}
for (int k = 0;k < crossSectionCurves.length();k++)
{
pPath = crossSectionCurves.at(k);
DELETE_PTR(pPath);
}
crossSectionCurves.removeAll();
if (arBomCurPtrs.length() == 1 && arTopCurPtrs.length() == 1)
{
AcDbEntity* pEntTop = (AcDbEntity* )arTopCurPtrs.first();
AcDbEntity* pEntBom = (AcDbEntity* )arBomCurPtrs.first();
pPlTop = AcDbPolyline::cast(pEntTop);
pPlBom = AcDbPolyline::cast(pEntBom);
if (pPlBom != NULL && pPlTop != NULL)
{
pPlBom->setElevation(dBomEl - dBomThick);
crossSectionCurves.append(pPlTop);
crossSectionCurves.append(pPlBom);
AcDb3dSolid* pSolidAll = new AcDb3dSolid;//外部厚体
if (Acad::eOk == (es = pSolidAll->createLoftedSolid(crossSectionCurves, guideCurves, NULL, op)))
{
// 如果成功,将两个截面取出保存,方便导出到json
{
for (int i(0); i < crossSectionCurves.length(); ++i)
{
AcDbPolyline *pL((AcDbPolyline*)crossSectionCurves[i]);
if (!pL) continue;
CString str;
if (CoreTools::PolylineToString(pL, str, false))
{
strRegions += str;
strRegions += TCHAR(0x00c1);
}
}
DELETE_ARR_(m_pSatBuffer);
m_nSatLen = sizeof(TCHAR) * strRegions.GetLength();
m_pSatBuffer = new TCHAR[m_nSatLen];
::memset(m_pSatBuffer, 0, m_nSatLen);
::memcpy(m_pSatBuffer, strRegions.GetBuffer(), m_nSatLen);
}
for (int k = 0;k < arBomCurPtrs.length();k++)
{
pPath = (AcDbEntity* )arBomCurPtrs.at(k);
DELETE_PTR(pPath);
}
arBomCurPtrs.removeAll();
for (int k = 0;k < arTopCurPtrs.length();k++)
{
pPath = (AcDbEntity* )arTopCurPtrs.at(k);
DELETE_PTR(pPath);
}
arTopCurPtrs.removeAll();
es = pSolidAll->booleanOper(AcDb::kBoolSubtract,pSolidIn);
if ( es != Acad::eOk )
{
return false;
}
m_pSolid = pSolidAll;
return true;
}
for (int k = 0;k < arBomCurPtrs.length();k++)
{
pPath = (AcDbEntity* )arBomCurPtrs.at(k);
DELETE_PTR(pPath);
}
arBomCurPtrs.removeAll();
for (int k = 0;k < arTopCurPtrs.length();k++)
{
pPath = (AcDbEntity* )arTopCurPtrs.at(k);
DELETE_PTR(pPath);
}
arTopCurPtrs.removeAll();
return false;
}
}
else
{
for (int k = 0;k < arBomCurPtrs.length();k++)
{
pPath = (AcDbEntity* )arBomCurPtrs.at(k);
DELETE_PTR(pPath);
}
for (int k = 0;k < arTopCurPtrs.length();k++)
{
pPath = (AcDbEntity* )arTopCurPtrs.at(k);
DELETE_PTR(pPath);
}
m_pSolid = pSolidIn;
return true;
}
}
else
{
acutPrintf(_T("\n创建 LoftedSolid 失败%d"),es);
//DELETE_PTR(pGuideline);
for (int k = 0;k < crossSectionCurves.length();k++)
{
pPath = crossSectionCurves.at(k);
DELETE_PTR(pPath);
}
return false;
}
return false;
}
int AcDbX3dSolid::GetSizes(AcArray<double>& arSizes) const
{
if (m_arSizes.length() > 0)
{
arSizes.append(m_arSizes);
}
return m_arSizes.length();
}
//可用于三维脚本安装
bool AcDbX3dSolid::GetInterface(AcArray<AecInterface>& arInfs) const
{
switch(m_eType)
{
case kBox: //BOX LxWxH
{
if (m_arSizes.length() >= 3)
{
AecInterface inf[6];
inf[0].ptPos.set(0,0,0);
inf[0].ptPos.z += 0.5 * m_arSizes.at(Z);
inf[0].vtDir = AcGeVector3d::kZAxis;
inf[0].dSize1 = m_arSizes.at(X);
inf[0].dSize2 = m_arSizes.at(Y);
inf[0].dGasket = 0;
inf[1].ptPos.set(0,0,0);
inf[1].ptPos.z -= 0.5 * m_arSizes.at(Z);
inf[1].vtDir = -AcGeVector3d::kZAxis;
inf[1].dSize1 = m_arSizes.at(X);
inf[1].dSize2 = m_arSizes.at(Y);
inf[1].dGasket = 0;
inf[2].ptPos.set(0,0,0);
inf[2].ptPos.x -= 0.5 * m_arSizes.at(X);
inf[2].vtDir = -AcGeVector3d::kXAxis;
inf[2].dSize1 = m_arSizes.at(Y);
inf[2].dSize2 = m_arSizes.at(Z);
inf[2].dGasket = 0;
inf[3].ptPos.set(0,0,0);
inf[3].ptPos.x += 0.5 * m_arSizes.at(X);
inf[3].vtDir = AcGeVector3d::kXAxis;
inf[3].dSize1 = m_arSizes.at(Y);
inf[3].dSize2 = m_arSizes.at(Z);
inf[3].dGasket = 0;
inf[4].ptPos.set(0,0,0);
inf[4].ptPos.y -= 0.5 * m_arSizes.at(Y);
inf[4].vtDir = -AcGeVector3d::kYAxis;
inf[4].dSize1 = m_arSizes.at(X);
inf[4].dSize2 = m_arSizes.at(Z);
inf[4].dGasket = 0;
inf[5].ptPos.set(0,0,0);
inf[5].ptPos.y += 0.5 * m_arSizes.at(Y);
inf[5].vtDir = AcGeVector3d::kYAxis;
inf[5].dSize1 = m_arSizes.at(X);
inf[5].dSize2 = m_arSizes.at(Z);
inf[5].dGasket = 0;
AcGePlane plan(m_ptOrg,m_vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < 6;i++)
{
inf[i].ptPos.transformBy(xform);
inf[i].vtDir.transformBy(xform);
arInfs.append(inf[i]);
}
}
break;
}
case kCylinder: //CYL RxH
{
if (m_arSizes.length() >= 2)
{
AecInterface inf[2];
inf[0].ptPos.set(0,0,0);
inf[0].ptPos.z += 0.5 * m_arSizes.at(Y);
inf[0].vtDir = AcGeVector3d::kZAxis;
inf[0].dSize1 = m_arSizes.at(X);
inf[0].dSize2 = m_arSizes.at(X);
inf[1].ptPos.set(0,0,0);
inf[1].ptPos.z -= 0.5 * m_arSizes.at(Y);
inf[1].vtDir = -AcGeVector3d::kZAxis;
inf[1].dSize1 = m_arSizes.at(X);
inf[1].dSize2 = m_arSizes.at(X);
AcGePlane plan(m_ptOrg,m_vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < 2;i++)
{
inf[i].ptPos.transformBy(xform);
inf[i].vtDir.transformBy(xform);
arInfs.append(inf[i]);
}
}
break;
}
case kCone: //CON R1xR2xH
{
if (m_arSizes.length() >= 3)
{
AecInterface inf[2];
inf[0].ptPos.set(0,0,0);
inf[0].ptPos.z += 0.5 * m_arSizes.at(Z);
inf[0].vtDir = AcGeVector3d::kZAxis;
inf[0].dSize1 = m_arSizes.at(X);
inf[0].dSize2 = m_arSizes.at(X);
inf[1].ptPos.set(0,0,0);
inf[1].ptPos.z -= 0.5 * m_arSizes.at(Z);
inf[1].vtDir = -AcGeVector3d::kZAxis;
inf[1].dSize1 = m_arSizes.at(Y);
inf[1].dSize2 = m_arSizes.at(Y);
AcGePlane plan(m_ptOrg,m_vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < 2;i++)
{
inf[i].ptPos.transformBy(xform);
inf[i].vtDir.transformBy(xform);
arInfs.append(inf[i]);
}
}
break;
}
case kQPyramid: //四方台 LxWxHxAng
{
if (m_arSizes.length() >= 4)
{
AecInterface inf[2];
inf[0].ptPos.set(0,0,0);
inf[0].vtDir = -AcGeVector3d::kZAxis;
inf[0].dSize1 = m_arSizes.at(X);
inf[0].dSize2 = m_arSizes.at(Y);
double dX = m_arSizes.at(Z) * cos(m_arSizes.last() ) / sin(m_arSizes.last());
inf[1].ptPos.set(0,0,0);
inf[1].ptPos.z += m_arSizes.at(Z);
inf[1].vtDir = AcGeVector3d::kZAxis;
inf[1].dSize1 = m_arSizes.at(X) - 2.0 * dX;
inf[1].dSize2 = m_arSizes.at(Y) - 2.0 * dX;
AcGePlane plan(m_ptOrg,m_vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < 2;i++)
{
inf[i].ptPos.transformBy(xform);
inf[i].vtDir.transformBy(xform);
arInfs.append(inf[i]);
}
}
break;
}
case kPipe: //圆管rxtxH
{
//rxtxh
if (m_arSizes.length() >= 3)
{
AcGePoint3d pt1 = m_ptOrg;
pt1 += m_vtZ * 0.5 * m_arSizes.at(2);
AcGePoint3d pt2 = m_ptOrg;
pt2 -= m_vtZ * 0.5 * m_arSizes.at(2);
//先旋转
AcGeVector3d vtZ = m_vtZ;
AcGeMatrix3d xRote;
for (int i = 0;i < m_arAxisVector.length();i++)
{
if (fabs(m_dAxisRotats[i]) > 1.e-10)
{
xRote.setToRotation(m_dAxisRotats[i],m_arAxisVector.at(i),m_ptOrg);
pt1.transformBy(xRote);
pt2.transformBy(xRote);
vtZ.transformBy(xRote);
}
}
//移动
AcGeMatrix3d xMove;
xMove.setToTranslation(m_vtMove);
pt1.transformBy(xMove);
pt2.transformBy(xMove);
AecInterface inf;
inf.ptPos = pt1;
inf.vtDir = vtZ;
inf.dSize1 = m_arSizes.at(0);//rxtxh
inf.dSize2 = 0.0;
arInfs.append(inf);
inf.ptPos = pt2;
inf.vtDir = -vtZ;
arInfs.append(inf);
return true;
}
break;
}
case kRectTube: //方管子LxWxtxH
{
//L,W,t,H 长宽,厚度
if (m_arSizes.length() >= 4)
{
AecInterface inf[2];
inf[0].ptPos.set(0,0,0);
inf[0].ptPos.z -= 0.5 * m_arSizes.at(3);
inf[0].vtDir = -AcGeVector3d::kZAxis;
inf[0].dSize1 = m_arSizes.at(X);
inf[0].dSize2 = m_arSizes.at(Y);
inf[1].ptPos.set(0,0,0);
inf[1].ptPos.z += 0.5 * m_arSizes.at(3);
inf[1].vtDir = AcGeVector3d::kZAxis;
inf[1].dSize1 = m_arSizes.at(X);
inf[1].dSize2 = m_arSizes.at(Y);
AcGePlane plan(m_ptOrg,m_vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < 2;i++)
{
inf[i].ptPos.transformBy(xform);
inf[i].vtDir.transformBy(xform);
arInfs.append(inf[i]);
}
}
break;
}
case kEarthWorm: //管廊段 SxL
case kStairway: //坡道
case kLadder: //爬梯和扶梯
{
break;
}
case kExtrude: //拉伸体
{
AecInterface inf[2];
AcDbPolyline* pPl = CoreTools::StringToPolyline(m_sszPoint2ds);
if (pPl != NULL)
{
AcDbExtents ext;
pPl->getGeomExtents(ext);
inf[0].ptPos.set(0,0,0);
inf[0].vtDir = -AcGeVector3d::kZAxis;
inf[0].dSize1 = ext.maxPoint().x - ext.minPoint().x;
inf[0].dSize2 = ext.maxPoint().y - ext.minPoint().y;
inf[0].ptPos.set(0,0,0);
inf[0].ptPos.z += m_dH;
inf[0].vtDir = AcGeVector3d::kZAxis;
inf[0].dSize1 = ext.maxPoint().x - ext.minPoint().x - 2.0 * m_dT;
inf[0].dSize2 = ext.maxPoint().y - ext.minPoint().y - 2.0 * m_dT;
AcGePlane plan(m_ptOrg,m_vtZ);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
for (int i = 0;i < 2;i++)
{
inf[i].ptPos.transformBy(xform);
inf[i].vtDir.transformBy(xform);
arInfs.append(inf[i]);
}
delete pPl;
}
break;
}
case kTorus: //环形 Rxr
{
break;
}
case kWPyramid: //梯形方台 LxWxHxAng1xAng2
{
break;
}
case kElbow: //弯头 RxRr //半径x曲率
{
AcGePoint3d ptMid = m_ptOrg;
double dR = m_arSizes.at(0);
double dRatio = m_arSizes.at(1);
double dAngle = m_arSizes.last();
AcGeVector3d vtMaj = m_vtLast;
AcGeVector3d vtMin = m_vtNext;
AcGePoint3d ptFr;
AcDbArc* pArcElbow = KTCADUtilityEx::FormatArc(vtMaj,vtMin,ptMid,ptFr,dAngle,dR,dRatio);
if (pArcElbow == NULL)
return false;
AcGePoint3d pt1,pt2;
pArcElbow->getStartPoint(pt1);
pArcElbow->getEndPoint(pt2);
AcGeVector3d vt1,vt2;
pArcElbow->getFirstDeriv(pt1,vt1);
pArcElbow->getFirstDeriv(pt2,vt2);
//先旋转
AcGeMatrix3d xRote;
for (int i = 0;i < m_arAxisVector.length();i++)
{
if (fabs(m_dAxisRotats[i]) > 1.e-10)
{
xRote.setToRotation(m_dAxisRotats[i],m_arAxisVector.at(i),m_ptOrg);
pt1.transformBy(xRote);
pt2.transformBy(xRote);
vt1.transformBy(xRote);
vt2.transformBy(xRote);
vtMaj.transformBy(xRote);
vtMin.transformBy(xRote);
}
}
//移动
AcGeMatrix3d xMove;
xMove.setToTranslation(m_vtMove);
pt1.transformBy(xMove);
pt2.transformBy(xMove);
AecInterface inf;
inf.ptPos = pt1;
if (vt1.isParallelTo(vtMaj))
{
vt1 = vtMaj;
vt1.negate();
}
else if (vt1.isParallelTo(vtMin))
{
vt1 = vtMin;
}
inf.vtDir = vt1;
arInfs.append(inf);
if (vt2.isParallelTo(vtMaj))
{
vt2 = vtMaj;
vt2.negate();
}
else if (vt2.isParallelTo(vtMin))
{
vt2 = vtMin;
}
inf.ptPos = pt2;
inf.vtDir = vt2;
arInfs.append(inf);
DELETE_PTR(pArcElbow);
return true;
break;
}
case kTee: //三通 RxLxT
{
break;
}
case kCross : //四通 RxL
{
break;
}
case kReducer: //变径 RxrxL
{
break;
}
case kFromSat: //sat 文件
{
break;
}
case kExtrudePath: //路径拉伸
{
break;
}
case kLoftExtrudePath: //螺旋上升拉伸体,比如弹簧
{
break;
}
case kPathPipe: //路径管道
{
break;
}
case kRevolve: //旋转体
{
break;
}
case kLoftReducer: //两层loft变径腔体
{
break;
}
case kSHEarthWorm: //盾构管廊段 SxL
{
break;
}
case kFrom3JS: //从外部数据导入的三角面,构成subDMesh实体
{
break;
}
case kFenceExtrude: //围栏拉伸Ponts->Extrude
{
break;
}
case kSlicePipe: //斜切管状物拉伸体
{
break;
}
case kExtrude2: //标准拉伸体,region+path
{
break;
}
case kIntersect: //solid的交集
{
break;
}
case kSliceSolid: //切割体
{
break;
}
case kConePipe: //Cone斜管杯体
{
break;
}
case kTydf: //天圆地方
{
break;
}
case kDrum: //鼓
{
break;
}
case kFrustum: //球台
{
break;
}
case kNozzle:
{
break;
}
default:
break;
}
if (m_arAxisVector.length() < MAX_AXISROTATS)
{
//先旋转
AcGeMatrix3d xRote;
for (int i = 0;i < m_arAxisVector.length();i++)
{
if (fabs(m_dAxisRotats[i]) > 1.e-10)
{
xRote.setToRotation(m_dAxisRotats[i],m_arAxisVector.at(i),m_ptOrg);
for (int j = 0;j < arInfs.length();j++)
{
AecInterface& infT = arInfs.at(j);
infT.ptPos.transformBy(xRote);
infT.vtDir.transformBy(xRote);
}
}
}
}
//后移动
AcGeMatrix3d xMove;
xMove.setToTranslation(m_vtMove);
for (int j = 0;j < arInfs.length();j++)
{
AecInterface& infT = arInfs.at(j);
infT.ptPos.transformBy(xMove);
}
return !arInfs.isEmpty();
}
bool AcDbX3dSolid::CreateStairWay(const AcGePoint3d& ptFr,const AcGePoint3d& ptTo,const AcGeVector3d& vtDirX,float fStepH,float fStepW,float fStairW)
{
AcDb3dSolid* pSolid = AecDbEarthWorm::NewStairWay(ptFr,ptTo,vtDirX,fStepH,fStepW,fStairW);
if (pSolid != NULL)
{
m_ptFr = ptFr;
m_ptTo = ptTo;
m_vtDirx = vtDirX;
m_fStair[0] = fStepH;
m_fStair[1] = fStepW;
m_fStair[2] = fStairW;
m_pSolid = pSolid;
m_eType = AcDbX3dSolid::kStairway;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
m_ptOrg = ptFr;
return true;
}
return false;
}
//有效
bool AcDbX3dSolid::CreateLadder(const AcGePoint3d& ptFr,const AcGeVector3d& vtDirX,const AcGeVector3d& vtDirXY,double dH,double dW,int nKind)
{
AcDbVoidPtrArray arOther3dPtrs;
AcDb3dSolid* pSolid = NULL;
if (nKind == 0)
{
pSolid = AecDbPortRoom::DrawCatLadder(ptFr,vtDirX,vtDirXY, 0.001 * dH,0.001 * dW,arOther3dPtrs);
}
else
{
pSolid = AecDbPortRoom::DrawCatLadderH(ptFr,vtDirX,vtDirXY,0.001 * dH,0.001 * dW,arOther3dPtrs);
m_fStair[0] = (float)(0.001 * dH);
m_fStair[1] = 0.3f;//300
m_fStair[2] = (float)(0.001 * dW);
}
if (pSolid != NULL)
{
m_ptFr = ptFr;
m_vtDirx = vtDirX;
m_vtDirXY = vtDirXY;
m_dH = dH;
m_dW = dW;
m_nKind = nKind;
m_pSolid = pSolid;
m_eType = AcDbX3dSolid::kStairway;
m_arAxisVector.removeAll();
m_arAxisVector.append(AcGeVector3d::kXAxis);
m_arAxisVector.append(AcGeVector3d::kYAxis);
m_arAxisVector.append(AcGeVector3d::kZAxis);
m_ptOrg.set(0,0,0);
m_ptOrg = ptFr;
return true;
}
return false;
}
AcDb3dSolid* AcDbX3dSolid::GetNative3dSolid() const
{
return m_pSolid;
}
AcDb3dSolid* AcDbX3dSolid::GetDraw3dSolid() const
{
if (m_pSolid != NULL)
{
AcDb3dSolid* pSolid = (AcDb3dSolid*)m_pSolid->clone();
if (pSolid != NULL)
{
if (m_arAxisVector.length() < MAX_AXISROTATS)
{
//先旋转
AcGeMatrix3d xRote;
for (int i = 0;i < m_arAxisVector.length();i++)
{
if (fabs(m_dAxisRotats[i]) > 1.e-10)
{
xRote.setToRotation(m_dAxisRotats[i],m_arAxisVector.at(i),m_ptOrg);
pSolid->transformBy(xRote);
}
}
}
AcGeMatrix3d xMove;
xMove.setToTranslation(m_vtMove);
pSolid->transformBy(xMove);
return pSolid;
}
}
return NULL;
}
#if ARX > 17
AcDbSubDMesh* AcDbX3dSolid::GetNativeSubDMesh() const
{
return m_pSubDMesh;
}
AcDbSubDMesh* AcDbX3dSolid::GetDrawSubDMesh() const
{
if (m_eType != kFrom3JS) return NULL;
return (AcDbSubDMesh*)m_pSubDMesh->clone();
// 移动和旋转操作在Group内完成,这里属于预留
if (m_pSubDMesh != NULL)
{
AcDbSubDMesh* pSubDMesh = (AcDbSubDMesh*)m_pSubDMesh->clone();
if (pSubDMesh != NULL)
{
if (m_arAxisVector.length() < MAX_AXISROTATS)
{
//先旋转
AcGeMatrix3d xRote;
for (int i = 0; i < m_arAxisVector.length(); i++)
{
if (fabs(m_dAxisRotats[i]) > 1.e-10)
{
xRote.setToRotation(m_dAxisRotats[i], m_arAxisVector.at(i), m_ptOrg);
pSubDMesh->transformBy(xRote);
}
}
}
AcGeMatrix3d xMove;
xMove.setToTranslation(m_vtMove);
pSubDMesh->transformBy(xMove);
return pSubDMesh;
}
}
return NULL;
}
void AcDbX3dSolid::GetDrawSubDMesh2D(AcArray<AcGeLineSeg3d> &ar) const
{
ar.append(m_pSubDMesh2Ds);
}
#endif
bool AcDbX3dSolid::GetDraw2d(AcDbVoidPtrArray& arCurPtrs)
{
return false;
}
int AcDbX3dSolid::SetActiveFace(int nFace)
{
if (m_arRegionFaces.isEmpty())
{
AcDb3dSolid* pSolid = GetDraw3dSolid();
if (pSolid != NULL)
{
pSolid->explode(m_arRegionFaces);
}
}
AcDbEntity* pEnt = NULL;
for (int i = 0;i < m_arRegionFaces.length();i++)
{
pEnt = (AcDbEntity*)m_arRegionFaces.at(nFace);
pEnt->setColorIndex(0);
}
if (nFace > -1 && nFace < m_arRegionFaces.length() )
{
pEnt = (AcDbEntity*)m_arRegionFaces.at(nFace);
if (pEnt != NULL)
{
pEnt->setColorIndex(1);
}
}
return -1;
}
void AcDbX3dSolid::SetGSMarkerID(Adesk::Int32 nMarker)
{
//当AcDbX3dSolid不用在拉伸体时 gsmarker共用m_sszPoint2ds
//m_sszPoint2ds
m_sszPoint2ds.Format(_T("%d"),nMarker);
}
Adesk::Int32 AcDbX3dSolid::GetGSMarkerID() const
{
if (m_sszPoint2ds.IsEmpty())
return -1;
return _ttoi(m_sszPoint2ds);
}
void AcDbX3dSolid::SetOrgPoint(const AcGePoint3d & pt)
{
m_ptOrg = pt;
}
AcGePoint3d AcDbX3dSolid::GetOrgPoint() const
{
AcGePoint3d ptOrg = m_ptOrg;
//先旋转
AcGeMatrix3d xRote;
for (int i = 0;i < m_arAxisVector.length();i++)
{
if (fabs(m_dAxisRotats[i]) > 1.e-10)
{
xRote.setToRotation(m_dAxisRotats[i],m_arAxisVector.at(i),m_ptOrg);
ptOrg.transformBy(xRote);
}
}
ptOrg += m_vtMove;
return ptOrg;
}
int AcDbX3dSolid::GetAxisCount() const
{
return m_arAxisVector.length();
}
AcGeVector3d AcDbX3dSolid::GetAxis(int nIndex) const
{
if (nIndex >= 0 && nIndex < m_arAxisVector.length() )
{
AcGeVector3d vtAxis = m_arAxisVector.at(nIndex);;
AcGeMatrix3d xRote;
if (fabs(m_dAxisRotats[nIndex]) > 1.e-10)
{
xRote.setToRotation(m_dAxisRotats[nIndex],m_arAxisVector.at(nIndex),m_ptOrg);
vtAxis.transformBy(xRote);
}
return vtAxis;
}
return AcGeVector3d::kIdentity;
}
void AcDbX3dSolid::AddMove(const AcGeVector3d& vtMove)
{
m_vtMove += vtMove;
if (m_pSolidDraw != NULL)
DELETE_PTR(m_pSolidDraw);
FreeBuffer(0,m_arRegionFaces);
}
void AcDbX3dSolid::ResetMove()
{
m_vtMove.set(0,0,0);
if (m_pSolidDraw != NULL)
DELETE_PTR(m_pSolidDraw);
FreeBuffer(0,m_arRegionFaces);
}
void AcDbX3dSolid::AddRotate(double dRot,int nAxisIndex)
{
if (nAxisIndex >= 0 && nAxisIndex < m_arAxisVector.length())
{
m_dAxisRotats[nAxisIndex] += dRot;
if (m_pSolidDraw != NULL)
DELETE_PTR(m_pSolidDraw);
FreeBuffer(0,m_arRegionFaces);
}
}
void AcDbX3dSolid::ResetRotate(int nAxisIndex)
{
if (nAxisIndex >= 0 && nAxisIndex < m_arAxisVector.length())
{
m_dAxisRotats[nAxisIndex] = 0.0;
if (m_pSolidDraw != NULL)
DELETE_PTR(m_pSolidDraw);
FreeBuffer(0,m_arRegionFaces);
}
if (nAxisIndex == -1)
{
memset(m_dAxisRotats,0,sizeof(double) * MAX_AXISROTATS);
if (m_pSolidDraw != NULL)
DELETE_PTR(m_pSolidDraw);
FreeBuffer(0,m_arRegionFaces);
}
}
Acad::ErrorStatus AcDbX3dSolid::Draw3d(AcGiDraw &dc) const
{
// solid 和 subdmesh 有哪个,画哪个,只画其中一个
if (m_eType == kFrom3JS)
{
#if ARX > 17
if (!m_pSubDMeshDraw)
m_pSubDMeshDraw = GetDrawSubDMesh();
if (m_pSubDMeshDraw)
dc.DrawEntity(*m_pSubDMeshDraw);
#endif
return Acad::eOk;
}
else
{
if (m_pSolidDraw == NULL)
m_pSolidDraw = GetDraw3dSolid();
if (m_pSolidDraw != NULL)
dc.DrawEntity(*m_pSolidDraw);
return Acad::eOk;
}
return Acad::eOk;
}
Acad::ErrorStatus AcDbX3dSolid::DrawActiveFace(AcGiDraw &dc) const
{
AcDbEntity* pEnt = NULL;
for (int i = 0;i < m_arRegionFaces.length();i++)
{
pEnt = (AcDbEntity*)m_arRegionFaces.at(i);
if (pEnt->colorIndex() == 1)
{
pEnt->setColorIndex(kMagenta);
dc.DrawEntity(pEnt);
return Acad::eOk;
}
}
return Acad::eInvalidInput;
}
Acad::ErrorStatus AcDbX3dSolid::ReCreate()
{
AcGeVector3d vtMaj = m_vtLast;
AcGeVector3d vtMin = m_vtNext;
AcGeVector3d vtZ;
AcGePoint3d ptOrg = m_ptOrg;
int nPos = -1,nShape = 0;
CString sTemp,sScript,sScript1,sScript2;
//loft
double dE0 = 0.0;
double dE1 = 0.0;
AcGeVector3d vtL;
AcGeVector3d vtN;
int nF = 20;
double dT2 = 0.0;
double dT3 = 0.0;
//loft
double dBomEl = 0.0;
double dH = 0.0,dAngle = 0.0;
double dThick = 0.0,dBomThick = 0.0;
AcGePoint2dArray arTopPts,arBomPts;
AcDbLine lnPath;
AcArray<double> arSize;
arSize.append(m_arSizes);
m_arSizes.removeAll();
CString sScr1;
CString sScr2;
if (m_pSolid)
{
m_pSolid->erase();
m_pSolid->close();
DELETE_PTR(m_pSolid);
}
switch(m_eType)
{
case kBox:
{
Create(AcDbX3dSolid::kBox,ptOrg,m_vtZ,3,arSize.at(0),arSize.at(1),arSize.at(2));
break;
}
case kCylinder:
{
Create(AcDbX3dSolid::kCylinder,ptOrg,m_vtZ,2,arSize.at(0),arSize.at(1));
break;
}
case kCone:
{
Create(AcDbX3dSolid::kCone,ptOrg,m_vtZ,3,arSize.at(0),arSize.at(1),arSize.at(2));
break;
}
case kQPyramid:
{
Create(AcDbX3dSolid::kQPyramid,ptOrg,m_vtZ,4,arSize.at(0),arSize.at(1),arSize.at(2),arSize.at(3));
break;
}
case kWPyramid:
{
Create(AcDbX3dSolid::kWPyramid,ptOrg,m_vtZ,5,arSize.at(0),arSize.at(1),arSize.at(2),arSize.at(3),arSize.at(4));
break;
}
case kPipe:
{
Create(AcDbX3dSolid::kPipe,ptOrg,m_vtZ,3,arSize.at(0),arSize.at(1),arSize.at(2));
break;
}
case kRectTube:
{
Create(AcDbX3dSolid::kRectTube,ptOrg,m_vtZ,4,arSize.at(0),arSize.at(1),arSize.at(2),arSize.at(3));
break;
}
case kEarthWorm:
{
CreateEarthWorm(ptOrg,m_vtZ,m_sScr,m_dLen,m_vtLast,m_vtNext);
break;
}
case kStairway:
/*{
CreateStairWay(m_ptFr,m_ptTo,m_vtDirx,m_fStair[0],m_fStair[1],m_fStair[2]);
break;
}*/
case kLadder:
{
CreateLadder(m_ptFr,m_vtDirx,m_vtDirXY,m_dH,m_dW,m_nKind);
break;
}
case kExtrude:
{
CreateExtrude(ptOrg,m_vtZ,m_sszPoint2ds,m_dH,m_dT,m_nKind);
break;
}
case kExtrudePath:
{
sTemp = m_sszPoint2ds;
nPos = sTemp.ReverseFind(_T('@'));
if (nPos != -1)
{
sScript = sTemp.Mid(0,nPos);
nShape = _ttoi(sTemp.Mid(nPos + 1));
}
dE0 = m_fStair[0];
dE1 = m_fStair[1];
nF = m_nKind;
vtL = m_vtLast;
vtN = m_vtNext;
dT2 = 0.0;
dT3 = 0.0;
if (arSize.length() == 2)
{
dT2 = arSize.first();
dT3 = arSize.last();
}
CreatePathExtrude(ptOrg,sScript,nShape,nF,m_dW,m_dH,m_dT,dT2,dT3,dE0,dE1,vtL,vtN);
break;
}
case kPathPipe:
{
sTemp = m_sszPoint2ds;
nPos = sTemp.ReverseFind(_T('@'));
if (nPos != -1)
{
sScript = sTemp.Mid(0,nPos);
nShape = _ttoi(sTemp.Mid(nPos + 1));
}
dE0 = m_fStair[0];
dE1 = m_fStair[1];
nF = m_nKind;
vtL = m_vtLast;
vtN = m_vtNext;
dT2 = 0.0;
dT3 = 0.0;
if (arSize.length() == 2)
{
dT2 = arSize.first();
dT3 = arSize.last();
}
CreatePipe(ptOrg,sScript,nShape,m_dW,m_dH,m_dT,dT2,dT3,vtL,vtN);
break;
}
case kTorus:
{
Create(AcDbX3dSolid::kTorus,ptOrg,m_vtZ,2,arSize.at(0),arSize.at(1));
break;
}
case kElbow:// = 13, //弯头 RxRr //半径x曲率
{
CreateElbow(ptOrg,vtMaj.negate(),vtMin,arSize.at(Z),arSize.at(X),arSize.at(Y));
break;
}
case kTee:// = 14, //三通 RxLxT
{
CreateTee(ptOrg,vtMaj,vtMin,arSize.at(X),arSize.at(Y),arSize.at(Z));
break;
}
case kCross:// = 15, //四通 RxL
{
CreateCross(ptOrg,vtMaj,vtMin,arSize.at(X),arSize.at(Y));
break;
}
case kReducer:// = 16, //变径 RxrxL
{
CreateReducer(ptOrg,vtMaj,arSize.at(X),arSize.at(Z),arSize.at(Y));
break;
}
case kFromSat:
{
CreateFromSat(NULL,m_dH);
break;
}
case kLoftReducer:
{
if ( AcDbX3dSolid::GetLoftReducerSides(m_sszPoint2ds,arTopPts,arBomPts) )
{
dBomEl = m_dW;
dH = m_dH;
dThick = m_dT;
dBomThick = m_dLen;
sTemp = m_sszPoint2ds;
nPos = sTemp.Find(_T('|'));
if (nPos != -1)
{
sScript1 = sTemp.Mid(0,nPos);//bom
sScript2 = sTemp.Mid(nPos+1);//top
if ( CreateLoftReducer(sScript2,sScript1,dBomEl,dH,dThick,dBomThick) )
{
}
else
{
acutPrintf(_T("\nFailed create LoftReducer!"));
}
}
}
break;
}
case kSHEarthWorm:
{
STSection* pSection = FormatSTSectionFromScript(m_sScr);
CreateSHEarthWorm(ptOrg,m_vtZ,pSection,m_dLen,m_vtLast,m_vtNext);
}
case kFrom3JS:
{
#if ARX > 17
CreateSubDMeshByMemory();
#endif
break;
}
case kFenceExtrude:
{
int nPoints = m_nSatLen / sizeof(AcGePoint3d);
AcGePoint3d* pPoints = (AcGePoint3d*)m_pSatBuffer;
dH = m_dH;
vtZ = m_vtZ;
ptOrg = m_ptOrg;
CreateFenceExtrude(ptOrg,pPoints,nPoints,vtZ,dH);
break;
}
case kSlicePipe:
{
vtZ = m_vtZ;
ptOrg = m_ptOrg;
lnPath.setStartPoint(m_ptFr);
lnPath.setEndPoint(m_ptTo);
AcDbRegion* pReg = CoreTools::StringToRegion(m_sScr);
if (pReg != NULL)
{
CreateSlicePipe(pReg,lnPath,ptOrg,vtZ);
}
break;
}
case kExtrude2:
{
lnPath.setStartPoint(m_ptFr);
lnPath.setEndPoint(m_ptTo);
AcDbRegion* pReg = CoreTools::StringToRegion(m_sScr);
if (pReg != NULL)
{
double dTape = m_dW;
CreateExtrude(pReg,lnPath,dTape);
DELETE_PTR(pReg);
}
break;
}
case kIntersect:
{
//序列化数据
//m_eType = kIntersect;
//m_ptOrg = ptOrg;
//m_ptFr = lnPath.startPoint();
//m_ptTo = lnPath.endPoint();
//m_vtZ = vtExDir;
nPos = m_sScr.Find(_T('|'));
if (nPos != -1)
{
sScr1 = m_sScr.Mid(0,nPos);
sScr2 = m_sScr.Mid(nPos);
AcDbRegion* pReg1 = CoreTools::StringToRegion(sScr1);
AcDbPolyline* pPl = CoreTools::StringToPolyline(sScr2);
if (pReg1 != NULL && pPl != NULL)
{
pPl->setClosed(Adesk::kTrue);
AcGeVector3d vtExDir = m_vtZ;
ptOrg = m_ptOrg;
lnPath.setStartPoint(m_ptFr);
lnPath.setEndPoint(m_ptTo);
CreateIntersect(pReg1,lnPath,ptOrg,pPl,vtExDir);
}
}
break;
}
case kSliceSolid:
{
//m_eType = kSliceSolid;
//m_pSolid = pSolid;
//m_ptFr = lnPath.startPoint();
//m_ptTo = lnPath.endPoint();
//m_ptOrg = ptOrg;
//m_vtZ = vtExDir;
//m_dH = dWallHeight;
//CString sSrc1;
//CoreTools::RegionToString(pRegionWall,sSrc1);
//CString sScr2;
//CurveToString(pPlFenceTop,sScr2);
nPos = m_sScr.Find(_T('|'));
if (nPos != -1)
{
sScr1 = m_sScr.Mid(0,nPos);
sScr2 = m_sScr.Mid(nPos);
AcDbRegion* pReg1 = CoreTools::StringToRegion(sScr1);
AcDbPolyline* pPlFenceTop = CoreTools::StringToPolyline(sScr2);
double dWallH = m_dH;
AcGeVector3d vtExDir = m_vtZ;
ptOrg = m_ptOrg;
lnPath.setStartPoint(m_ptFr);
lnPath.setEndPoint(m_ptTo);
if (pReg1 != NULL && pPlFenceTop != NULL)
{
CreateSliceSolid((AcDbCurve*)pPlFenceTop,lnPath,ptOrg,pReg1,dWallH,vtExDir);
delete pReg1;
delete pPlFenceTop;
}
}
break;
}
case kRevolve:
{
// m_pSolid = pSolid;
// m_eType = kRevolve;
// CoreTools::RegionToString(pRegion,m_sScr);
//
// m_ptOrg = ptOrg;
// m_vtZ = vtAxis;
// m_dW = dSweepAngle;
AcDbRegion* pReg = CoreTools::StringToRegion(m_sScr);
ptOrg = m_ptOrg;
vtZ = m_vtZ;
dAngle = m_dW;
if (pReg != NULL)
{
CreateRevolve(pReg,ptOrg,vtZ,dAngle);
delete pReg;
}
break;
}
case kConePipe:
{
nPos = m_sScr.Find(_T('|'));
if (nPos != -1)
{
sScr1 = m_sScr.Mid(0,nPos);
sScr2 = m_sScr.Mid(nPos);
AcDbRegion* pReg1 = CoreTools::StringToRegion(sScr1);
AcDbRegion* pReg2 = CoreTools::StringToRegion(sScr2);
if (pReg1 != NULL && pReg2 != NULL)
{
lnPath.setStartPoint(m_ptFr);
lnPath.setEndPoint(m_ptTo);
dAngle = m_dW;
dThick = m_dT;
CreateConePipe(pReg1,pReg2,lnPath,dAngle,dThick);
}
}
}
case kTydf:
{
double dTr = m_dT;
double dBx = m_dW;
double dBy = m_dLen;
double dH = m_dH;
double dXOffset = m_fStair[0];
ptOrg = m_ptOrg;
vtZ = m_vtZ;
BOOL bIsTfdy = m_nKind;
CreateTydf(ptOrg,vtZ,dTr,dBx,dBy,dH,dXOffset,bIsTfdy);
break;
}
case kTriPyramid:
{
if (!m_pSatBuffer) break;
if (m_nSatLen < 4 * sizeof(SubDMesh::Pnt)) break;
AcGePoint3d pt0, pt1, pt2, pt3;
buffer2TriangularPyramid(pt0, pt1, pt2, pt3, m_pSatBuffer);
::memset(m_pSatBuffer, 0, 4 * sizeof(SubDMesh::Pnt));
CreateTriangularPyramid(pt0, pt1, pt2, pt3);
break;
}
case kDrum:
{
Create(AcDbX3dSolid::kDrum
, ptOrg
, m_vtZ
, 5
, arSize.at(0)
, arSize.at(1)
, arSize.at(2)
, arSize.at(3)
, arSize.at(4) );
break;
}
case kWedge:
{
Create(AcDbX3dSolid::kWedge
, ptOrg
, m_vtZ
, 3
, arSize.at(0)
, arSize.at(1)
, arSize.at(2) );
break;
}
case kSpere:
{
Create(AcDbX3dSolid::kSpere
, ptOrg
, m_vtZ
, 1
, arSize.at(0) );
break;
}
case kRevolve2:
{
AcDbRegion* pReg = CoreTools::StringToRegion(m_sScr);
ptOrg = m_ptOrg;
vtZ = m_vtZ;
double dSweepAngle = m_dW;
double dStartAngle = m_dT;
if (pReg)
{
CreateRevolve2(pReg, ptOrg, vtZ, dSweepAngle, dStartAngle);
DELETE_PTR(pReg);
}
break;
}
case kPyramid:
{
Create(kPyramid, ptOrg, m_vtZ, 6, arSize[0], arSize[1], arSize[2], arSize[3], arSize[4], arSize[5]);
break;
}
case kLoft:
{
std::vector<CString> vec;
CoreTools::SplitString(m_sScr, REGION_SPLITE, vec);
AcArray<AcDbRegion*> regs;
for (size_t i = 0; i < vec.size(); ++i)
{
AcDbRegion *pReg = CoreTools::StringToRegion(vec[i]);
if (!pReg) continue;
regs.append(pReg);
}
AcDbCurve *pCurve = (AcDbPolyline*)CoreTools::StringToAcDbCurve(m_sszPoint2ds);
CreateLoft(regs, pCurve);
deleteContainerOfArx<AcDbRegion>(regs);
DELETE_PTR(pCurve);
break;
}
case kSweep:
{
AcDbRegion *pReg = CoreTools::StringToRegion(m_sScr);
//AcDbPolyline *pPoly = CoreTools::StringToPolyline(m_sszPoint2ds);
AcDbPolyline *pPoly = (AcDbPolyline*)CoreTools::StringToAcDbCurve(m_sszPoint2ds);
if (pReg && pPoly)
{
CreateSweep(pReg, pPoly);
DELETE_PTR(pReg);
DELETE_PTR(pPoly);
}
break;
}
default:
break;
}
return Acad::eOk;
}
bool AcDbX3dSolid::GetLoftReducerSides(CString& sPoint2ds,AcGePoint2dArray& arTopPts,AcGePoint2dArray& arBomPts)
{
CString sTemp = sPoint2ds;
int nPos = sTemp.Find(_T('|'));
if (nPos != -1)
{
CString sScript1 = sTemp.Mid(0,nPos);
CString sScript2 = sTemp.Mid(nPos+1);
CStringArray arXYs;
CoreTools::SplitStrintToArray(sScript1,arXYs,_T(','));
CString sX,sYB,sBulge,sY;
double dBulge = 0.0;
int nFind = -1;
AcGePoint2d pt;
for (int i = 0;i < arXYs.GetSize() / 2 ;i++)
{
sX = arXYs.GetAt(2 * i);
sYB = arXYs.GetAt(2 * i + 1);
sY = sYB;
dBulge = 0.0;
pt.set(_ttof(sX),_ttof(sY));
arBomPts.append(pt);
}
arXYs.RemoveAll();
CoreTools::SplitStrintToArray(sScript2,arXYs,_T(','));
for (int i = 0;i < arXYs.GetSize() / 2 ;i++)
{
sX = arXYs.GetAt(2 * i);
sYB = arXYs.GetAt(2 * i + 1);
sY = sYB;
dBulge = 0.0;
pt.set(_ttof(sX),_ttof(sY));
arTopPts.append(pt);
}
return true;
}
return false;
}
Acad::ErrorStatus AcDbX3dSolid::dwgInFields (AcDbDwgFiler* pFiler)
{
Acad::ErrorStatus es;
Adesk::UInt32 version =0 ;
if ( (es =pFiler->readUInt32 (&version)) != Acad::eOk )
return (es) ;
if ( version > AcDbX3dSolid::kCurrentVersionNumber )
return (Acad::eMakeMeProxy) ;
Adesk::Int32 nVal = 0;
pFiler->readInt32(&nVal);
m_eType = (AcDbX3dSolid::Primitive)nVal;
pFiler->readVector3d(&m_vtZ);
double dVal = 0.0;
pFiler->readInt32(&nVal);
for (int i = 0;i < nVal;i++)
{
pFiler->readDouble(&dVal);
m_arSizes.append(dVal);
}
pFiler->readPoint3d(&m_ptOrg);
TCHAR* pszTemp = NULL;
pFiler->readString(&pszTemp);
if (pszTemp != NULL)
{
m_sszPoint2ds = pszTemp;
acutDelString(pszTemp);
}
pFiler->readDouble(&m_dH);
pFiler->readDouble(&m_dT);
pFiler->readDouble(&m_dW);
pszTemp = NULL;
pFiler->readString(&pszTemp);
if (pszTemp != NULL)
{
m_sScr = pszTemp;
acutDelString(pszTemp);
}
pFiler->readDouble(&m_dLen);
pFiler->readVector3d(&m_vtLast);
pFiler->readVector3d(&m_vtNext);
pFiler->readPoint3d(&m_ptFr);
pFiler->readPoint3d(&m_ptTo);
pFiler->readVector3d(&m_vtDirx);
pFiler->readVector3d(&m_vtDirXY);
pFiler->readBytes(m_fStair,sizeof(float) * 3);
pFiler->readInt32(&m_nKind);
pFiler->readVector3d(&m_vtMove);
nVal = 0;
pFiler->readInt32(&nVal);
AcGeVector3d vt;
m_arAxisVector.removeAll();
for(int i = 0;i < nVal;i++)
{
pFiler->readVector3d(&vt);
m_arAxisVector.append(vt);
}
memset(m_dAxisRotats,0,sizeof(double) * MAX_AXISROTATS);
pFiler->readBytes(m_dAxisRotats,sizeof(double) * MAX_AXISROTATS);
if ( version > 1 )//新增加SAT支持
{
pFiler->readUInt32(&m_nSatLen);
if (m_nSatLen > 0)
{
m_pSatBuffer = new byte[m_nSatLen];
pFiler->readBytes(m_pSatBuffer,m_nSatLen);
}
}
if (version > 2 && version < 4)
{
AcDbPolyline poly;
poly.dwgInFields(pFiler);
if (m_eType == kSweep)
CoreTools::PolylineToString(&poly, m_sszPoint2ds, false);
}
ReCreate();
return pFiler->filerStatus();
}
Acad::ErrorStatus AcDbX3dSolid::dwgOutFields(AcDbDwgFiler* pFiler) const
{
Acad::ErrorStatus es;
//----- Object version number needs to be saved first
if ( (es = pFiler->writeUInt32 (AcDbX3dSolid::kCurrentVersionNumber)) != Acad::eOk )
return (es);
Adesk::Int32 nVal = (Adesk::Int32)m_eType;
pFiler->writeInt32(nVal);
pFiler->writeVector3d(m_vtZ);
nVal = m_arSizes.length();
pFiler->writeInt32(nVal);
for (int i = 0;i < nVal;i++)
{
pFiler->writeDouble(m_arSizes.at(i));
}
pFiler->writePoint3d(m_ptOrg);
pFiler->writeString((LPCTSTR)m_sszPoint2ds);
pFiler->writeDouble(m_dH);
pFiler->writeDouble(m_dT);
pFiler->writeDouble(m_dW);
pFiler->writeString((LPCTSTR)m_sScr);
pFiler->writeDouble(m_dLen);
pFiler->writeVector3d(m_vtLast);
pFiler->writeVector3d(m_vtNext);
pFiler->writePoint3d(m_ptFr);
pFiler->writePoint3d(m_ptTo);
pFiler->writeVector3d(m_vtDirx);
pFiler->writeVector3d(m_vtDirXY);
pFiler->writeBytes(m_fStair,sizeof(float) * 3);
pFiler->writeInt32(m_nKind);
pFiler->writeVector3d(m_vtMove);
nVal = m_arAxisVector.length();
pFiler->writeInt32(nVal);
for(int i = 0;i < nVal;i++)
{
pFiler->writeVector3d(m_arAxisVector.at(i));
}
pFiler->writeBytes(m_dAxisRotats,sizeof(double) * MAX_AXISROTATS);
if (AcDbX3dSolid::kCurrentVersionNumber > 1)//新版本
{
pFiler->writeUInt32(m_nSatLen);
if (m_pSatBuffer != NULL)
{
pFiler->writeBytes(m_pSatBuffer,m_nSatLen);
}
}
return Acad::eOk;
}
bool AcDbX3dSolid::SetSolidData(const Primitive &type, const AcArray<double> &ar, LPCTSTR srcRegion)
{
m_arSizes.removeAll();
switch (type)
{
case kBox:
{
if (ar.length() < 3) return false;
m_arSizes.append(ar);
}
break;
case kCylinder:
{
if (ar.length() < 2) return false;
m_arSizes.append(ar);
}
break;
case kCone:
{
if (ar.length() < 3) return false;
m_arSizes.append(ar);
}
break;
case kDrum:
{
if (ar.length() < 5) return false;
m_arSizes.append(ar);
}
break;
case kWedge:
{
if (ar.length() < 3) return false;
m_arSizes.append(ar);
}
break;
case kSpere:
{
if (ar.length() < 1) return false;
m_arSizes.append(ar);
}
break;
case kRevolve2:
{
if (!srcRegion) return false;
if (ar.length() < 2) return false;
m_dW = ar[0];
m_dT = ar[1];
if (srcRegion)
m_sScr = srcRegion;
}
break;
case kExtrude2:
{
if (ar.length() < 6) return false;
m_ptFr.x = ar[0];
m_ptFr.y = ar[1];
m_ptFr.z = ar[2];
m_ptTo.x = ar[3];
m_ptTo.y = ar[4];
m_ptTo.z = ar[5];
if (srcRegion)
m_sScr = srcRegion;
}
break;
case kPyramid:
{
if (ar.length() < 6) return false;
m_arSizes.append(ar);
}
break;
default:
return false;
}
ReCreate();
return true;
}
bool AcDbX3dSolid::GetSolidData(const Primitive & type, AcArray<double>& ar, CString *pSrc)
{
ar.removeAll();
switch (type)
{
case kBox:
{
if (m_arSizes.length() < 3) return false;
ar.append(m_arSizes);
}
break;
case kCylinder:
{
if (m_arSizes.length() < 2) return false;
ar.append(m_arSizes);
}
break;
case kCone:
{
if (m_arSizes.length() < 3) return false;
ar.append(m_arSizes);
}
break;
case kDrum:
{
if (m_arSizes.length() < 5) return false;
ar.append(m_arSizes);
}
break;
case kWedge:
{
if (m_arSizes.length() < 3) return false;
ar.append(m_arSizes);
}
break;
case kSpere:
{
if (m_arSizes.length() < 1) return false;
ar.append(m_arSizes);
}
break;
case kRevolve2:
{
ar.append(m_dW);
ar.append(m_dT);
if (pSrc)
*pSrc = m_sScr;
}
break;
case kExtrude2:
{
ar.append(m_ptFr.x);
ar.append(m_ptFr.y);
ar.append(m_ptFr.z);
ar.append(m_ptTo.x);
ar.append(m_ptTo.y);
ar.append(m_ptTo.z);
if (pSrc)
*pSrc = m_sScr;
}
break;
case kPyramid:
{
if (m_arSizes.length() < 6) return false;
ar.append(m_arSizes);
}
break;
default:
return false;
}
return true;
}
void AcDbX3dSolid::SetSatBuffer(const int &len, const void *pBuffer)
{
DELETE_ARR_(m_pSatBuffer);
m_nSatLen = len;
m_pSatBuffer = new byte[m_nSatLen];
::memset(m_pSatBuffer, 0, sizeof(byte) * m_nSatLen);
::memcpy(m_pSatBuffer, pBuffer, sizeof(byte) * m_nSatLen);
}
int AcDbX3dSolid::GetSatBuffer(void **pBuffer)
{
if (!m_nSatLen) return 0;
*pBuffer = new byte[m_nSatLen];
::memset(*pBuffer, 0, sizeof(byte) * m_nSatLen);
::memcpy(*pBuffer, m_pSatBuffer, sizeof(byte) * m_nSatLen);
return m_nSatLen;
}
bool AcDbX3dSolid::CreateLoft(const AcArray<AcDbRegion*>& crossSectionCruves, AcDbCurve *_pCurve)
{
if (crossSectionCruves.isEmpty()) return false;
m_eType = kLoft;
AcDbCurve *pCurve(NULL);
if (_pCurve)
pCurve = (AcDbCurve *)_pCurve->clone();
AcDbLoftOptions op;
op.setRuled(true);
op.setNormal(AcDbLoftOptions::kNoNormal);
AcArray<AcDb3dSolid*> solids;
AcGePoint3d pt1, pt2;
AcArray<AcDbEntity*> ents, guides;
AcArray<AcDbEntity*> ar;
CString strAll(_T("")), str(_T(""));
for (int i = 0; i < crossSectionCruves.length(); ++i)
{
ar.append((AcDbEntity*)crossSectionCruves[i]->clone());
str.Empty();
AcDbRegion *pReg(crossSectionCruves[i]);
CoreTools::RegionToString(pReg, str);
strAll += str;
strAll += REGION_SPLITE;
}
strAll.TrimRight(REGION_SPLITE);
m_sScr = strAll;
CoreTools::AcDbCurveToString(pCurve, m_sszPoint2ds);
AcDb3dSolid* pSolid = new AcDb3dSolid;
Acad::ErrorStatus es = pSolid->createLoftedSolid(ar, guides, pCurve, op);
if (es != Acad::eOk)
{
#ifndef NDEBUG
CoreTools::CloneAndAddToModelSpace(pCurve, 1);
CoreTools::CloneAndAddToModelSpace(ar.first(), 1);
CoreTools::CloneAndAddToModelSpace(ar.last(), 1);
#endif // !NDEBUG
DELETE_PTR(pCurve);
DELETE_PTR(pSolid);
deleteContainerOfArx<AcDbEntity>(ar);
m_sScr.Empty();
m_sszPoint2ds.Empty();
return false;
}
DELETE_PTR(pCurve);
deleteContainerOfArx<AcDbEntity>(ar);
DELETE_PTR(m_pSolid);
m_pSolid = pSolid;
if (!m_pSolid) return false;
return true;
}
bool AcDbX3dSolid::CreateSweep(const AcDbRegion * pSweepEnt, const AcDbPolyline *pPathEnt)
{
if (!pSweepEnt) return false;
if (!pPathEnt) return false;
AcDbPolyline* pPath = (AcDbPolyline*)pPathEnt;
m_eType = kSweep;
AcDb3dSolid* pSolid = new AcDb3dSolid;
AcDbSpline *pSpline = AcDbSpline::cast(pPathEnt);
if (pSpline)
{
AcDbSweepOptions op;
op.setAlign(AcDbSweepOptions::kAlignSweepEntityToPath);
AcDbRegion *pReg = (AcDbRegion*)pSweepEnt;
if (Acad::eOk == pSolid->createSweptSolid(pReg, pPath, op))
{
DELETE_PTR(m_pSolid);
m_pSolid = pSolid;
CoreTools::RegionToString(pSweepEnt, m_sScr);
CoreTools::AcDbCurveToString(pPath, m_sszPoint2ds);
}
else
{
DELETE_PTR(pSolid);
}
}
else
{
if (Acad::eOk == pSolid->extrudeAlongPath(pSweepEnt, pPathEnt))
{
DELETE_PTR(m_pSolid);
m_pSolid = pSolid;
CoreTools::RegionToString(pSweepEnt, m_sScr);
//CoreTools::PolylineToString(pPath, m_sszPoint2ds, false);
CoreTools::AcDbCurveToString(pPath, m_sszPoint2ds);
}
else
{
#ifndef NDEBUG
CoreTools::CloneAndAddToModelSpace(pSweepEnt);
CoreTools::CloneAndAddToModelSpace(pPathEnt);
#endif
DELETE_PTR(pSolid);
}
}
if (!pSolid) return false;
return true;
}
bool AcDbX3dSolid::GetExturd2Data(CString &sReg, AcGePoint3d &ptFr, AcGePoint3d &ptTo)
{
if (m_eType != kExtrude2) return false;
ptFr = m_ptFr;
ptTo = m_ptTo;
sReg = m_sScr;
return true;
}
void AcDbX3dSolid::SetExturd2Data(const CString &sReg, const AcGePoint3d &ptFr, const AcGePoint3d &ptTo)
{
if (m_eType == kExtrude2)
{
m_ptFr = ptFr;
m_ptTo = ptTo;
m_sScr = sReg;
ReCreate();
}
}
bool AcDbX3dSolid::GetRevolve2Data(CString &sReg, AcGePoint3d &ptOrg, AcGeVector3d &vt, double &dSweepAngle, double &dStartAngle)
{
if (m_eType != kRevolve2) return false;
sReg = m_sScr;
ptOrg = m_ptOrg;
vt = m_vtZ;
dSweepAngle = m_dW;
dStartAngle = m_dT;
return true;
}
void AcDbX3dSolid::SetRevolve2Data(const CString &sReg, const AcGePoint3d &ptOrg, const AcGeVector3d &vt, const double &dSweepAngle, double const &dStartAngle)
{
if (m_eType == kRevolve2)
{
m_sScr = sReg;
m_ptOrg = ptOrg;
m_vtZ = vt;
m_dW = dSweepAngle;
m_dT = dStartAngle;
ReCreate();
}
}
bool AcDbX3dSolid::GetSweepData(CString &sReg, AcDbCurve *&pCurve)
{
if (m_eType != kSweep) return false;
pCurve = CoreTools::StringToAcDbCurve(m_sszPoint2ds);
sReg = m_sScr;
return true;
}
void AcDbX3dSolid::SetSweepData(const CString &sReg, const AcDbCurve *pCurve)
{
if (m_eType == kSweep && pCurve)
{
m_sScr = sReg;
AcDbCurve *pClone((AcDbCurve*)pCurve->clone());
CoreTools::AcDbCurveToString(pClone, m_sszPoint2ds);
DELETE_PTR(pClone);
//AcDbPolyline *pPoly(AcDbPolyline::cast(pCurve));
//if (pPoly)
// CoreTools::PolylineToString(pPoly, m_sszPoint2ds, false);
ReCreate();
}
}
bool AcDbX3dSolid::GetLoftData(std::vector<CString> &regs)
{
if (m_eType != kLoft) return false;
CoreTools::SplitString(m_sScr, REGION_SPLITE, regs);
return true;
}
void AcDbX3dSolid::SetLoftData(const std::vector<CString> &regs)
{
if (m_eType == kLoft)
{
CString strAll(_T("")), str(_T(""));
for (int i = 0; i < regs.size(); ++i)
{
strAll += regs[i];
strAll += REGION_SPLITE;
}
strAll.TrimRight(REGION_SPLITE);
m_sScr = strAll;
ReCreate();
}
}
SHJson::WValue &AcDbX3dSolid::ToJson() const
{
/*
AcDbX3dSolid::Primitive m_eType; //类型
AcGeVector3d m_vtZ; //放置方向向量
AcArray<double> m_arSizes; //参数
AcGePoint3d m_ptOrg; //中心点
CString m_sszPoint2ds; //
double m_dH; //
double m_dT; //
double m_dW; //
CString m_sScr; //管廊段脚本,及其他脚本
double m_dLen;
AcGeVector3d m_vtLast; //管廊段上向量,管线 其他使用
AcGeVector3d m_vtNext; //管廊段下向量,管线 其他使用
//楼梯
AcGePoint3d m_ptFr;
AcGePoint3d m_ptTo;
AcGeVector3d m_vtDirx;
AcGeVector3d m_vtDirXY;
float m_fStair[3]; //
Adesk::Int32 m_nKind; //类型
//变换部分
AcGeVector3d m_vtMove; //总移动
AcGeVector3dArray m_arAxisVector; //轴向向量
double m_dAxisRotats[MAX_AXISROTATS];//最多10个轴向旋转
Adesk::UInt32 m_nSatLen;
void* m_pSatBuffer;
//以上数据创建的模型,->不序列化
AcDb3dSolid* m_pSolid; //原始solid元,不序列化
AcDbVoidPtrArray m_arCurPtrs; //创建的二维曲线
*/
using namespace SHJson;
WValue &v = m_json;
addMember(v, _T("__class__"), _T("AcDbX3dSolid"));
addMember(v, _T("__type__"), (int)m_eType);
addMember(v, _T("__vtZ__"), GEO2JSON::vector(m_vtZ).ToJson());
WValue ar;
ar.SetArray();
for (int i = 0; i < m_arSizes.length(); ++i)
{
pushBack(ar, m_arSizes[i]);
}
addMember(v, _T("__arSizes__"), ar);
addMember(v, _T("__ptOrg__"), GEO2JSON::point(m_ptOrg).ToJson());
addMember(v, _T("__dH__"), m_dH);
addMember(v, _T("__dT__"), m_dT);
addMember(v, _T("__dW__"), m_dW);
//addMember(v, _T("sszPoint2ds"), m_sszPoint2ds);
addMember(v, _T("__dLen__"), m_dLen);
addMember(v, _T("__vtLast__"), GEO2JSON::vector(m_vtLast).ToJson());
addMember(v, _T("__vtNext__"), GEO2JSON::vector(m_vtNext).ToJson());
addMember(v, _T("__ptFr__"), GEO2JSON::point(m_ptFr).ToJson());
addMember(v, _T("__ptTo__"), GEO2JSON::point(m_ptTo).ToJson());
addMember(v, _T("__vtDirx__"), GEO2JSON::vector(m_vtDirx).ToJson());
addMember(v, _T("__vtDirXY__"), GEO2JSON::vector(m_vtDirXY).ToJson());
ar.SetNull();
ar.SetArray();
for (size_t i = 0; i < 3; ++i)
{
pushBack(ar, m_fStair[i]);
}
addMember(v, _T("__fStair__"), ar);
addMember(v, _T("__nKind__"), m_nKind);
addMember(v, _T("__vtMove__"), GEO2JSON::vector(m_vtMove).ToJson());
// 轴向量
ar.SetNull();
ar.SetArray();
for (int i = 0; i < m_arAxisVector.length(); ++i)
{
pushBack(ar, GEO2JSON::vector(m_arAxisVector[i]).ToJson());
}
addMember(v, _T("__arAxisVector__"), ar);
// 旋转量
ar.SetNull();
ar.SetArray();
for (int i = 0; i < MAX_AXISROTATS; ++i)
{
pushBack(ar, m_dAxisRotats[i]);
}
addMember(v, _T("__dAxisRotats__"), ar);
addMember(v, _T("__nSatLen__"), (__int64)m_nSatLen);
addMember(v, _T("__pSatBuffer__"), GEO2JSON::binary((byte *)m_pSatBuffer, m_nSatLen).ToJson());
// 为 sweep 单独处理
if (m_eType == kSweep && !m_sszPoint2ds.IsEmpty() && !m_sScr.IsEmpty())
{
AcDbPolyline *pPoly = (AcDbPolyline*)CoreTools::StringToAcDbCurve(m_sszPoint2ds);
AcDbRegion *pReg = CoreTools::StringToRegion(m_sScr);
if (pPoly)
{
if (pReg)
{
CoreTools::fixPathAndRegionForRevitSweep(pPoly, pReg);
addMember(v, _T("__PathCurve__"), GEO2JSON::path(*pPoly).ToJson());
ar.SetArray();
pushBack(ar, GEO2JSON::region(*pReg).ToJson());
addMember(v, _T("__sScr__"), ar);
DELETE_PTR(pReg);
}
DELETE_PTR(pPoly);
}
return v;
}
if ((m_eType == kExtrude2
|| m_eType == kSlicePipe
|| m_eType == kRevolve
|| m_eType == kRevolve2)
&& !m_sScr.IsEmpty())
{
AcDbRegion *pReg = CoreTools::StringToRegion(m_sScr);
if (pReg)
{
ar.SetArray();
pushBack(ar, GEO2JSON::region(*pReg).ToJson());
addMember(v, _T("__sScr__"), ar);
DELETE_PTR(pReg);
}
return v;
}
if ((m_eType == kConePipe
|| m_eType == kIntersect
|| m_eType == kSliceSolid
|| m_eType == kLoft)
&& !m_sScr.IsEmpty())
{
CString split((m_eType == kLoft) ? REGION_SPLITE : _T("|"));
std::vector<CString> vec(0);
CoreTools::SplitString(m_sScr, split, vec);
ar.SetArray();
for (size_t i = 0; i < vec.size(); ++i)
{
AcDbRegion *pReg = CoreTools::StringToRegion(vec[i]);
if (pReg)
{
pushBack(ar, GEO2JSON::region(*pReg).ToJson());
DELETE_PTR(pReg);
}
}
if (ar.Size() > 0)
addMember(v, _T("__sScr__"), ar);
if (m_eType == kLoft)
{
AcDbCurve *pCurve = CoreTools::StringToAcDbCurve(m_sszPoint2ds);
if (pCurve)
{
addMember(v, _T("__PathCurve__"), GEO2JSON::path(*pCurve).ToJson());
DELETE_PTR(pCurve);
}
}
return v;
}
if (m_eType == kExtrude
|| m_eType == kPathPipe
|| m_eType == kExtrudePath
|| m_eType == kLoftReducer)
{
// 此处复杂,并且并不知道是否需要解析,先这样
addMember(v, _T("__sszPoint2ds__"), m_sszPoint2ds);
if (m_eType == kLoftReducer)
{
ar.SetNull();
ar.SetArray();
CString str((TCHAR*)m_pSatBuffer);
std::vector<CString>ss;
CoreTools::SplitString(str, TCHAR(0x00c1), ss);
if (ss.size() > 1)
{
AcDbPolyline *p0 = CoreTools::StringToPolyline(ss[0]);
AcDbPolyline *p1 = CoreTools::StringToPolyline(ss[1]);
if (p0 && p1)
{
pushBack(ar, GEO2JSON::region(*p0).ToJson());
pushBack(ar, GEO2JSON::region(*p1).ToJson());
}
DELETE_PTR(p0);
DELETE_PTR(p1);
}
if (ss.size() > 3)
{
AcDbPolyline *p2 = CoreTools::StringToPolyline(ss[2]);
AcDbPolyline *p3 = CoreTools::StringToPolyline(ss[3]);
if (p2 && p3)
{
pushBack(ar, GEO2JSON::region(*p2).ToJson());
pushBack(ar, GEO2JSON::region(*p3).ToJson());
}
DELETE_PTR(p2);
DELETE_PTR(p3);
}
if (ar.Size() > 0)
addMember(v, _T("__sScr__"), ar);
}
// 将m_sszPoint2ds保存成AcDbPolyline
AcDbPolyline *pPl = CoreTools::StringToPolyline(m_sszPoint2ds);
if (pPl)
{
ar.SetNull();
ar.SetArray();
pushBack(ar, GEO2JSON::region(*pPl).ToJson());
addMember(v, _T("__sszPoint2ds__sScr__"), ar);
DELETE_PTR(pPl);
}
return v;
}
// 如果走到这里,还没有return
if (!m_sScr.IsEmpty())
{
AcDbRegion *pReg = CoreTools::StringToRegion(m_sScr);
if (pReg)
{
ar.SetArray();
pushBack(ar, GEO2JSON::region(*pReg).ToJson());
addMember(v, _T("__sScr__"), ar);
DELETE_PTR(pReg);
}
return v;
}
return v;
}
bool AcDbX3dSolid::ByJson(const SHJson::WValue &v)
{
return false;
}
AcGePoint3d AcDbX3dSolid::GetCentoridPoint()
{
AcGePoint3d pt;
if (!m_pSolid)
{
ReCreate();
}
if (m_pSolid)
{
double v;
double ds[3];
AcGeVector3d vts[3];
AcDbExtents ext;
m_pSolid->getMassProp(v, pt, ds, ds, ds, vts, ds, ext);
}
return pt;
}
void AcDbX3dSolid::TransformBy(const AcGeMatrix3d & mat)
{
if (mat == AcGeMatrix3d::kIdentity)
return;
bool bChanged(false);
switch (m_eType)
{
case kBox:
case kCylinder:
case kPyramid:
case kDrum:
case kCone:
case kSpere:
{
m_ptOrg.transformBy(mat);
m_vtZ.transformBy(mat);
bChanged = true;
}
break;
case kExtrude2:
{
m_ptFr.transformBy(mat);
m_ptTo.transformBy(mat);
AcDbRegion* pReg = CoreTools::StringToRegion(m_sScr);
if (pReg)
{
pReg->transformBy(mat);
CoreTools::RegionToString(pReg,m_sScr);
DELETE_PTR(pReg);
bChanged = true;
}
}
break;
case kRevolve:
{
AcDbRegion *pReg = CoreTools::StringToRegion(m_sScr);
if (pReg)
{
pReg->transformBy(mat);
CoreTools::RegionToString(pReg, m_sScr);
DELETE_PTR(pReg);
m_ptOrg.transformBy(mat);
m_vtZ.transformBy(mat);
bChanged = true;
}
}
break;
case kRevolve2:
{
AcDbRegion* pReg = CoreTools::StringToRegion(m_sScr);
if (pReg)
{
pReg->transformBy(mat);
CoreTools::RegionToString(pReg,m_sScr);
DELETE_PTR(pReg);
m_ptOrg.transformBy(mat);
m_vtZ.transformBy(mat);
bChanged = true;
}
}
break;
case kLoft:
{
CString strAll(_T("")), str(_T(""));
std::vector<CString> vec;
CoreTools::SplitString(m_sScr, REGION_SPLITE, vec);
AcArray<AcDbRegion*> regs;
for (size_t i = 0; i < vec.size(); ++i)
{
AcDbRegion *pReg = CoreTools::StringToRegion(vec[i]);
if (!pReg) continue;
pReg->transformBy(mat);
regs.append(pReg);
CoreTools::RegionToString(pReg, str);
strAll += str;
strAll += REGION_SPLITE;
}
strAll.TrimRight(REGION_SPLITE);
m_sScr = strAll;
AcDbCurve *pCurve = (AcDbPolyline *)CoreTools::StringToAcDbCurve(m_sszPoint2ds);
if (pCurve)
{
pCurve->transformBy(mat);
CoreTools::AcDbCurveToString(pCurve, m_sszPoint2ds);
DELETE_PTR(pCurve);
}
deleteContainerOfArx<AcDbRegion>(regs);
bChanged = true;
}
break;
case kSweep:
{
AcDbCurve *pPoly = CoreTools::StringToAcDbCurve(m_sszPoint2ds);
AcDbRegion *pReg = CoreTools::StringToRegion(m_sScr);
if (pReg && pPoly)
{
pPoly->transformBy(mat);
pReg->transformBy(mat);
CoreTools::RegionToString(pReg, m_sScr);
CoreTools::AcDbCurveToString(pPoly, m_sszPoint2ds);
DELETE_PTR(pReg);
DELETE_PTR(pPoly);
bChanged = true;
}
}
break;
default:
break;
}
if (bChanged)
ReCreate();
}
AcDbX3dSolid * AcDbX3dSolid::Clone()
{
return new AcDbX3dSolid(*this);
}