1096 lines
25 KiB
C++
1096 lines
25 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, SH Software Co. Ltd.
|
|
// = FileName : XExplodeStream 类
|
|
// = Version : ver2.0
|
|
// = Author : zjq
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: XExplodeStream 定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "XExplodeStream.h"
|
|
#include "XDbObject.h"
|
|
#include "XPathParser.h"
|
|
#include "dbsol3d.h"
|
|
#include "dbregion.h"
|
|
#include "XTrianglePface.h"
|
|
#include "XHoleModel.h"
|
|
#include "DList.h"
|
|
#include "XPolygonEx.h"
|
|
#include "dbhatch.h"
|
|
#include "XGlobalFunc.h"
|
|
#include "XGlobalCurveFunc.h"
|
|
|
|
BOOL XExplodeStream::m_bFullExplode = FALSE;
|
|
BOOL XExplodeStream::m_bExportTch4 = FALSE;
|
|
|
|
XExplodeStream::XExplodeStream(AcDbVoidPtrArray &entArray)
|
|
{
|
|
m_pEntSet = &entArray;
|
|
m_nColor = 256;
|
|
m_bIsDragging = Adesk::kFalse;
|
|
|
|
//add by zjq on 100629 TArch8.5
|
|
m_crColor = AcCmColor();
|
|
}
|
|
|
|
XExplodeStream::~XExplodeStream()
|
|
{
|
|
|
|
}
|
|
|
|
BOOL XExplodeStream::IsFullExplode() const
|
|
{
|
|
return m_bFullExplode;
|
|
}
|
|
|
|
BOOL XExplodeStream::IsExportTch4() const
|
|
{
|
|
return m_bExportTch4;
|
|
}
|
|
|
|
AcDbVoidPtrArray * XExplodeStream::GetEntitySet()
|
|
{
|
|
return m_pEntSet;
|
|
}
|
|
|
|
Adesk::UInt16 XExplodeStream::GetColor() const
|
|
{
|
|
return m_nColor;
|
|
}
|
|
|
|
void XExplodeStream::SetColor(Adesk::UInt16 nColor)
|
|
{
|
|
m_nColor = nColor;
|
|
}
|
|
|
|
//add by zjq on 100629 TArch8.5
|
|
//COLORREF XExplodeStream::GetTrueColor() const
|
|
AcCmColor XExplodeStream::GetTrueColor() const
|
|
{
|
|
return m_crColor;
|
|
}
|
|
|
|
//void XExplodeStream::SetTrueColor(COLORREF crRef)
|
|
void XExplodeStream::SetTrueColor(AcCmColor crRef)
|
|
{
|
|
m_crColor = crRef;
|
|
}
|
|
|
|
// 设置图层,线型,颜色
|
|
void XExplodeStream::SetPropertiesFrom(const AcDbEntity *pEnt)
|
|
{
|
|
ASSERT(pEnt);
|
|
|
|
m_idLinetype = pEnt->linetypeId();
|
|
m_idLayer = pEnt->layerId();
|
|
m_nColor = pEnt->colorIndex();
|
|
|
|
#if ARX > 17
|
|
m_idMaterial = pEnt->materialId();
|
|
#endif
|
|
}
|
|
|
|
// 往集合加入实体, 并设置通用的三个属性
|
|
void XExplodeStream::Append(AcDbEntity *pEnt, BOOL bUseAutoProp)
|
|
{
|
|
ASSERT(m_pEntSet);
|
|
|
|
if (bUseAutoProp && IsAutoProp())
|
|
{
|
|
if (!!m_idLayer)
|
|
{
|
|
pEnt->setLayer(m_idLayer);
|
|
}
|
|
|
|
if (!!m_idLinetype)
|
|
{
|
|
pEnt->setLinetype(m_idLinetype);
|
|
}
|
|
|
|
#if ARX > 17
|
|
if (!!m_idMaterial)
|
|
{
|
|
pEnt->setMaterial(m_idMaterial);
|
|
}
|
|
#endif
|
|
|
|
//modify by zjq on 100629
|
|
//pEnt->setColorIndex(m_nColor);
|
|
if (m_crColor == AcCmColor())
|
|
{
|
|
pEnt->setColorIndex(m_nColor);
|
|
}
|
|
else
|
|
{
|
|
pEnt->setColor(m_crColor);
|
|
}
|
|
}
|
|
|
|
m_pEntSet->append(pEnt);
|
|
}
|
|
|
|
BOOL XExplodeStream::MakeBlockInsert(const XPoint &ptBase)
|
|
{
|
|
if (m_pEntSet->isEmpty())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
AcDbBlockTableRecord *pBlockTableRec;
|
|
AcDbObjectId blockTableRecordId,EntId;
|
|
AcDbBlockTable *pBlockTable = NULL;
|
|
AcDbBlockReference *pBlk;
|
|
AcDbEntity *pEnt;
|
|
int i;
|
|
|
|
pBlockTableRec = new AcDbBlockTableRecord();
|
|
pBlockTableRec->setName(_T("*U"));
|
|
|
|
acdbCurDwg()->getBlockTable(pBlockTable,AcDb::kForWrite);
|
|
pBlockTable->add(blockTableRecordId, pBlockTableRec);
|
|
pBlockTable->close();
|
|
|
|
pBlockTableRec->setOrigin(ptBase);
|
|
for (i = 0;i < m_pEntSet->length();i++)
|
|
{
|
|
pEnt = (AcDbEntity *)(*m_pEntSet)[i];
|
|
pBlockTableRec->appendAcDbEntity(EntId,pEnt);
|
|
pEnt->close();
|
|
}
|
|
|
|
pBlockTableRec->close();
|
|
|
|
//insert block
|
|
pBlk = new AcDbBlockReference(ptBase,blockTableRecordId);
|
|
if (!!m_idLayer)
|
|
{
|
|
pBlk ->setLayer(m_idLayer);
|
|
}
|
|
|
|
#if ARX > 17
|
|
if (!!m_idMaterial)
|
|
{
|
|
pBlk->setMaterial(m_idMaterial);
|
|
}
|
|
#endif
|
|
|
|
while (!m_pEntSet->isEmpty())
|
|
{
|
|
m_pEntSet->removeAt(0);
|
|
}
|
|
|
|
m_pEntSet->append(pBlk);
|
|
|
|
pBlockTable = NULL;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void XExplodeStream::DrawEntity(const AcDbEntity &ent)
|
|
{
|
|
AcDbEntity *pEnt = (AcDbEntity *)ent.clone();
|
|
ASSERT(pEnt);
|
|
|
|
m_pEntSet->append(pEnt);
|
|
}
|
|
|
|
void XExplodeStream::Polyline(AcDbPolyline &pline)
|
|
{
|
|
Append((AcDbEntity *)pline.clone());
|
|
}
|
|
|
|
void XExplodeStream::DrawLine(const XLine &ln, double nThickness)
|
|
{
|
|
AcDbLine *line = new AcDbLine(ln.GetStartPoint(), ln.GetEndPoint());
|
|
line->setThickness(nThickness);
|
|
|
|
Append(line);
|
|
}
|
|
|
|
void XExplodeStream::DrawArc(const XArc &ar, double nThickness)
|
|
{
|
|
AcDbArc *pArc = new AcDbArc(ar.GetCenterPt(), ar.GetRadius(), ar.GetStarAngle(), ar.GetEndAngle());
|
|
pArc->setThickness(nThickness);
|
|
|
|
Append(pArc);
|
|
}
|
|
|
|
void XExplodeStream::DrawCircle(const XCircle &cir, double nThickness)
|
|
{
|
|
AcDbCircle *pCir = new AcDbCircle(cir.GetCenterPt(), AcGeVector3d(0,0,1), cir.GetRadius());
|
|
pCir->setThickness(nThickness);
|
|
|
|
Append(pCir);
|
|
}
|
|
|
|
void XExplodeStream::DrawXPoly(const XPoly2D &poly,double nThickness)
|
|
{
|
|
AcDbPolyline *pline = new AcDbPolyline;
|
|
PolyConvert(poly, *pline);
|
|
pline->setThickness(nThickness);
|
|
|
|
Append(pline);
|
|
}
|
|
|
|
const TCHAR * XExplodeStream::Descriptor()
|
|
{
|
|
return _T("XExplodeStream");
|
|
}
|
|
|
|
const TCHAR * XExplodeStream::Desc()
|
|
{
|
|
return Descriptor();
|
|
}
|
|
|
|
Adesk::Boolean XExplodeStream::IsDragging() const
|
|
{
|
|
return m_bIsDragging;
|
|
}
|
|
|
|
void XExplodeStream::SetIsDragging(Adesk::Boolean bDragging)
|
|
{
|
|
m_bIsDragging = bDragging;
|
|
}
|
|
|
|
AcDbObjectId XExplodeStream::GetLineTypeId() const
|
|
{
|
|
return m_idLinetype;
|
|
}
|
|
|
|
AcDbObjectId XExplodeStream::GetMaterialId()const
|
|
{
|
|
return m_idMaterial;
|
|
}
|
|
|
|
Acad::ErrorStatus XExplodeStream::SetLineType(const TCHAR *pltype)
|
|
{
|
|
AcDbObjectId idLineType = GetLinetypeIdFromString(pltype);
|
|
if (!idLineType)
|
|
{
|
|
return Acad::eInvalidInput;
|
|
}
|
|
|
|
m_idLinetype = idLineType;
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus XExplodeStream::SetLineType(AcDbObjectId idLineType)
|
|
{
|
|
m_idLinetype = idLineType;
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus XExplodeStream::SetMaterial(AcDbObjectId idMaterial)
|
|
{
|
|
if (idMaterial.isValid())
|
|
{
|
|
m_idMaterial = idMaterial;
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
// 对polyOutline的方向没有规定
|
|
void XExplodeStream::DrawSolid(const XPoly2D &polyOutline)
|
|
{
|
|
if (polyOutline.Area() < 1E-6)//add by W on 070306
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbHatch *pHatch = NewHatchFromPoly2D(polyOutline, _T("SOLID"), 1.0);
|
|
ASSERT(pHatch);
|
|
|
|
Append(pHatch);
|
|
}
|
|
|
|
|
|
void XExplodeStream::DrawHatch(const XPoly2D &polyOutline, const TCHAR *pszPattern, double nScale)
|
|
{
|
|
if (!pszPattern)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (polyOutline.Area() < 1E-6)//add by W on 070306
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbHatch *pHatch = NewHatchFromPoly2D(polyOutline, pszPattern, nScale);
|
|
if (!pHatch)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Append(pHatch);
|
|
}
|
|
|
|
void XExplodeStream::DrawHatchEx(const XPoly2D &polyOutline, const TCHAR *pszPattern, double nScale,double rotation)
|
|
{
|
|
if (!pszPattern)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (polyOutline.Area() < 1E-6)//add by W on 070306
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbHatch *pHatch = NewHatchFromPoly2D(polyOutline, pszPattern, nScale,rotation);
|
|
if (!pHatch)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Append(pHatch);
|
|
}
|
|
|
|
void XExplodeStream::DrawShell(Adesk::UInt32 nbVertex,
|
|
const AcGePoint3d* pVertexList,
|
|
Adesk::UInt32 faceListSize,
|
|
const Adesk::Int32* pFaceList,
|
|
const AcGiEdgeData* pEdgeData)
|
|
{
|
|
XPolygonEx *pLast = NULL;
|
|
XVector3D vtEcs;
|
|
Adesk::UInt8* visibleArray = pEdgeData ? pEdgeData->visibility() : NULL;
|
|
Adesk::UInt32 j = 0; //面索引
|
|
int nEdgeIndex = 0;
|
|
DList<XHoleModel> lstPolygons;
|
|
XHoleModel *pHoleModel = NULL;
|
|
|
|
while (j < faceListSize)
|
|
{
|
|
Adesk::Int32 nFaceNum = pFaceList[j];
|
|
if (nFaceNum > 0) //外轮廓
|
|
{
|
|
pHoleModel = new XHoleModel;
|
|
lstPolygons.Append(pHoleModel);
|
|
|
|
//XPolygonEx &polyEx1 = pHoleModel->m_outline;
|
|
XPolygonEx &polyEx1 = pHoleModel->GetOutLine();
|
|
for (Adesk::Int32 i = 1; i <= abs(nFaceNum); i++)
|
|
{
|
|
int nVertNum = pFaceList[j + i];
|
|
XPoint ptVert = pVertexList[nVertNum];
|
|
BOOL bVis = TRUE;
|
|
if (visibleArray)
|
|
{
|
|
if (visibleArray[nEdgeIndex] == kAcGiInvisible || visibleArray[nEdgeIndex] == kAcGiSilhouette)
|
|
{
|
|
bVis = FALSE;
|
|
}
|
|
}
|
|
|
|
polyEx1.AppendNode(ptVert, bVis);
|
|
nEdgeIndex++;
|
|
}
|
|
ASSERT(pHoleModel->IsValid());
|
|
}
|
|
else //洞口
|
|
{
|
|
ASSERT(pHoleModel->IsValid());
|
|
XPolygonEx *pHole = new XPolygonEx;
|
|
for (Adesk::Int32 i = 1; i <= abs(nFaceNum); i++)
|
|
{
|
|
int nVertNum = pFaceList[j + i];
|
|
XPoint ptVert = pVertexList[nVertNum];
|
|
BOOL bVis = TRUE;
|
|
if (visibleArray)
|
|
{
|
|
if (visibleArray[nEdgeIndex] == kAcGiInvisible || visibleArray[nEdgeIndex] == kAcGiSilhouette)
|
|
{
|
|
bVis = FALSE;
|
|
}
|
|
}
|
|
|
|
pHole->AppendNode(ptVert, bVis);
|
|
nEdgeIndex++;
|
|
}
|
|
|
|
ASSERT(pHole->Length() >= 3);
|
|
//pHoleModel->m_holes.Append(pHole);
|
|
pHoleModel->AppendHoleList(pHole);
|
|
}
|
|
|
|
j += abs(nFaceNum) + 1;
|
|
}
|
|
|
|
for (int k = 0; k < lstPolygons.Length(); k++)
|
|
{
|
|
XHoleModel *pModel = lstPolygons[k];
|
|
DList<XTriangle> lstTris;
|
|
|
|
if (!pModel->Triangulate(FALSE, lstTris))
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
for (int n = 0; n < lstTris.Length(); n++)
|
|
{
|
|
XTriangle *triangle = lstTris[n];
|
|
Adesk::Boolean bSide1 = !(triangle->m_nFlag&SIDE1_INVISIBLE);
|
|
Adesk::Boolean bSide2 = !(triangle->m_nFlag&SIDE2_INVISIBLE);
|
|
Adesk::Boolean bSide3 = !(triangle->m_nFlag&SIDE3_INVISIBLE);
|
|
AcDbFace *pFace = new AcDbFace(triangle->vertex1, triangle->vertex2,triangle->vertex3,
|
|
triangle->vertex1, bSide1, bSide2, bSide3);
|
|
Append(pFace);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 根据给定的内外边界, 绘制三维外壳
|
|
// 如果有圆弧边界,则必须平行于XY平面
|
|
void XExplodeStream::DrawShell(const XPoly2D &polyOut1, const DList<XPoly2D> &lstPolyIn1)
|
|
{
|
|
int i = 0;
|
|
if (g_bEnableAcis)
|
|
{
|
|
XPoly poly1, poly2;
|
|
((XPoly2D &)polyOut1).MapToPolygon1(poly1, _AS_SYS_UNIT(g_nCirDeviation));
|
|
|
|
ASSERT(poly1.Length() > 2);
|
|
|
|
XHoleModel model;
|
|
for (int k = 0; k < poly1.Length(); k++)
|
|
{
|
|
//model.m_outline.AppendNode(*poly1[k], TRUE);
|
|
model.GetOutLine().AppendNode(*poly1[k], TRUE);
|
|
}
|
|
|
|
for (i = 0; i < lstPolyIn1.Length(); i++)
|
|
{
|
|
((XPoly2D &)lstPolyIn1[i]).MapToPolygon1(poly2, _AS_SYS_UNIT(g_nCirDeviation));
|
|
|
|
XPolygonEx *polyEx2 = new XPolygonEx(poly2);
|
|
//model.m_holes.Append(polyEx2);
|
|
model.AppendHoleList(polyEx2);
|
|
}
|
|
|
|
XTrianglePface lstTris;
|
|
if (model.Triangulate(FALSE, lstTris))
|
|
{
|
|
for (int n = 0; n < lstTris.Length(); n++)
|
|
{
|
|
XTriangle *triangle = lstTris[n];
|
|
Adesk::Boolean bSide1 = !(triangle->m_nFlag&SIDE1_INVISIBLE);
|
|
Adesk::Boolean bSide2 = !(triangle->m_nFlag&SIDE2_INVISIBLE);
|
|
Adesk::Boolean bSide3 = !(triangle->m_nFlag&SIDE3_INVISIBLE);
|
|
|
|
AcDbFace *pFace = new AcDbFace(triangle->vertex1, triangle->vertex2,
|
|
triangle->vertex3, triangle->vertex1, bSide1, bSide2, bSide3);
|
|
|
|
Append(pFace);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DList<XCurveSegment> lstSegs;
|
|
ExplodePoly2D(polyOut1, lstSegs);
|
|
|
|
for (i = 0; i < lstPolyIn1.Length(); i++)
|
|
{
|
|
ExplodePoly2D(polyOut1, lstSegs);
|
|
}
|
|
|
|
for (i = 0; i < lstSegs.Length(); i++)
|
|
{
|
|
Append(lstSegs[i]->AsAcDbCurve());
|
|
}
|
|
}
|
|
}
|
|
|
|
// make a 3DSolid
|
|
void XExplodeStream::DrawBody(const XPoly2D &polySrc, const XVector3D &vtOffset)
|
|
{
|
|
DList<XPoly2D> lstPoly;
|
|
DrawBody(polySrc, lstPoly, vtOffset);
|
|
}
|
|
|
|
void XExplodeStream::DrawBody(const XPoly2D &polyOut, const DList<XPoly2D> &lstHoles, const XVector3D &vtOffset)
|
|
{
|
|
if (g_bEnableAcis)
|
|
{
|
|
if (g_bExplodeMesh)
|
|
{
|
|
// 绘制侧面
|
|
for (int i = 0; i < lstHoles.Length(); i++)
|
|
{
|
|
DrawMesh(lstHoles[i], vtOffset);
|
|
}
|
|
|
|
DrawMesh(polyOut, vtOffset);
|
|
|
|
//绘制前台面
|
|
DrawShell(polyOut, lstHoles);
|
|
|
|
//绘制后台面
|
|
XPoly2D polyUp(polyOut);
|
|
for (int i = 0; i < polyUp.Length(); i++)
|
|
{
|
|
*polyUp[i] += vtOffset;
|
|
}
|
|
|
|
DList<XPoly2D> lstHoleUp;
|
|
for (int n = 0; n < lstHoles.Length(); n++)
|
|
{
|
|
XPoly2D *pHole = new XPoly2D(lstHoles[n]);
|
|
for (int j = 0; j < pHole->Length(); j++)
|
|
{
|
|
*(*pHole)[j] += vtOffset;
|
|
}
|
|
|
|
lstHoleUp.Append(pHole);
|
|
}
|
|
|
|
DrawShell(polyUp, lstHoleUp);
|
|
}
|
|
else
|
|
{
|
|
AcDbRegion *regioni = AsRegion(polyOut);
|
|
if (!regioni)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcGeVector3d vtNormalI;
|
|
VERIFY(regioni->getNormal(vtNormalI) == Acad::eOk);
|
|
|
|
double dThickI = vtOffset.Length();
|
|
if (vtNormalI.angleTo(vtOffset) > PI / 2.0)
|
|
{
|
|
dThickI = -dThickI;
|
|
}
|
|
|
|
AcDb3dSolid *solid3di = new AcDb3dSolid();
|
|
VERIFY(solid3di->extrude(regioni, dThickI,0.0) == Acad::eOk);
|
|
delete regioni;
|
|
|
|
for (int n = 0; n < lstHoles.Length(); n++)
|
|
{
|
|
const XPoly2D polyIn = lstHoles[n];
|
|
AcDbRegion *regionj = AsRegion(polyIn);
|
|
if (!regionj)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
AcGeVector3d vtNormalJ;
|
|
VERIFY(regionj->getNormal(vtNormalJ) == Acad::eOk);
|
|
AcDb3dSolid *solid3dj = new AcDb3dSolid();
|
|
double dThickJ = vtOffset.Length();
|
|
if (vtNormalJ.angleTo(vtOffset) > PI / 2.0)
|
|
{
|
|
dThickJ = -dThickJ;
|
|
}
|
|
|
|
VERIFY(solid3dj->extrude(regionj,dThickJ,0.0) == Acad::eOk);
|
|
delete regionj;
|
|
if (solid3di->booleanOper(AcDb::kBoolSubtract,solid3dj) != Acad::eOk)
|
|
{
|
|
delete solid3di;
|
|
delete solid3dj;
|
|
|
|
return;
|
|
}
|
|
|
|
delete solid3dj;
|
|
}
|
|
|
|
if (solid3di->isNull())
|
|
{
|
|
delete solid3di;
|
|
}
|
|
else
|
|
{
|
|
Append(solid3di);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
XPoly2D polyOffsetOut(polyOut);
|
|
DList<XCurveSegment> lstSegs;
|
|
for (int i = 0; i < polyOffsetOut.Length(); i++)
|
|
{
|
|
*polyOffsetOut[i] += vtOffset;
|
|
lstSegs.Append(new XCurveSegment(polyOut[i], *polyOffsetOut[i], 0.0));
|
|
}
|
|
|
|
ExplodePoly2D(polyOut, lstSegs);
|
|
ExplodePoly2D(polyOffsetOut, lstSegs);
|
|
|
|
for (int n = 0; n < lstHoles.Length(); n++)
|
|
{
|
|
XPoly2D polyIn(lstHoles[n]);
|
|
XPoly2D polyOffsetIn(polyIn);
|
|
for (int i = 0; i < polyOffsetIn.Length(); i++)
|
|
{
|
|
*polyOffsetIn[i] += vtOffset;
|
|
lstSegs.Append(new XCurveSegment(*polyIn[i], *polyOffsetIn[i], 0.0));
|
|
}
|
|
|
|
ExplodePoly2D(polyIn, lstSegs);
|
|
ExplodePoly2D(polyOffsetIn, lstSegs);
|
|
}
|
|
|
|
for (int i = 0; i < lstSegs.Length(); i++)
|
|
{
|
|
Append(lstSegs[i]->AsAcDbCurve());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void XExplodeStream::DrawBody(const XPoly2D &polyOut, const XPoly2D &polyIn, const XVector3D &vtOffset)
|
|
{
|
|
DList<XPoly2D> lstHoles;
|
|
lstHoles.Append(new XPoly2D(polyIn));
|
|
|
|
DrawBody(polyOut, lstHoles, vtOffset);
|
|
}
|
|
|
|
void XExplodeStream::DrawMesh( const Adesk::UInt32 rows,
|
|
const Adesk::UInt32 columns,
|
|
const AcGePoint3d* pVertexList,
|
|
const AcGiEdgeData* pEdgeData)
|
|
{
|
|
for (Adesk::UInt32 m = 0; m < rows - 1; m++)
|
|
{
|
|
for (Adesk::UInt32 n = 0; n < columns - 1; n++)
|
|
{
|
|
int idVertex1 = m * columns + n;
|
|
int idVertex2 = m * columns + n + 1;
|
|
int idVertex3 = (m + 1) * columns + n + 1;
|
|
int idVertex4 = (m + 1) * columns + n;
|
|
Adesk::Boolean bVis1 = Adesk::kTrue, bVis2 = Adesk::kTrue,
|
|
bVis3 = Adesk::kTrue, bVis4 = Adesk::kTrue;
|
|
if (pEdgeData)
|
|
{
|
|
Adesk::UInt8 *pVisArray = pEdgeData->visibility();
|
|
if (pVisArray)
|
|
{
|
|
bVis1 = pVisArray[m * (columns - 1) + n];
|
|
bVis2 = pVisArray[rows * (columns - 1) + m * columns + n + 1];
|
|
bVis3 = pVisArray[(m + 1) * (columns - 1) + n];
|
|
bVis4 = pVisArray[rows * (columns - 1) + m * columns + n];
|
|
}
|
|
}
|
|
|
|
AcDbFace *pFace = new AcDbFace(pVertexList[idVertex1],
|
|
pVertexList[idVertex2], pVertexList[idVertex3], pVertexList[idVertex4],
|
|
bVis1, bVis2, bVis3, bVis4);
|
|
|
|
Append(pFace);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 根据给定的边界和凸起方向, 绘制三维外壳
|
|
void XExplodeStream::DrawMesh(const XPoly2D &polyOut, const XVector3D &vtOffset)
|
|
{
|
|
XPoly poly;
|
|
polyOut.AsOpenPoly1(poly, _AS_SYS_UNIT(g_nCirDeviation)); //变成开口的poly, 如果原先封闭, 则起点复制为终点
|
|
|
|
int nColumn = poly.Length(); //+1;
|
|
int nRow = 2;
|
|
XPoint *ptArray = new XPoint[nColumn*nRow];
|
|
for (int m = 0; m < nRow; m++)
|
|
{
|
|
for (int n = 0; n < nColumn; n++)
|
|
{
|
|
int nBase = m * nColumn;
|
|
ptArray[nBase + n] = *poly[n];
|
|
|
|
if (m == 1)
|
|
{
|
|
ptArray[nBase + n] += vtOffset;
|
|
}
|
|
}
|
|
}
|
|
|
|
AcGePoint3dArray vertexArray;
|
|
for (int i = 0; i < nColumn * nRow; i++)
|
|
{
|
|
vertexArray.append(ptArray[i]);
|
|
}
|
|
|
|
AcDbPolygonMesh mesh(AcDb::kSimpleMesh, nRow, nColumn, vertexArray,
|
|
Adesk::kFalse, Adesk::kFalse);
|
|
|
|
AcDbVoidPtrArray entSet;
|
|
mesh.explode(entSet);
|
|
|
|
int nCount = entSet.length();
|
|
for (int idx = 0; idx < nCount; idx++)
|
|
{
|
|
Append((AcDbEntity *)entSet[idx]);
|
|
}
|
|
|
|
delete [] ptArray;
|
|
}
|
|
|
|
// 显示分别连接两个区域的边缘构成的侧面
|
|
void XExplodeStream::DrawMesh(const XPoly2D &polyRegion1, const XPoly2D &polyRegion2)
|
|
{
|
|
XPoly poly1, poly2;
|
|
polyRegion1.AsOpenPoly(poly1); //变成开口的poly, 如果原先封闭, 则起点复制为终点
|
|
polyRegion2.AsOpenPoly(poly2);
|
|
|
|
if (poly1.Length() != poly2.Length())
|
|
{
|
|
return;
|
|
}
|
|
|
|
int nColumn = poly1.Length(); //+1;
|
|
int nRow = 2;
|
|
XPoint *ptArray = new XPoint[nColumn * nRow];
|
|
|
|
for (int m = 0; m < nRow; m++)
|
|
{
|
|
for (int n = 0; n < nColumn; n++)
|
|
{
|
|
int nBase = m * nColumn;
|
|
if (!m)
|
|
{
|
|
ptArray[nBase + n] = *poly1[n];
|
|
}
|
|
else
|
|
{
|
|
ptArray[nBase + n] = *poly2[n];
|
|
}
|
|
}
|
|
}
|
|
|
|
AcGePoint3dArray vertexArray;
|
|
for (int i = 0; i < nColumn*nRow; i++)
|
|
{
|
|
vertexArray.append(ptArray[i]);
|
|
}
|
|
|
|
AcDbPolygonMesh mesh(AcDb::kSimpleMesh, nRow, nColumn, vertexArray,
|
|
Adesk::kFalse, Adesk::kFalse);
|
|
AcDbVoidPtrArray entSet;
|
|
mesh.explode(entSet);
|
|
|
|
int nCount = entSet.length();
|
|
for (int idx = 0; idx < nCount; idx++)
|
|
{
|
|
Append((AcDbEntity *)entSet[idx]);
|
|
}
|
|
|
|
delete [] ptArray;
|
|
}
|
|
|
|
void XExplodeStream::DrawFace(const X3DFace &face0)
|
|
{
|
|
if (face0.IsPoint() || face0.IsLinear())
|
|
{
|
|
#ifndef NDEBUG
|
|
XGeLib::adsout << _T("\nXExplodeStream: Bad 3dface is skipped!");
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
X3DFace face(face0);
|
|
if (face.IsTriangle(2))
|
|
{
|
|
if (face.GetVertex(0).Distance(face.GetVertex(1)) < _DIST_SNAP)
|
|
{
|
|
face.MoveShift(FALSE);
|
|
}
|
|
else if (face.GetVertex(1).Distance(face.GetVertex(2)) < _DIST_SNAP)
|
|
{
|
|
face.MoveShift(FALSE);
|
|
face.MoveShift(FALSE);
|
|
}
|
|
else if (face.GetVertex(2).Distance(face.GetVertex(3)) < _DIST_SNAP)
|
|
{
|
|
face.MoveShift(TRUE);
|
|
}
|
|
|
|
ASSERT(face.IsTriangle(1));
|
|
}
|
|
|
|
AcDbFace *pDbFace = new AcDbFace(face.GetVertex(0), face.GetVertex(1),
|
|
face.GetVertex(2), face.GetVertex(3),
|
|
((face.GetFlag() & 0x01) == 0),
|
|
((face.GetFlag() & 0x02) == 0),
|
|
((face.GetFlag() & 0x04) == 0),
|
|
((face.GetFlag() & 0x08) == 0));
|
|
Append(pDbFace);
|
|
}
|
|
}
|
|
|
|
void XExplodeStream::DrawText(const TCHAR *pszContent)
|
|
{
|
|
AcDbObjectId idTextStyle = m_idTextStyle;
|
|
if (!idTextStyle)
|
|
{
|
|
XString sTextStyle;
|
|
xg_getvar(_T("TEXTSTYLE"), sTextStyle);
|
|
idTextStyle = GetTextStyleId(sTextStyle);
|
|
}
|
|
|
|
if (!idTextStyle || !pszContent)
|
|
{
|
|
return;
|
|
}
|
|
|
|
XDbObject obj(idTextStyle, AcDb::kForRead);
|
|
if (!obj)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbTextStyleTableRecord *newStyle = AcDbTextStyleTableRecord::cast(obj.m_pObject);
|
|
if (!newStyle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
double nTextSize = m_nHeight;
|
|
if (nTextSize < 1.0E-5)
|
|
{
|
|
nTextSize = newStyle->textSize();
|
|
}
|
|
|
|
if (nTextSize < 1.0E-5)
|
|
{
|
|
xg_getvar(_T("TEXTSIZE"), &nTextSize);
|
|
if (nTextSize < 1.0E-5)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
double nWidthFactor = newStyle->xScale();
|
|
if (m_nControlFlag & EDF_XSCALE) //Modify on 2002/10/13
|
|
{
|
|
nWidthFactor = m_nWidthFactor;
|
|
}
|
|
|
|
//refreshed by W on 050424,原错误:PI/2到3PI/2转角的文字被强制修改为(-PI/2,PI/2)区间
|
|
//AcDbText *pAttrib = new AcDbText(m_ptLocation, pszContent, idTextStyle, nTextSize, XExport::xg_angle(m_nRotation));
|
|
AcDbText *pAttrib = new AcDbText(m_ptLocation, pszContent, idTextStyle, nTextSize, m_nRotation);
|
|
|
|
pAttrib->setHeight(nTextSize);
|
|
pAttrib->setWidthFactor(nWidthFactor);
|
|
|
|
AcDb::TextHorzMode nHMode;
|
|
AcDb::TextVertMode nVMode;
|
|
Adesk::UInt16 nAlignMode = GetTextAlignment(m_align);
|
|
nHMode = (AcDb::TextHorzMode)LOBYTE(nAlignMode);
|
|
nVMode = (AcDb::TextVertMode)HIBYTE(nAlignMode);
|
|
pAttrib->setHorizontalMode(nHMode);
|
|
pAttrib->setVerticalMode(nVMode);
|
|
|
|
pAttrib->setAlignmentPoint(m_ptLocation);
|
|
Append(pAttrib);
|
|
}
|
|
|
|
void XExplodeStream::DrawTextFit(const TCHAR *pszText, XPoint pt1, XPoint pt2, double nTextHeight)
|
|
{
|
|
ASSERT(m_bInitStyle);
|
|
double nTextSize = nTextHeight;
|
|
if (nTextSize < 1.0E-5)
|
|
{
|
|
return;
|
|
}
|
|
|
|
double nOldSize = m_textStyle.textSize();
|
|
m_textStyle.setTextSize(nTextSize);
|
|
|
|
Adesk::Boolean bIncludeSpace = Adesk::kTrue;
|
|
TCHAR *pTypeface = NULL;
|
|
Adesk::Boolean bBold, bItalic;
|
|
#if ARX < 21
|
|
int tmp0, tmp1;
|
|
BOOL bWinFont = (m_textStyle.font(pTypeface, bBold, bItalic, tmp0, tmp1) == Acad::eOk);
|
|
#else
|
|
Autodesk::AutoCAD::PAL::FontUtils::FontPitch tmp0;
|
|
Autodesk::AutoCAD::PAL::FontUtils::FontFamily tmp1;
|
|
Charset charset;
|
|
BOOL bWinFont = (m_textStyle.font(pTypeface, bBold, bItalic, charset, tmp0, tmp1) == Acad::eOk);
|
|
#endif
|
|
if (bWinFont)
|
|
{
|
|
if (!pTypeface || !pTypeface[0])
|
|
{
|
|
bWinFont = FALSE;
|
|
}
|
|
}
|
|
|
|
if (pTypeface)
|
|
{
|
|
delete[] pTypeface;
|
|
}
|
|
|
|
if (bWinFont)
|
|
{
|
|
bIncludeSpace = Adesk::kTrue;
|
|
}
|
|
else
|
|
{
|
|
bIncludeSpace = Adesk::kFalse;
|
|
const TCHAR *pShxFile = m_textStyle.fileName();
|
|
if (pShxFile)
|
|
{
|
|
XPathParser paser(pShxFile);
|
|
_tcsupr(paser.m_sFileName);
|
|
|
|
TCHAR sFilter[] = _T("GBE*,GOTH*,ISO*,SCRIPT*,ROMAN*");
|
|
if (ads_wcmatch(paser.m_sFileName, sFilter) == RTNORM)
|
|
{
|
|
bIncludeSpace = Adesk::kTrue;
|
|
}
|
|
}
|
|
}
|
|
|
|
AcGePoint2d ptExt = m_textStyle.extents(pszText, bIncludeSpace, -1, Adesk::kFalse);
|
|
double nWidth = ptExt[0];
|
|
double nWidthFactor = pt1.Distance2d(pt2) / nWidth;
|
|
m_textStyle.setTextSize(nOldSize);
|
|
|
|
AcDbObjectId idTextStyle = m_idTextStyle;;
|
|
if (!idTextStyle)
|
|
{
|
|
XString sTextStyle;
|
|
xg_getvar(_T("TEXTSTYLE"), sTextStyle);
|
|
idTextStyle = GetTextStyleId(sTextStyle);
|
|
}
|
|
|
|
AcDbText *pAttrib = new AcDbText;
|
|
pAttrib->setHorizontalMode(AcDb::kTextFit);
|
|
pAttrib->setVerticalMode(AcDb::kTextBase);
|
|
pAttrib->setTextStyle(idTextStyle);
|
|
pAttrib->setTextString(pszText);
|
|
pAttrib->setPosition(pt1);
|
|
pAttrib->setAlignmentPoint(pt2);
|
|
pAttrib->setHeight(nTextHeight);
|
|
|
|
//modified by W 051023
|
|
pAttrib->setWidthFactor(nWidthFactor);
|
|
pAttrib->setHorizontalMode(AcDb::kTextFit);
|
|
|
|
//add by W on 060218
|
|
XPoint vt = pt2 - pt1;
|
|
pAttrib->setRotation(vt.AsAcGeVector2d().angle());
|
|
|
|
Append(pAttrib);
|
|
}
|
|
|
|
// 增加一图块
|
|
void XExplodeStream::DrawBlock(const AcDbBlockTableRecord &blockRec, const XPoint &ptInsert, const AcGeScale3d &scales,
|
|
double nRot, BOOL bMakeBlock)
|
|
{
|
|
AcDbObjectId idBlock = blockRec.objectId();
|
|
if (!idBlock)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbBlockReference * pInsert = new AcDbBlockReference(ptInsert, idBlock);
|
|
pInsert->setScaleFactors(scales);
|
|
pInsert->setRotation(nRot);
|
|
|
|
if (bMakeBlock)
|
|
{
|
|
Append(pInsert);
|
|
}
|
|
else
|
|
{
|
|
XMasterProperties prop;
|
|
InitModel(prop, pInsert, NULL, *m_pEntSet);
|
|
delete pInsert;
|
|
}
|
|
}
|
|
|
|
void XExplodeStream::DrawAtomicEntSet(const AcDbVoidPtrArray &entSet, const AcGeMatrix3d &matTrans)
|
|
{
|
|
TCHAR szMatch[256] = _T("AEC_*");
|
|
int nCount = entSet.length();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
AcDbEntity *pEntity = (AcDbEntity *)entSet[i];
|
|
AcDbPolyline *pline = AsPolyline(pEntity);
|
|
if (pline)
|
|
{
|
|
XPoly2D poly2d;
|
|
PolyConvert(*pline, poly2d);
|
|
|
|
XVector3D vtNormal;
|
|
(AcGeVector3d &)vtNormal = pline->normal();
|
|
double nElev = 0.0;
|
|
AcGeMatrix2d xform2d(matTrans.convertToLocal(vtNormal,nElev));
|
|
ads_matrix mat0 = {
|
|
{xform2d(0,0), xform2d(0,1), 0, xform2d(0,2)},
|
|
{xform2d(1,0), xform2d(1,1), 0, xform2d(1,2)},
|
|
{0,0,1, nElev},
|
|
{0,0,0,1}
|
|
};
|
|
poly2d.TransUCS(mat0);
|
|
|
|
PolyConvert(poly2d, *pline);
|
|
|
|
((AcGeVector3d &)vtNormal).normalize();
|
|
pline->setNormal(vtNormal);
|
|
|
|
Append(pline);
|
|
}
|
|
else
|
|
{
|
|
AcDbEntity *pEntCloned = NULL;
|
|
// ARC,CIRCLE Transform后丢失厚度信息
|
|
Acad::ErrorStatus es = pEntity->getTransformedCopy(matTrans, pEntCloned);
|
|
if (es == Acad::eOk && pEntCloned)
|
|
{
|
|
XString sDxfName;
|
|
sDxfName = pEntCloned->isA()->dxfName();
|
|
if (ads_wcmatch(sDxfName, szMatch) == RTNORM && IsFullExplode())
|
|
{
|
|
pEntCloned->explode(*m_pEntSet);
|
|
delete pEntCloned;
|
|
}
|
|
else
|
|
{
|
|
Append(pEntCloned);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
AcDbObjectId XExplodeStream::GetLayerId() const
|
|
{
|
|
return m_idLayer;
|
|
}
|
|
|
|
|
|
Acad::ErrorStatus XExplodeStream::SetLayer(const AcDbObjectId &id)
|
|
{
|
|
m_idLayer = id;
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus XExplodeStream::SetLayer(const TCHAR *pszLayer)
|
|
{
|
|
AcDbObjectId id = GetLayerIdFromString(pszLayer);
|
|
if (!id)
|
|
{
|
|
return Acad::eInvalidInput;
|
|
}
|
|
|
|
return SetLayer(id);
|
|
}
|