966 lines
24 KiB
C++
966 lines
24 KiB
C++
#include "StdAfx.h"
|
|
#include "GiDrawutility.h"
|
|
#include "EarThwormDef.h"
|
|
|
|
namespace
|
|
{
|
|
Acad::ErrorStatus AddToModelSpace(AcDbEntity *pEnt, AcDbDatabase *pDb, bool bClose, AcDbObjectId *pId)
|
|
{
|
|
if (!pEnt) return Acad::eInvalidInput;
|
|
|
|
if (pDb == NULL)
|
|
pDb = acdbHostApplicationServices()->workingDatabase();
|
|
|
|
Acad::ErrorStatus es;
|
|
|
|
AcDbBlockTable *pTbl = NULL;
|
|
if (Acad::eOk == (es = pDb->getBlockTable(pTbl, AcDb::kForRead)))
|
|
{
|
|
AcDbBlockTableRecord *pBTR = NULL;
|
|
if (Acad::eOk == (es = pTbl->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite)))
|
|
{
|
|
es = pBTR->appendAcDbEntity(pEnt);
|
|
if (es == Acad::eOk && pId) *pId = pEnt->objectId();
|
|
if (bClose)
|
|
pEnt->close();
|
|
pBTR->close();
|
|
}
|
|
pTbl->close();
|
|
}
|
|
return es;
|
|
}
|
|
|
|
AcDbObjectId AddToModelSpace(AcDbEntity *pEnt, bool bClose)
|
|
{
|
|
if (!pEnt) return AcDbObjectId::kNull;
|
|
|
|
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
|
|
|
|
Acad::ErrorStatus es;
|
|
AcDbObjectId id(AcDbObjectId::kNull);
|
|
AcDbBlockTable *pTbl = NULL;
|
|
if (Acad::eOk == (es = pDb->getBlockTable(pTbl, AcDb::kForRead)))
|
|
{
|
|
AcDbBlockTableRecord *pBTR = NULL;
|
|
if (Acad::eOk == (es = pTbl->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite)))
|
|
{
|
|
es = pBTR->appendAcDbEntity(id, pEnt);
|
|
if (bClose)
|
|
pEnt->close();
|
|
pBTR->close();
|
|
}
|
|
pTbl->close();
|
|
}
|
|
return id;
|
|
}
|
|
|
|
Acad::ErrorStatus CloneAndAddToModelSpace(const AcDbEntity *pEnt, int clr)
|
|
{
|
|
if (!pEnt) return Acad::eInvalidInput;
|
|
AcDbEntity *p((AcDbEntity *)pEnt->clone());
|
|
p->setColorIndex(clr);
|
|
return AddToModelSpace(p, NULL, true, NULL);
|
|
}
|
|
|
|
|
|
AcGePoint3d MidPt(AcGePoint3d ptGe1, AcGePoint3d ptGe2)
|
|
{
|
|
return AcGePoint3d((ptGe1.x + ptGe2.x) * 0.5
|
|
, (ptGe1.y + ptGe2.y) * .5
|
|
, (ptGe1.z + ptGe2.z) * .5);
|
|
}
|
|
|
|
Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt, AcDbDatabase* pDb = NULL, bool bClose = true)
|
|
{
|
|
if (pDb == NULL)
|
|
pDb = acdbHostApplicationServices()->workingDatabase();
|
|
|
|
Acad::ErrorStatus es;
|
|
|
|
AcDbBlockTable* pTbl = NULL;
|
|
if (Acad::eOk == (es = pDb->getBlockTable(pTbl, AcDb::kForRead)))
|
|
{
|
|
AcDbBlockTableRecord* pBTR = NULL;
|
|
if (Acad::eOk == (es = pTbl->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite)))
|
|
{
|
|
es = pBTR->appendAcDbEntity(pEnt);
|
|
if (bClose) pEnt->close();
|
|
|
|
pBTR->close();
|
|
}
|
|
pTbl->close();
|
|
}
|
|
return es;
|
|
}
|
|
|
|
bool createRegion(const AcDbVoidPtrArray& curveSegments, AcDbVoidPtrArray& regions)
|
|
{
|
|
Acad::ErrorStatus es;
|
|
if ( (es = AcDbRegion::createFromCurves(curveSegments, regions) ) != Acad::eOk)
|
|
{
|
|
acutPrintf(_T("\ncreateFromCurves failed:%d."),es);
|
|
return false;
|
|
}
|
|
|
|
if (regions.isEmpty())
|
|
{
|
|
acutPrintf(_T("\n result is empty."));
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
AcDbRegion* createRegion(AcDbEntity *pEnt)
|
|
{
|
|
AcDbVoidPtrArray arr, segs;
|
|
|
|
arr.append(pEnt);
|
|
|
|
if (!createRegion(arr, segs))
|
|
{
|
|
return NULL;
|
|
}
|
|
return (AcDbRegion*)segs[0];
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
}
|
|
p->makeClosed();
|
|
return p;
|
|
}
|
|
}
|
|
|
|
// 把region变换到以 vtNormal为法向,以ptOnPlan为中心的面上,并且, 将region上的点ptOnRegion与平面中心点ptOnPlan对齐
|
|
AECDLLIMPEXP void GiDrawUtility::transfromRegion(AcDbRegion *pRegion
|
|
, const AcGePoint3d &ptOnRegion
|
|
, const AcGeVector3d &vtNormal
|
|
, const AcGePoint3d &ptOnPlan)
|
|
{
|
|
AcGePlane plan;
|
|
plan.set(ptOnPlan, vtNormal);
|
|
AcGePoint3d pt0, pt1, pt2;
|
|
plan.get(pt0, pt1, pt2);
|
|
|
|
AcGeMatrix3d xform;
|
|
xform.setToPlaneToWorld(plan);
|
|
|
|
// 把region转到此面上
|
|
pRegion->transformBy(xform);
|
|
|
|
// 把 region 上的点也转到面上
|
|
AcGePoint3d pt(ptOnRegion);
|
|
pt.transformBy(xform);
|
|
|
|
// 再把region在面上平移
|
|
AcGeVector3d vtm = ptOnPlan - pt;
|
|
if (!vtm.isZeroLength())
|
|
{
|
|
xform.setToIdentity();
|
|
xform.setToTranslation(ptOnPlan - pt);
|
|
pRegion->transformBy(xform);
|
|
}
|
|
}
|
|
|
|
AECDLLIMPEXP AcGeMatrix3d GiDrawUtility::RotateAndMove(const AcGeVector3d &vtOrig
|
|
, const AcGePoint3d &ptOrig
|
|
, const AcGeVector3d &vtDist
|
|
, const AcGePoint3d &ptDist)
|
|
{
|
|
AcGeVector3d _vtOrig(vtOrig);
|
|
AcGeVector3d _vtDist(vtDist);
|
|
_vtOrig *= 1;// 保证长度不为0
|
|
_vtDist *= 1;// 保证长度不为0
|
|
AcGeMatrix3d mat(AcGeMatrix3d::kIdentity);
|
|
//mat = _vtDist.rotateTo(_vtOrig);
|
|
mat = _vtOrig.rotateTo(_vtDist);
|
|
mat.setTranslation(ptDist - ptOrig);
|
|
return mat;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawLoft(const AcDbRegion *pTop
|
|
, const AcDbRegion *pBottom
|
|
, const AcDbCurve *pLine)
|
|
{
|
|
AcDbRegion *_pTop = (AcDbRegion*)pTop->clone();
|
|
AcDbRegion *_pBottom = (AcDbRegion*)pBottom->clone();
|
|
|
|
AcDbCurve *_pLine(NULL);
|
|
if (pLine)
|
|
_pLine = (AcDbCurve *)pLine->clone();
|
|
|
|
AcArray<AcDbEntity*> arGuides;
|
|
|
|
AcArray<AcDbEntity*> arSections;
|
|
arSections.append(_pTop);
|
|
arSections.append(_pBottom);
|
|
AcDbLoftOptions op;
|
|
|
|
AcDb3dSolid *pEnt = new AcDb3dSolid;
|
|
if (pEnt->createLoftedSolid(arSections, arGuides, _pLine, op) != Acad::eOk)
|
|
{
|
|
DELETE_PTR(pEnt);
|
|
DELETE_PTR(_pTop);
|
|
DELETE_PTR(_pBottom);
|
|
DELETE_PTR(_pLine);
|
|
return NULL;
|
|
}
|
|
|
|
DELETE_PTR(_pTop);
|
|
DELETE_PTR(_pBottom);
|
|
DELETE_PTR(_pLine);
|
|
|
|
return pEnt;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawLoft(const AcDbCurve *pTop
|
|
, const AcDbCurve *pBottom
|
|
, const AcDbCurve *pLine)
|
|
{
|
|
if (!pTop || !pBottom || !pLine) return NULL;
|
|
|
|
AcDbCurve *_pTop = (AcDbCurve*)pTop->clone();
|
|
AcDbCurve *_pBottom = (AcDbCurve*)pBottom->clone();
|
|
AcDbCurve *_pLine = (AcDbCurve*)pLine->clone();
|
|
|
|
AcDbRegion *pRegT = createRegion(_pTop);
|
|
AcDbRegion *pRegB = createRegion(_pBottom);
|
|
|
|
if (!pRegT || !pRegB) return NULL;
|
|
|
|
AcDbEntity *p = DrawLoft(pRegT, pRegB, pLine);
|
|
|
|
DELETE_PTR(pRegT);
|
|
DELETE_PTR(pRegB);
|
|
DELETE_PTR(_pTop);
|
|
DELETE_PTR(_pBottom);
|
|
DELETE_PTR(_pLine);
|
|
|
|
return p;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawRevolve(const AcDbLine& lnAxis
|
|
, const AcDbRegion *pReg)
|
|
{
|
|
AcDbRegion *_pReg = (AcDbRegion*)pReg->clone();
|
|
|
|
AcDbRevolveOptions op;
|
|
AcDb3dSolid *p = new AcDb3dSolid;
|
|
if (p->createRevolvedSolid(_pReg
|
|
, lnAxis.startPoint()
|
|
, lnAxis.endPoint() - lnAxis.startPoint()
|
|
, 2 * PI
|
|
, .0
|
|
, op) != Acad::eOk)
|
|
{
|
|
DELETE_PTR(p);
|
|
DELETE_PTR(_pReg);
|
|
return NULL;
|
|
}
|
|
|
|
DELETE_PTR(_pReg);
|
|
return p;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawRevolve(const AcDbLine& lnAxis
|
|
, const AcDbCurve *pCurve)
|
|
{
|
|
if (!pCurve) return NULL;
|
|
|
|
AcDbCurve *_pC = (AcDbCurve*)pCurve->clone();
|
|
AcDbRegion *pReg = createRegion(_pC);
|
|
if (!pReg)
|
|
{
|
|
//DELETE_PTR(_pC);
|
|
_pC->setColorIndex(1);
|
|
AddToModelSpace(_pC);
|
|
return NULL;
|
|
}
|
|
AcDbEntity *p = DrawRevolve(lnAxis, pReg);
|
|
|
|
DELETE_PTR(pReg);
|
|
DELETE_PTR(_pC);
|
|
return p;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawRevolve(const AcDbLine& lnAxis
|
|
, const AcGePoint3dArray& arSectionPtrs)
|
|
{
|
|
AcDb3dPolyline *pPL = create3DPolyline(arSectionPtrs.asArrayPtr()
|
|
, arSectionPtrs.length());
|
|
if (!pPL) return NULL;
|
|
return DrawRevolve(lnAxis, pPL);
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawCone(const AcGePoint3d &ptPos
|
|
, const AcGeVector3d &vtMove
|
|
, const double &Tr
|
|
, const double &Br
|
|
, const double &H
|
|
, const double &xOffset)
|
|
{
|
|
AcGePoint3d ptBottom(AcGePoint3d::kOrigin);
|
|
AcGePoint3d ptTop(ptBottom + xOffset * AcGeVector3d::kXAxis);
|
|
ptTop.z = H;
|
|
|
|
AcDbCircle cirB(ptBottom, AcGeVector3d::kZAxis, Br);
|
|
AcDbCircle cirT(ptTop, AcGeVector3d::kZAxis, Tr);
|
|
AcDbLine line(ptBottom, ptTop);
|
|
|
|
AcDbEntity *p = DrawLoft(&cirT, &cirB, &line);
|
|
|
|
if (!p) return NULL;
|
|
|
|
p->transformBy(RotateAndMove(AcGeVector3d::kZAxis
|
|
, ptBottom
|
|
, vtMove, ptPos ));
|
|
|
|
return p;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawExclude(const AcGePoint3dArray& arSectionPtrs, const AcGeVector3d &vtPath)
|
|
{
|
|
AcDb3dPolyline *pPL = create3DPolyline(arSectionPtrs.asArrayPtr(), arSectionPtrs.length());
|
|
if (!pPL) return NULL;
|
|
return DrawExclude(pPL, vtPath);
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawMesh( const Adesk::UInt32 &rows
|
|
, const Adesk::UInt32 &columns
|
|
, const AcGePoint3d *pVertexList
|
|
, bool bHasSeal /* = true*/)
|
|
{
|
|
// 去掉头尾两个无效面
|
|
int first = 1, last = rows - 1;
|
|
if (!bHasSeal)
|
|
{
|
|
first = 0;
|
|
last = rows;
|
|
}
|
|
|
|
// 取第一个点和最后一个点连成一条线
|
|
AcDbLine line(pVertexList[0], pVertexList[rows * columns - 1]);
|
|
|
|
AcGePoint3d *pSection = new AcGePoint3d[columns];
|
|
AcArray<AcDbEntity*> vecPLs, vecGuides;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
::memset(pSection, 0, sizeof(AcGePoint3d)*columns);
|
|
::memcpy(pSection, pVertexList + i * columns, sizeof(AcGePoint3d)*columns);
|
|
AcDb3dPolyline *p3dPL = create3DPolyline(pSection, columns);
|
|
vecPLs.append(p3dPL);
|
|
}
|
|
|
|
AcDbLoftOptions op;
|
|
op.setRuled(true);
|
|
op.setNormal(AcDbLoftOptions::kUseDraftAngles);
|
|
AcDb3dSolid *pEnt = new AcDb3dSolid;
|
|
if (pEnt->createLoftedSolid(vecPLs, vecGuides, &line, op) != Acad::eOk)
|
|
{
|
|
DELETE_PTR(pEnt);
|
|
return NULL;
|
|
}
|
|
|
|
delete [] pSection;
|
|
for (size_t i = 0; i < vecPLs.length(); ++i)
|
|
{
|
|
if (vecPLs[i]) DELETE_PTR(vecPLs[i]);
|
|
}
|
|
return pEnt;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawExclude(const AcDbRegion *pReg
|
|
, const AcGePoint3d &ptInReg
|
|
, const AcGeVector3d &vtPath)
|
|
{
|
|
AcDbRegion *_pReg = (AcDbRegion*)pReg->clone();
|
|
|
|
AcDbLine line;
|
|
line.setStartPoint(ptInReg);
|
|
line.setEndPoint(ptInReg + vtPath);
|
|
|
|
AcDb3dSolid *p = new AcDb3dSolid;
|
|
if (p->extrudeAlongPath(_pReg, &line) != Acad::eOk)
|
|
{
|
|
DELETE_PTR(p);
|
|
DELETE_PTR(_pReg);
|
|
return NULL;
|
|
}
|
|
|
|
DELETE_PTR(_pReg);
|
|
return p;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawExclude(const AcDbCurve *pCurve, const AcGeVector3d &vtPath)
|
|
{
|
|
AcDbCurve *_pCurve = (AcDbCurve*)pCurve->clone();
|
|
AcDbRegion *pReg = createRegion(_pCurve);
|
|
if (!pReg)
|
|
{
|
|
DELETE_PTR(_pCurve);
|
|
return NULL;
|
|
}
|
|
|
|
AcDbExtents ext;
|
|
pReg->getGeomExtents(ext);
|
|
AcGePoint3d pt1(ext.maxPoint()), pt2(ext.minPoint());
|
|
AcGePoint3d ptS((pt1.x + pt2.x) * .5, (pt1.y + pt2.y) * .5, (pt1.z + pt2.z) * .5);
|
|
|
|
AcDbEntity *p = DrawExclude(pReg, ptS, vtPath);
|
|
DELETE_PTR(pReg);
|
|
DELETE_PTR(_pCurve);
|
|
return p;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawBox(const AcGePoint3d &ptPos
|
|
, const AcGeVector3d &vtMove
|
|
, const double &X
|
|
, const double &Y
|
|
, const double &Z)
|
|
{
|
|
AcDb3dSolid *pSolid = new AcDb3dSolid();
|
|
if (!pSolid) return NULL;
|
|
if (Acad::eOk != pSolid->createBox(X, Y, Z))
|
|
return NULL;
|
|
|
|
pSolid->transformBy(
|
|
RotateAndMove(AcGeVector3d::kZAxis
|
|
, AcGePoint3d::kOrigin
|
|
, vtMove, ptPos)
|
|
);
|
|
|
|
return pSolid;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawSphere(const AcGePoint3d &ptCenter
|
|
, const double &dRadius)
|
|
{
|
|
AcDb3dSolid *pSolid = new AcDb3dSolid();
|
|
if (!pSolid) return NULL;
|
|
if (Acad::eOk != pSolid->createSphere(dRadius))
|
|
return NULL;
|
|
|
|
pSolid->transformBy(
|
|
RotateAndMove(AcGeVector3d::kZAxis
|
|
, AcGePoint3d::kOrigin
|
|
, AcGeVector3d::kZAxis, ptCenter)
|
|
);
|
|
|
|
return pSolid;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawPyramid(const AcGePoint3d &ptPos
|
|
, const AcGeVector3d &vtMove
|
|
, const double &Tx
|
|
, const double &Ty
|
|
, const double &Bx
|
|
, const double &By
|
|
, const double &H
|
|
, const double &xOffset)
|
|
{
|
|
// 构建两个四边形region
|
|
AcGePoint3d ptBottom(AcGePoint3d::kOrigin);
|
|
AcGePoint3d ptTop(ptBottom + xOffset * AcGeVector3d::kXAxis);
|
|
ptTop.z = H;
|
|
|
|
double xt(Tx * .5), yt(Ty * .5), xb(Bx * .5), yb(By * .5);
|
|
AcGePoint2d ptGeTop[4] = {
|
|
AcGePoint2d(-xt, -yt)
|
|
,AcGePoint2d(-xt, yt)
|
|
,AcGePoint2d(xt, yt)
|
|
,AcGePoint2d(xt, -yt) };
|
|
|
|
AcGePoint2d ptGeBottom[4] = {
|
|
AcGePoint2d(-xb, -yb)
|
|
,AcGePoint2d(-xb, yb)
|
|
,AcGePoint2d(xb, yb)
|
|
,AcGePoint2d(xb, -yb) };
|
|
|
|
AcGeMatrix3d mat;
|
|
|
|
AcDbPolyline plTop;
|
|
plTop.addVertexAt(0, ptGeTop[0]);
|
|
plTop.addVertexAt(1, ptGeTop[1]);
|
|
plTop.addVertexAt(2, ptGeTop[2]);
|
|
plTop.addVertexAt(3, ptGeTop[3]);
|
|
plTop.setClosed(Adesk::kTrue);
|
|
mat.setToTranslation(ptTop - AcGePoint3d::kOrigin);
|
|
plTop.transformBy(mat);
|
|
|
|
AcDbPolyline plBottom;
|
|
plBottom.addVertexAt(0, ptGeBottom[0]);
|
|
plBottom.addVertexAt(1, ptGeBottom[1]);
|
|
plBottom.addVertexAt(2, ptGeBottom[2]);
|
|
plBottom.addVertexAt(3, ptGeBottom[3]);
|
|
plBottom.setClosed(Adesk::kTrue);
|
|
mat.setToTranslation(ptBottom - AcGePoint3d::kOrigin);
|
|
plBottom.transformBy(mat);
|
|
|
|
AcDbLine line(ptBottom, ptTop);
|
|
|
|
AcDbEntity *p = DrawLoft(&plTop, &plBottom, &line);
|
|
|
|
if (!p) return NULL;
|
|
|
|
p->transformBy(RotateAndMove(AcGeVector3d::kZAxis
|
|
, ptBottom
|
|
, vtMove, ptPos));
|
|
|
|
return p;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawTydf(const AcGePoint3d &ptPos
|
|
, const AcGeVector3d &vtMove
|
|
, const double &Tr
|
|
, const double &Bx
|
|
, const double &By
|
|
, const double &H
|
|
, const double &xOffset
|
|
, BOOL bIsTfdy)
|
|
{
|
|
AcGePoint3d ptBottom(AcGePoint3d::kOrigin);
|
|
AcGePoint3d ptTop(ptBottom + xOffset * AcGeVector3d::kXAxis);
|
|
ptTop.z = H;
|
|
|
|
double xb(Bx * .5), yb(By * .5);
|
|
AcGePoint2d ptGeBottom[4] = {
|
|
AcGePoint2d(-xb, -yb)
|
|
,AcGePoint2d(-xb, yb)
|
|
,AcGePoint2d(xb, yb)
|
|
,AcGePoint2d(xb, -yb) };
|
|
|
|
AcGeMatrix3d mat;
|
|
|
|
AcDbCircle cir(ptTop, AcGeVector3d::kZAxis, Tr);
|
|
|
|
AcDbPolyline plBottom;
|
|
plBottom.addVertexAt(0, ptGeBottom[0]);
|
|
plBottom.addVertexAt(1, ptGeBottom[1]);
|
|
plBottom.addVertexAt(2, ptGeBottom[2]);
|
|
plBottom.addVertexAt(3, ptGeBottom[3]);
|
|
plBottom.setClosed(Adesk::kTrue);
|
|
mat.setToTranslation(ptBottom - AcGePoint3d::kOrigin);
|
|
plBottom.transformBy(mat);
|
|
|
|
AcDbLine line(ptBottom, ptTop);
|
|
|
|
AcDbEntity *p = NULL;
|
|
if (bIsTfdy)
|
|
{
|
|
AcGeVector3d vt(0,0,H);
|
|
AcGeMatrix3d xForm1;
|
|
xForm1.setToTranslation(vt);
|
|
plBottom.transformBy(xForm1);
|
|
ptBottom.transformBy(xForm1);
|
|
|
|
xForm1.invert();
|
|
cir.transformBy(xForm1);
|
|
ptTop.transformBy(xForm1);
|
|
|
|
p = DrawLoft(&plBottom, &cir, &line);
|
|
}
|
|
else
|
|
{
|
|
p = DrawLoft(&cir, &plBottom, &line);
|
|
}
|
|
if (!p) return NULL;
|
|
|
|
p->transformBy(RotateAndMove(AcGeVector3d::kZAxis
|
|
, ptBottom
|
|
, vtMove, ptPos));
|
|
|
|
return p;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawCylinder(const AcGePoint3d &ptFr
|
|
, const AcGePoint3d &ptTo
|
|
, const double &dRadius)
|
|
{
|
|
return DrawPipe(ptFr, ptTo, dRadius, 0.);
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawCirTorus(const AcGePoint3d &ptCenter
|
|
, const AcGeVector3d &vtNormal
|
|
, const double &majorRadius /* 大半径 */
|
|
, const double &minorRadius /* 小半径,大半径减小半径是管子直径 */
|
|
, const double &startAngle
|
|
, const double &endAngle)
|
|
{
|
|
AcDbArc arc(ptCenter, vtNormal, (majorRadius + minorRadius) * .5, startAngle, endAngle);
|
|
AcDbCircle cir(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, (majorRadius - minorRadius) * .5);
|
|
return DrawPipe(&arc, &cir, AcGePoint3d::kOrigin);
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawRectTorus(const AcGePoint3d &ptCenter
|
|
, const AcGeVector3d &vtNormal
|
|
, const double &majorRadius /* 大半径 */
|
|
, const double &minorRadius /* 小半径 */
|
|
, const double &height /* 大半径减小半径是正方形的宽,这个参数是高 */
|
|
, const double &startAngle
|
|
, const double &endAngle)
|
|
{
|
|
AcDbArc arc(ptCenter, vtNormal, (majorRadius + minorRadius) * .5, startAngle, endAngle);
|
|
|
|
double dW = (majorRadius - minorRadius) * .5;
|
|
double xt(dW * .5), yt(height * .5);
|
|
AcGePoint2d ptGeTop[4] = {
|
|
AcGePoint2d(-xt, -yt)
|
|
,AcGePoint2d(-xt, yt)
|
|
,AcGePoint2d(xt, yt)
|
|
,AcGePoint2d(xt, -yt) };
|
|
AcDbPolyline plTop;
|
|
plTop.addVertexAt(0, ptGeTop[0]);
|
|
plTop.addVertexAt(1, ptGeTop[1]);
|
|
plTop.addVertexAt(2, ptGeTop[2]);
|
|
plTop.addVertexAt(3, ptGeTop[3]);
|
|
plTop.setClosed(Adesk::kTrue);
|
|
|
|
return DrawPipe(&arc, &plTop, AcGePoint3d::kOrigin);
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawDish(const double &dH /*小半径*/
|
|
, const double &dD /* 大直径 */
|
|
, const AcGePoint3d &axisPnt
|
|
, const AcGeVector3d &axisDir)
|
|
{
|
|
// 先构造一个(zox)面, 圆心为原点的1/4椭圆, 然后绕Z轴旋转
|
|
// 再转换到 axisPnt点,其中心轴(原Z轴)指向axisDir
|
|
AcDbEllipse elArc(AcGePoint3d::kOrigin
|
|
, -1 * AcGeVector3d::kYAxis
|
|
, AcGeVector3d::kXAxis * dD * .5
|
|
, 2 * dH / dD
|
|
, 0
|
|
, .5 * PI);
|
|
|
|
AcDbLine line1(AcGePoint3d::kOrigin, AcGePoint3d(dD * .5, 0, 0));
|
|
AcDbLine line2(AcGePoint3d::kOrigin, AcGePoint3d(0, 0, dH));
|
|
|
|
AcDbVoidPtrArray arCurves, arRegs;
|
|
arCurves.append(&line1);
|
|
arCurves.append(&line2);
|
|
arCurves.append(&elArc);
|
|
if (AcDbRegion::createFromCurves(arCurves, arRegs) != Acad::eOk)
|
|
return NULL;
|
|
if (arRegs.isEmpty()) return NULL;
|
|
|
|
AcDbEntity *p = DrawRevolve(
|
|
AcDbLine(AcGePoint3d::kOrigin , AcGePoint3d::kOrigin + AcGeVector3d::kZAxis * 1)
|
|
, (AcDbRegion*)arRegs[0]);
|
|
|
|
if (!p) return NULL;
|
|
|
|
AcGeMatrix3d mat = RotateAndMove(AcGeVector3d::kZAxis, AcGePoint3d::kOrigin, axisDir, axisPnt);
|
|
p->transformBy(mat);
|
|
|
|
AcDbEntity *pDel((AcDbEntity*)arRegs[0]);
|
|
DELETE_PTR(pDel);
|
|
return p;
|
|
}
|
|
|
|
AcDbEntity* GiDrawUtility::DrawPipe(const AcGePoint3d& ptFrom
|
|
, const AcGePoint3d& ptTo
|
|
, const double &dRadius
|
|
, const double &dThick
|
|
, const int &nSegs /*= 20*/)
|
|
{
|
|
AcDbCircle Cir1(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, dRadius);
|
|
|
|
if (!createRegion(&Cir1)) return NULL;
|
|
AcDbRegion *pBig = createRegion(&Cir1);
|
|
if (!pBig) return NULL;
|
|
|
|
AcDbRegion *pSml(NULL);
|
|
if (!EQUAL_ZERO(dThick))
|
|
{
|
|
AcDbCircle Cir2(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, dRadius - dThick);
|
|
pSml = createRegion(&Cir2);
|
|
if (!pSml) return NULL;
|
|
}
|
|
|
|
// 这里做一个布尔减
|
|
if (pBig && pSml)
|
|
{
|
|
if (pBig->booleanOper(AcDb::kBoolSubtract, pSml) != Acad::eOk)
|
|
{
|
|
acutPrintf(_T("\n DrawPipe booleanOper failed."));
|
|
DELETE_PTR(pBig);
|
|
DELETE_PTR(pSml);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
AcDbRegion *pRegion(pBig);
|
|
AcDbLine path(ptTo, ptFrom);
|
|
AcDbEntity *pSolid = DrawPipe(&path, pRegion, AcGePoint3d::kOrigin);
|
|
DELETE_PTR(pRegion);
|
|
return pSolid;
|
|
}
|
|
|
|
AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve* pCurve
|
|
, const AcDbCurve* pPoly
|
|
, const AcGePoint3d& ptCenInRgn)
|
|
{
|
|
if (!pPoly || !pCurve) return NULL;
|
|
AcDbCurve *pClonePoly = (AcDbCurve*)pPoly->clone();
|
|
AcDbRegion *pRegion = createRegion(pClonePoly);
|
|
AcDbEntity *pSolid = DrawPipe(pCurve, pRegion, ptCenInRgn);
|
|
DELETE_PTR(pRegion);
|
|
DELETE_PTR(pClonePoly);
|
|
return pSolid;
|
|
}
|
|
|
|
// 分段长度大于max取max,小于max,取min
|
|
static int spliteCurve(const AcDbCurve *pCurve, const double &max, const double &min, AcDbVoidPtrArray &ar)
|
|
{
|
|
Acad::ErrorStatus es;
|
|
|
|
double dEnd = 0.0, dLen = 0.0, dSplitLen = 100000.0;
|
|
es = pCurve->getEndParam(dEnd);
|
|
if (es != Acad::eOk) return 0;
|
|
|
|
es = pCurve->getDistAtParam(dEnd, dLen);
|
|
if (es != Acad::eOk) return 0;
|
|
|
|
if (dLen > max)
|
|
dSplitLen = max;
|
|
else
|
|
dSplitLen = min;
|
|
|
|
|
|
double dMax(dSplitLen), dPrec(10e-4);
|
|
AcGePoint3d ptStart(AcGePoint3d::kOrigin), ptEnd(AcGePoint3d::kOrigin), pt(AcGePoint3d::kOrigin);
|
|
|
|
es = pCurve->getPointAtDist(.0, ptStart);
|
|
if (es != Acad::eOk) return 0;
|
|
|
|
es = pCurve->getEndPoint(ptEnd);
|
|
if (es != Acad::eOk) return 0;
|
|
|
|
int quotient((int)(dLen / dMax));
|
|
double remainder(fmod(dLen, dMax));
|
|
if (remainder < dPrec) quotient -= 1;
|
|
|
|
AcGePoint3dArray arPts;
|
|
|
|
if (dLen - dMax > dPrec)
|
|
{
|
|
for (int i = 0; i < quotient; ++i)
|
|
{
|
|
if (pCurve->getPointAtDist((i + 1) * dMax, pt) != Acad::eOk) continue;
|
|
arPts.append(pt);
|
|
}
|
|
}
|
|
|
|
if (arPts.isEmpty()) return 0;
|
|
|
|
es = pCurve->getSplitCurves(arPts, ar);
|
|
|
|
return ar.length();
|
|
}
|
|
|
|
static void deleteContainerOfArx(AcDbVoidPtrArray &ss)
|
|
{
|
|
while(!ss.isEmpty())
|
|
{
|
|
AcDbEntity *p = (AcDbEntity *)ss.last();
|
|
ss.removeLast();
|
|
delete p;
|
|
}
|
|
}
|
|
|
|
AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve* pCurve
|
|
, const AcDbPolyline* pPoly
|
|
, const AcGePoint3d& ptCenInRgn)
|
|
{
|
|
return DrawPipe(pCurve, (AcDbCurve*)pPoly, ptCenInRgn);
|
|
}
|
|
|
|
AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve *pCurve, double dR)
|
|
{
|
|
if (!pCurve) return NULL;
|
|
|
|
//开始切向量,向内
|
|
AcGePoint3d ptS;
|
|
AcGeVector3d vtS;
|
|
pCurve->getStartPoint(ptS);
|
|
if (Acad::eOk != pCurve->getFirstDeriv(ptS, vtS)) return NULL;
|
|
|
|
AcDbCircle cir;
|
|
cir.setNormal(vtS);
|
|
cir.setCenter(ptS);
|
|
cir.setRadius(dR);
|
|
|
|
AcDbVoidPtrArray arCurPts, arRegs;
|
|
arCurPts.append(&cir);
|
|
|
|
AcDbRegion::createFromCurves(arCurPts, arRegs);
|
|
if (arRegs.isEmpty()) return NULL;
|
|
|
|
AcDbRegion *pReg = (AcDbRegion *)arRegs.first();
|
|
if (!pReg) return NULL;
|
|
|
|
Acad::ErrorStatus es;
|
|
AcDb3dSolid *pSolid = new AcDb3dSolid();
|
|
|
|
//当时闭合Polyline线时,extrudeAlongPath结果三维和CAD命令Extrude比较变小;
|
|
//调整为createSweptSolid 和 CAD Extrude 命令结果一致
|
|
AcDbPolyline *pPl = AcDbPolyline::cast(pCurve);
|
|
if (pPl != NULL && pPl->isClosed())
|
|
{
|
|
AcDbSweepOptions sweepOp;
|
|
es = pSolid->createSweptSolid((AcDbEntity *)pReg, (AcDbEntity *)pCurve, sweepOp);
|
|
if (es != Acad::eOk)
|
|
{
|
|
acutPrintf(_T("\n拉伸错误:%d."), es);
|
|
DELETE_PTR(pSolid);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#ifndef ZWCAD
|
|
es = pSolid->extrudeAlongPath(pReg, pCurve);
|
|
DELETE_PTR(pReg);
|
|
if (es != Acad::eOk)
|
|
{
|
|
DELETE_PTR(pSolid);
|
|
|
|
// 处理 CAD 3D 实体体量不能大于 12000问题
|
|
// 拉伸 扫掠 实体,路径长不能大于 120000 ,圆,弧 除外
|
|
AcDbVoidPtrArray arCuvs;
|
|
spliteCurve(pCurve, 100000., 10000., arCuvs);
|
|
|
|
AcGePoint3d ptStart(AcGePoint3d::kOrigin);
|
|
AcDbVoidPtrArray arSolids;
|
|
for (int i = 0; i < arCuvs.length(); ++i)
|
|
{
|
|
AcDbCurve *p((AcDbCurve *)arCuvs[i]);
|
|
if (!p) continue;
|
|
|
|
AcDbEntity *pSo(DrawPipe(p, dR));
|
|
if (pSo)
|
|
arSolids.append(pSo);
|
|
}
|
|
deleteContainerOfArx(arCuvs);
|
|
|
|
if (!arSolids.isEmpty())
|
|
{
|
|
pSolid = (AcDb3dSolid *)((AcDbEntity *)arSolids.first())->clone();
|
|
for (int i(1); i < arSolids.length(); ++i)
|
|
es = pSolid->booleanOper(AcDb::kBoolUnite, (AcDb3dSolid *)arSolids[i]);
|
|
deleteContainerOfArx(arSolids);
|
|
}
|
|
else
|
|
acutPrintf(_T("\n拉伸错误."));
|
|
}
|
|
#else
|
|
AcDbSweepOptions sweepOp;
|
|
es = pSolid->createSweptSolid((AcDbEntity *)pReg, (AcDbEntity *)pCurve, sweepOp);
|
|
DELETE_PTR(pReg);
|
|
if (es != Acad::eOk)
|
|
{
|
|
DELETE_PTR(pSolid);
|
|
acutPrintf(_T("\n扫掠错误:%d."), es);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return pSolid;
|
|
|
|
}
|
|
|
|
AcDbEntity *GiDrawUtility::DrawPipe(
|
|
const AcDbCurve *pCurve
|
|
, const AcDbRegion *pRegion
|
|
, const AcGePoint3d &ptCenInRgn)
|
|
{
|
|
if (!pRegion || !pCurve) return NULL;
|
|
|
|
AcGePoint3d ptStart(AcGePoint3d::kOrigin);
|
|
if (pCurve->getStartPoint(ptStart) != Acad::eOk) return NULL;
|
|
AcGePoint3d ptEnd;
|
|
if (pCurve->getEndPoint(ptEnd) != Acad::eOk) return NULL;
|
|
|
|
AcGeVector3d vtNormal(AcGeVector3d::kIdentity);
|
|
if (pCurve->getFirstDeriv(ptStart, vtNormal) != Acad::eOk) return NULL;
|
|
|
|
AcDbRegion *pCloneRegion = (AcDbRegion*)pRegion->clone();
|
|
transfromRegion(pCloneRegion, ptCenInRgn, vtNormal, ptStart);
|
|
|
|
Acad::ErrorStatus es;
|
|
AcDb3dSolid *pSolid = new AcDb3dSolid();
|
|
|
|
//当时闭合Polyline线时,extrudeAlongPath结果三维和CAD命令Extrude比较变小;
|
|
//调整为createSweptSolid 和 CAD Extrude 命令结果一致
|
|
AcDbPolyline* pPl = AcDbPolyline::cast(pCurve);
|
|
if (pPl != NULL && pPl->isClosed() )
|
|
{
|
|
AcDbSweepOptions sweepOp;
|
|
es = pSolid->createSweptSolid((AcDbEntity*)pCloneRegion,(AcDbEntity*)pCurve,sweepOp);
|
|
DELETE_PTR(pCloneRegion);
|
|
if (es != Acad::eOk)
|
|
{
|
|
DELETE_PTR(pSolid);
|
|
acutPrintf(_T("\n拉伸错误:%d."), es);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#ifndef ZWCAD
|
|
es = pSolid->extrudeAlongPath(pCloneRegion, pCurve);
|
|
DELETE_PTR(pCloneRegion);
|
|
if (es != Acad::eOk)
|
|
{
|
|
DELETE_PTR(pSolid);
|
|
|
|
// 处理 CAD 3D 实体体量不能大于 12000问题
|
|
// 拉伸 扫掠 实体,路径长不能大于 120000 ,圆,弧 除外
|
|
AcDbVoidPtrArray arCuvs;
|
|
spliteCurve(pCurve, 100000., 10000., arCuvs);
|
|
|
|
AcGePoint3d ptStart(AcGePoint3d::kOrigin);
|
|
AcDbVoidPtrArray arSolids;
|
|
for (int i = 0; i < arCuvs.length(); ++i)
|
|
{
|
|
AcDbCurve *p((AcDbCurve *)arCuvs[i]);
|
|
if (!p) continue;
|
|
AcDbEntity *pSo(DrawPipe(p, pRegion, ptCenInRgn));
|
|
if (pSo)
|
|
arSolids.append(pSo);
|
|
}
|
|
deleteContainerOfArx(arCuvs);
|
|
|
|
if (!arSolids.isEmpty())
|
|
{
|
|
pSolid = (AcDb3dSolid *)((AcDbEntity *)arSolids.first())->clone();
|
|
for (int i(1); i < arSolids.length(); ++i)
|
|
es = pSolid->booleanOper(AcDb::kBoolUnite, (AcDb3dSolid *)arSolids[i]);
|
|
deleteContainerOfArx(arSolids);
|
|
}
|
|
else
|
|
acutPrintf(_T("\n拉伸错误."));
|
|
}
|
|
#else
|
|
AcDbSweepOptions sweepOp;
|
|
es = pSolid->createSweptSolid((AcDbEntity *)pCloneRegion, (AcDbEntity *)pCurve, sweepOp);
|
|
DELETE_PTR(pCloneRegion);
|
|
if (es != Acad::eOk)
|
|
{
|
|
DELETE_PTR(pSolid);
|
|
acutPrintf(_T("\n扫掠错误:%d."), es);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return pSolid;
|
|
}
|
|
|