672 lines
20 KiB
C++
672 lines
20 KiB
C++
#include "stdafx.h"
|
|
#include "aecroof.h"
|
|
#include "XGlobalFunc.h"
|
|
#include "XScreenDc.h"
|
|
#include "XCurveInline.h"
|
|
|
|
|
|
static int g_nDbgFlag=0;
|
|
//extern int DePeriod(int nPeriod, int nIndex);
|
|
|
|
/////////////////////////////////////
|
|
// 屋顶数据类
|
|
/////////////////////////////////////
|
|
|
|
//////////////////////////////////
|
|
// 求三阶行列式
|
|
double MatrixValue(double a[3][3])
|
|
{
|
|
double nRes = a[0][0]*a[1][1]*a[2][2] + a[0][1]*a[1][2]*a[2][0] + a[0][2]*a[1][0]*a[2][1]
|
|
- a[0][2]*a[1][1]*a[2][0] - a[0][1]*a[1][0]*a[2][2] - a[0][0]*a[1][2]*a[2][1];
|
|
return nRes;
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
// 求三个面的交点
|
|
int IntersectWith(const XPlanePara &plan1, const XPlanePara &plan2,
|
|
const XPlanePara &plan3, XPoint &ptInter)
|
|
{
|
|
double a[3][3]={
|
|
{plan1.nParaA, plan1.nParaB, plan1.nParaC},
|
|
{plan2.nParaA, plan2.nParaB, plan2.nParaC},
|
|
{plan3.nParaA, plan3.nParaB, plan3.nParaC},
|
|
};
|
|
|
|
double nDelta = MatrixValue(a);
|
|
if(fabs(nDelta)<1.0E-5)
|
|
return 0;
|
|
|
|
double a1[3][3] = {
|
|
{-plan1.nParaD, plan1.nParaB, plan1.nParaC},
|
|
{-plan2.nParaD, plan2.nParaB, plan2.nParaC},
|
|
{-plan3.nParaD, plan3.nParaB, plan3.nParaC},
|
|
};
|
|
double a2[3][3] = {
|
|
{plan1.nParaA, -plan1.nParaD, plan1.nParaC},
|
|
{plan2.nParaA, -plan2.nParaD, plan2.nParaC},
|
|
{plan3.nParaA, -plan3.nParaD, plan3.nParaC},
|
|
};
|
|
double a3[3][3] = {
|
|
{plan1.nParaA, plan1.nParaB, -plan1.nParaD},
|
|
{plan2.nParaA, plan2.nParaB, -plan2.nParaD},
|
|
{plan3.nParaA, plan3.nParaB, -plan3.nParaD},
|
|
};
|
|
ptInter.x = MatrixValue(a1)/nDelta;
|
|
ptInter.y = MatrixValue(a2)/nDelta;
|
|
ptInter.z = MatrixValue(a3)/nDelta;
|
|
return 1;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
// 求线和面的交点,考虑了线是否为无限长
|
|
int IntersectWith(const XLine &ln, const XPlanePara &plan, XPoint &res)
|
|
{
|
|
if(!CT_inter_line_plan1(ln.StartPoint(), ln.EndPoint(),
|
|
(const plan_para *)&plan, res))
|
|
return 0;
|
|
if(ln.GetLineFlag()==LS_FINITE) {
|
|
int nFlag=(res&ln);
|
|
if(nFlag==PR_INSIDE || nFlag==PR_ONPT1 || nFlag==PR_ONPT2)
|
|
return 1;
|
|
else return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
// XAecPlan: 空间几何平面的类
|
|
//////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// 平面内一点及法向量来初始化平面
|
|
int XPlanePara::InitPlane(const XPoint &pt0, const XVector3D &vt)
|
|
{
|
|
ASSERT(sizeof(XPlane)==sizeof(plan_para));
|
|
|
|
if(!CT_plan_equation(pt0, vt, (plan_para *)this))
|
|
return RTERROR;
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int XPlanePara::InitPlane(const XPoint &pt1, const XPoint &pt2, const XPoint &pt3)
|
|
{
|
|
XPoint vt;
|
|
if(!CT_vector_plan3p(pt1, pt2, pt3, vt))
|
|
return RTERROR;
|
|
ASSERT(sizeof(XPlanePara)==sizeof(plan_para));
|
|
|
|
if(!CT_plan_equation(pt1, vt, (plan_para *)this))
|
|
return RTERROR;
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
// XAecPlan: 坡屋顶几何类
|
|
//////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////
|
|
// 用底面和倾角来初始化等坡屋顶
|
|
/*
|
|
XAecRoof::XAecRoof(const XPoly2D &poly, double nSlant)
|
|
{
|
|
InitRoof(poly, nSlant);
|
|
}
|
|
*/
|
|
//////////////////////////////////////////////////////
|
|
// 用底面和倾角初始化等坡屋顶
|
|
int XAecRoof::InitRoof(const XPoly2D &poly, double nSlant)
|
|
{
|
|
m_lstEdges.Reset();
|
|
m_lstSlopeFaces.Reset();
|
|
|
|
poly.Disperse(m_polyBoundry, 20);
|
|
for(int i=0; i<m_polyBoundry.Length(); i++) {
|
|
m_lstEdges.Append(new XRoofEdgeCompact(*m_polyBoundry[i], nSlant));
|
|
}
|
|
m_nBottomElevation = poly[0].z;
|
|
|
|
//m_polyBoundry = (XPoly2D &)poly;
|
|
return RTNORM;
|
|
}
|
|
|
|
///////////////////////////////////////////////////
|
|
// 对象的赋值
|
|
/*
|
|
XAecRoof & XAecRoof::operator = (const XAecRoof &src)
|
|
{
|
|
m_lstEdges.Reset();
|
|
m_lstSlopeFaces.Reset();
|
|
m_lstRidges.Reset();
|
|
|
|
m_nBottomElevation = src.m_nBottomElevation;
|
|
for(int i=0; i<src.GetTotalEdge(); i++) {
|
|
m_lstEdges.Append(new XRoofEdgeCompact(src.m_lstEdges[i]));
|
|
}
|
|
for(i=0; i<src.m_lstSlopeFaces.Length(); i++) {
|
|
const XPointList &srcPts=src.m_lstSlopeFaces[i];
|
|
m_lstSlopeFaces.Append(new XPointList(srcPts));
|
|
}
|
|
for(i=0; i<src.m_lstRidges.Length(); i++) {
|
|
m_lstRidges.Append(new XLine(src.m_lstRidges[i]));
|
|
}
|
|
m_polyBoundry = src.m_polyBoundry;
|
|
return *this;
|
|
}
|
|
*/
|
|
////////////////////////////////////////
|
|
// 用边的数据来建立/更新底面的数据
|
|
int XAecRoof::InitBottomPolyByEdge()
|
|
{
|
|
m_polyBoundry.Reset();
|
|
m_polyBoundry.SetFlag(1);
|
|
for(int i=0; i<m_lstEdges.Length(); i++) {
|
|
m_polyBoundry.AppendNode(m_lstEdges[i]->m_ptVertex);
|
|
}
|
|
return RTNORM;
|
|
}
|
|
|
|
////////////////////////////////////////
|
|
// 计算屋顶各个坡面
|
|
int XAecRoof::Calculate()
|
|
{
|
|
m_lstSlopeFaces.Reset();
|
|
m_lstRidges.Reset();
|
|
for(int n=0; n<GetTotalEdge(); n++) {
|
|
XLine lnRidge;
|
|
if(GetRidge(n, lnRidge, FALSE)==RTNORM)
|
|
m_lstRidges.Append(new XLine(lnRidge));
|
|
else {
|
|
m_lstSlopeFaces.Reset();
|
|
m_lstRidges.Reset();
|
|
return RTERROR;
|
|
}
|
|
}
|
|
for(int i=0; i<m_lstEdges.Length(); i++) {
|
|
XPointList *pSlopeFace = new XPointList;
|
|
int nRet=CalculateSlopeFace(i, *pSlopeFace);
|
|
if(nRet==RTNORM) {
|
|
m_lstSlopeFaces.Append(pSlopeFace);
|
|
} else {
|
|
delete pSlopeFace;
|
|
m_lstSlopeFaces.Reset();
|
|
return RTERROR;
|
|
}
|
|
}
|
|
return RTNORM;
|
|
}
|
|
|
|
//extern _T("C") void get_matrix(ads_point pt1,ads_point pt2,ads_point pt3,
|
|
// ads_matrix tran_mt);
|
|
|
|
//////////////////////////////////////
|
|
// 画出所有的斜面, 调试用
|
|
// Status: 目前没有用到
|
|
int XAecRoof::DrawSlopeFaces()
|
|
{
|
|
int nSlopeNum=m_lstSlopeFaces.Length();
|
|
for(int i=0; i<nSlopeNum; i++) {
|
|
XPointList *pPoly=m_lstSlopeFaces[i];
|
|
XPointList &ptList=*pPoly;
|
|
int nTotalVertex=ptList.Length();
|
|
for(int i=0; i<nTotalVertex; i++) {
|
|
int nNext=i+1;
|
|
if(nNext==nTotalVertex) nNext=0;
|
|
XLine ln(*ptList[i], *ptList[nNext]);
|
|
ln.Make();
|
|
}
|
|
#if 0
|
|
//XPolygonEx poly(*(XPoly*)pPoly);
|
|
if(!poly) {
|
|
adsout << _T("\nerror");
|
|
return RTNORM;
|
|
}
|
|
assert(poly.Length()>=3);
|
|
ads_matrix matTran;
|
|
get_matrix(*poly[0], *poly[1], *poly[2], matTran);
|
|
poly.TransUCS(matTran);
|
|
|
|
poly.Compress();
|
|
XTrianglePface lstTris;
|
|
if(poly.Trianglize(0, lstTris)==RTNORM) {
|
|
ads_matrix aMatTran; //逆变换
|
|
for(int n=0; n<lstTris.Length(); n++) {
|
|
XTriangle *triangle=lstTris[n];
|
|
triangle->vertex1.TransformBy(aMatTran);
|
|
triangle->vertex2.TransformBy(aMatTran);
|
|
triangle->vertex3.TransformBy(aMatTran);
|
|
}
|
|
lstTris.MakePolyface();
|
|
} else {
|
|
adsout << _T("error");
|
|
return RTERROR;
|
|
}
|
|
#endif
|
|
}
|
|
return RTNORM;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// 功能: 求当前坡面的下一个屋脊线
|
|
// nThis, thisPlane -- 当前斜面的全局序号和当前斜面
|
|
// nLast, lastPlane -- 最近的一个轮面, 确定一待定下一个顶点, nLast>nThis
|
|
// ptLast -- 已经确定的前一个顶点,在lastPlane上
|
|
// pNextIndex, nextPlane -- 下一个轮面
|
|
// ptNext -- 待确定的点
|
|
// 如果返回RTERROR,则找不到
|
|
// 如果pNextIndex == nThis+nEdgeNum-1, 则下回不用再轮了, 因为下次将回到起点
|
|
int XAecRoof::GetNext(int nThis, const XPlanePara &thisPlane,
|
|
int nLast, const XPlanePara &lastPlane, const XPoint &ptLast,
|
|
int *pNextIndex, XPlanePara &nextPlane, XPoint &ptNext)
|
|
{
|
|
int nTotalEdge = GetTotalEdge();
|
|
ASSERT(nLast<nThis+nTotalEdge-1);
|
|
|
|
XPoint ptNext1;
|
|
XPlanePara nextPlane1;
|
|
int nNextIndex=0;
|
|
int bFindNext=0;
|
|
for(int i=nLast+1; i<nThis+nTotalEdge; i++) {
|
|
XPlanePara iPlane;
|
|
if(GetPlane(i, iPlane)!=RTNORM)
|
|
return RTERROR;
|
|
|
|
XPoint ptIntM;
|
|
if(!IntersectWith(thisPlane, lastPlane, iPlane, ptIntM))
|
|
continue;
|
|
///////////////////////////////////////
|
|
//验证交点的有效性:
|
|
// 1. 高于在底面
|
|
// 2. 在三个面的棱线内
|
|
// 3. 在边界内
|
|
if(ptIntM.z < m_nBottomElevation) //交点在底下,忽略
|
|
continue;
|
|
XPoint ptOnBottom=ptIntM;
|
|
ptOnBottom.z = m_nBottomElevation;
|
|
XCurveSegment lnRidgeStart, lnRidgeEnd;
|
|
lnRidgeStart.SetLineFlag(LS_INFINITE);
|
|
lnRidgeEnd.SetLineFlag(LS_INFINITE);
|
|
|
|
int indexArray[3]={nThis, nLast, i};
|
|
int bInsideLimits=TRUE;
|
|
for(int k=0; k<3; k++) {
|
|
if(GetRidge(indexArray[k], lnRidgeStart, 1)!=RTNORM ||
|
|
GetRidge(indexArray[k]+1, lnRidgeEnd, 1)!=RTNORM)
|
|
return RTERROR;
|
|
int prFlag=(ptOnBottom&lnRidgeStart);
|
|
int sideFlag=lnRidgeStart.OnWhichSide(ptOnBottom);
|
|
if(prFlag==PR_OUTSIDE && sideFlag==OFFSET_LEFT) {
|
|
bInsideLimits=FALSE;
|
|
break;
|
|
}
|
|
prFlag=(ptOnBottom&lnRidgeEnd);
|
|
sideFlag=lnRidgeEnd.OnWhichSide(ptOnBottom);
|
|
if(prFlag==PR_OUTSIDE && sideFlag==OFFSET_RIGHT) {
|
|
bInsideLimits=FALSE;
|
|
break;
|
|
}
|
|
}
|
|
if(!bInsideLimits)
|
|
continue;
|
|
|
|
|
|
if((ptOnBottom&m_polyBoundry)==PR_OUTSIDE)
|
|
continue;
|
|
if(!bFindNext) {
|
|
ptNext1=ptIntM;
|
|
nNextIndex=i;
|
|
nextPlane1 = iPlane;
|
|
bFindNext=TRUE;
|
|
} else if(ads_distance(ptLast, ptIntM)<ads_distance(ptLast, ptNext1)) {
|
|
ptNext1 = ptIntM;
|
|
nNextIndex=i;
|
|
nextPlane1 = iPlane;
|
|
}
|
|
}
|
|
if(!bFindNext)
|
|
return RTERROR;
|
|
*pNextIndex = nNextIndex;
|
|
nextPlane = nextPlane1;
|
|
ptNext = ptNext1;
|
|
return RTNORM;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
// 计算第n个坡面
|
|
int XAecRoof::CalculateSlopeFace(int n, XPointList &lstVertexes)
|
|
{
|
|
XScreenDc dc(7, 1);
|
|
XRoofEdge edge;
|
|
XPlanePara thisPlane;
|
|
if(GetEdge(n, edge)!=RTNORM || GetPlane(n, thisPlane)!=RTNORM)
|
|
return RTERROR;
|
|
|
|
lstVertexes.Reset();
|
|
lstVertexes.Append(new XPoint(edge.StartPoint()));
|
|
lstVertexes.Append(new XPoint(edge.EndPoint()));
|
|
|
|
|
|
int nTotalEdge=m_lstEdges.Length();
|
|
XPlanePara lastPlane; //初始化为底面
|
|
if(GetPlane(n+1, lastPlane)!=RTNORM)
|
|
return RTERROR;
|
|
//lastPlane.InitPlane(XPoint(0.0,0.0,nBottomElev), XVector3D(0,0,1));
|
|
//当前待定直线=thisPlane*lastPlane
|
|
int nLastIndex=n+1;
|
|
XPoint ptLast=edge.EndPoint();
|
|
while(1) {
|
|
XPoint ptNext;
|
|
XPlanePara nextPlane;
|
|
int nNextIndex;
|
|
if(GetNext(n, thisPlane, nLastIndex, lastPlane, ptLast, &nNextIndex, nextPlane, ptNext)!=RTNORM)
|
|
return RTERROR;
|
|
|
|
int nCurVertexNum=lstVertexes.Length();
|
|
//lstVertexes.Append(ptNext);
|
|
/*
|
|
XLine curLine(ptLast, ptNext, LS_FINITE); //最近的线段
|
|
for(int j=0; j<nCurVertexNum-2; j++) { //判自交叉时,不能同
|
|
XLine ln(*lstVertexes[j], *lstVertexes[j+1], LS_FINITE);
|
|
XPoint ptInter;
|
|
if(curLine.Intersection(ln, ptInter)) { //自交叉
|
|
for(int k=nCurVertexNum-2; k>=j+1; k--)
|
|
lstVertexes.Remove(k);
|
|
lstVertexes.Append(new XPoint(ptInter));
|
|
break;
|
|
}
|
|
}*/
|
|
|
|
lstVertexes.Append(new XPoint(ptNext));
|
|
if(g_nDbgFlag) {
|
|
dc << lstVertexes;
|
|
if(ads_getint(_T("\nStep: "), &nNextIndex)==RTCAN)
|
|
return RTCAN;
|
|
ads_redraw(NULL,0);
|
|
}
|
|
|
|
if(nNextIndex == n+nTotalEdge-1) // 最后一边
|
|
break;
|
|
|
|
lastPlane=nextPlane;
|
|
nLastIndex=nNextIndex;
|
|
ptLast = ptNext;
|
|
}
|
|
if(g_nDbgFlag) {
|
|
int nTemp;
|
|
dc.Draw(lstVertexes, 1);
|
|
if(ads_getint(_T("\nFinal Step: "), &nTemp)==RTCAN)
|
|
return RTCAN;
|
|
ads_redraw(NULL,0);
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
///////////////////////////////////////////////////
|
|
// 取得第n个坡面的几何平面
|
|
int XAecRoof::GetPlane(int n, XPlanePara &thisPlane) const
|
|
{
|
|
int nTotalEdge = GetTotalEdge();
|
|
n=DePeriod(nTotalEdge, n);
|
|
|
|
XRoofEdge edge;
|
|
if(GetEdge(n, edge)!=RTNORM)
|
|
return RTERROR;
|
|
|
|
XLine lnLeft=edge.Offset(-1000.0);
|
|
double nHeight=1000.0*tan(edge.m_nSlope);
|
|
XPoint pt3=lnLeft.StartPoint();
|
|
pt3.z += nHeight;
|
|
|
|
if(thisPlane.InitPlane(edge.StartPoint(), edge.EndPoint(), pt3)!=RTNORM)
|
|
return RTERROR;
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// 取得第n条棱(屋脊线)
|
|
// bOnBottom -- 是否投影到底面
|
|
int XAecRoof::GetRidge(int n, XLine &lnRidge, int bQuickGet) const
|
|
{
|
|
if(bQuickGet) {
|
|
n = DePeriod(GetTotalEdge(), n);
|
|
ASSERT(n<m_lstRidges.Length());
|
|
lnRidge = m_lstRidges[n];
|
|
return RTNORM;
|
|
}
|
|
|
|
BOOL bOnBottom=TRUE;
|
|
XPlanePara prevPlane, curPlane;
|
|
if(GetPlane(n-1, prevPlane)!=RTNORM ||
|
|
GetPlane(n, curPlane)!=RTNORM) {
|
|
return RTERROR;
|
|
}
|
|
|
|
XPlanePara topPlane, botPlane;
|
|
botPlane.InitPlane(XPoint(0.0,0.0,m_nBottomElevation), XVector3D(0,0,1));
|
|
topPlane.InitPlane(XPoint(0.0,0.0,m_nBottomElevation+1000.0), XVector3D(0,0,1));
|
|
XPoint pt1, pt2;
|
|
if(!IntersectWith(prevPlane, curPlane, botPlane, pt1) ||
|
|
!IntersectWith(prevPlane, curPlane, topPlane, pt2) )
|
|
return RTERROR;
|
|
|
|
if(bOnBottom) {
|
|
pt1.z = pt2.z = m_nBottomElevation;
|
|
}
|
|
lnRidge.StartPoint() = pt1;
|
|
lnRidge.EndPoint() = pt2;
|
|
return RTNORM;
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
|
// 取得第n条边
|
|
int XAecRoof::GetEdge(int n, XRoofEdge &edge) const
|
|
{
|
|
int nNext=n+1;
|
|
int nEdgeNum=m_lstEdges.Length();
|
|
n = DePeriod(nEdgeNum, n);
|
|
nNext = DePeriod(nEdgeNum, nNext);
|
|
|
|
edge.StartPoint() = m_lstEdges[n].m_ptVertex;
|
|
edge.m_nSlope = m_lstEdges[n].m_nSlope;
|
|
edge.EndPoint() = m_lstEdges[nNext].m_ptVertex;
|
|
return RTNORM;
|
|
}
|
|
|
|
//////////////////////////////////////////
|
|
// 求所有坡面的总面积
|
|
double XAecRoof::GetTotalSurfaceArea() const
|
|
{
|
|
double nArea = 0.0;
|
|
for(int i=0; i<m_lstSlopeFaces.Length(); i++) {
|
|
nArea += GetSlopeArea(i);
|
|
}
|
|
return nArea;
|
|
}
|
|
|
|
//////////////////////////////////////////
|
|
// 求第n个斜面的面积
|
|
double XAecRoof::GetSlopeArea(int n) const
|
|
{
|
|
//return 0.0;
|
|
if(!m_lstSlopeFaces.Length())
|
|
return 0.0;
|
|
|
|
ASSERT(n<m_lstSlopeFaces.Length());
|
|
const XPointList &slopeFace=m_lstSlopeFaces[n];
|
|
ASSERT(slopeFace.Length()>=3);
|
|
|
|
double nSlopeAngle=m_lstEdges[n].m_nSlope;
|
|
|
|
ads_matrix matTran;
|
|
get_matrix(slopeFace[0], slopeFace[1], slopeFace[2], matTran);
|
|
|
|
XPoly2D poly(1);
|
|
for(int i=0; i<slopeFace.Length(); i++) {
|
|
XPoint ptVertex = slopeFace[i];
|
|
//ptVertex.z=0;
|
|
ptVertex.TransformBy(matTran);
|
|
poly.AppendNode(ptVertex);
|
|
}
|
|
double nRes=poly.Area();
|
|
//ASSERT(nSlopeAngle>0.0);
|
|
//double nRes=((XPoly &)slopeFace).Area()/cos(nSlopeAngle);
|
|
return nRes;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 求面的描述
|
|
// 由调用函数负责释放点表和面表
|
|
typedef DList<int> IntList;
|
|
int XAecRoof::GetSurfaceData(int *nVerticeNum, XPoint * &pVerticeList,
|
|
int *pFaceListLen, Adesk::Int32 * &pFaceList,
|
|
Adesk::UInt8 * &pEdgeVisArray) const
|
|
{
|
|
int nTotalFaceNum=m_lstSlopeFaces.Length();
|
|
if(!nTotalFaceNum)
|
|
return RTERROR;
|
|
int nTotalEdge=GetTotalEdge();
|
|
|
|
XPointList lstVertices;
|
|
DList<IntList> lstFaces;
|
|
DList<IntList> lstEdgeVis; //边的可见性
|
|
int nFaceListLen=0;
|
|
int nEdgeListLen=0;
|
|
for(int i=0; i<nTotalFaceNum; i++) {
|
|
if(nTotalFaceNum==nTotalEdge &&
|
|
fabs(m_lstEdges[i].m_nSlope-PI/2.0)<_angSnap)
|
|
continue;
|
|
|
|
const XPointList &slopeFace = m_lstSlopeFaces[i];
|
|
ASSERT(slopeFace.Length()>=3);
|
|
DList<int> *pFace = new DList<int>;
|
|
DList<int> *pEdge = new DList<int>;
|
|
int nLastVertex=0;
|
|
int nFirstVertexIndex=0;
|
|
double nPreSlope=m_lstEdges[DePeriod(nTotalEdge, i-1)].m_nSlope;
|
|
double nNextSlope=m_lstEdges[DePeriod(nTotalEdge, i+1)].m_nSlope;
|
|
for(int j=0; j<slopeFace.Length(); j++) {
|
|
int nCurIndex=0;
|
|
const XPoint &ptCur=slopeFace[j];
|
|
if(lstVertices.FindPoint(ptCur)) {
|
|
nCurIndex=lstVertices.CurPosition();
|
|
} else {
|
|
nCurIndex=lstVertices.Length();
|
|
lstVertices.Append(new XPoint(ptCur));
|
|
}
|
|
pFace->Append(new int(nCurIndex));
|
|
if(j==0) nFirstVertexIndex = nCurIndex;
|
|
else if(j==1) { //第2个顶点确定第一边, 底边
|
|
pEdge->Append(new int(m_bBotVisible? kAcGiVisible : kAcGiInvisible));
|
|
} else { //否则升序的边为可见
|
|
if(fabs(nPreSlope-PI/2)<_angSnap || fabs(nNextSlope-PI/2)<_angSnap) {
|
|
pEdge->Append(new int(kAcGiVisible));
|
|
} else {
|
|
if(nCurIndex>nLastVertex) pEdge->Append(new int(kAcGiVisible));
|
|
else pEdge->Append(new int(kAcGiInvisible));
|
|
}
|
|
}
|
|
nLastVertex = nCurIndex;
|
|
}
|
|
if(fabs(nPreSlope-PI/2)<_angSnap || fabs(nNextSlope-PI/2)<_angSnap) {
|
|
pEdge->Append(new int(kAcGiVisible));
|
|
} else {
|
|
//最后一边 nLastVertex->nFirstVertexIndex
|
|
if(nFirstVertexIndex>nLastVertex) pEdge->Append(new int(kAcGiVisible));
|
|
else pEdge->Append(new int(kAcGiInvisible));
|
|
}
|
|
|
|
lstFaces.Append(pFace);
|
|
lstEdgeVis.Append(pEdge);
|
|
nEdgeListLen += pEdge->Length();
|
|
nFaceListLen += slopeFace.Length()+1;
|
|
}
|
|
|
|
*nVerticeNum = lstVertices.Length();
|
|
pVerticeList = new XPoint[*nVerticeNum];
|
|
for(i=0; i<*nVerticeNum; i++) {
|
|
pVerticeList[i]=*lstVertices[i];
|
|
}
|
|
*pFaceListLen = nFaceListLen;
|
|
pFaceList = new Adesk::Int32[nFaceListLen];
|
|
Adesk::Int32 *pInt=pFaceList;
|
|
for(i=0; i<lstFaces.Length(); i++) {
|
|
DList<int> *pFace=lstFaces[i];
|
|
*pInt = pFace->Length();
|
|
pInt ++;
|
|
for(int j=0; j<pFace->Length(); j++) {
|
|
*pInt = *(*pFace)[j];
|
|
pInt ++;
|
|
}
|
|
}
|
|
|
|
pEdgeVisArray = new Adesk::UInt8[nEdgeListLen];
|
|
Adesk::UInt8 *pUInt=pEdgeVisArray;
|
|
for(i=0; i<lstEdgeVis.Length(); i++) {
|
|
DList<int> *pEdge=lstEdgeVis[i];
|
|
for(int j=0; j<pEdge->Length(); j++) {
|
|
*pUInt = *(*pEdge)[j];
|
|
pUInt ++;
|
|
}
|
|
}
|
|
return RTNORM;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 求边的描述
|
|
// 由调用函数负责释放点表和面表
|
|
|
|
static int CompareForFindNode(const XIntDotPair *p1, const void *p2)
|
|
{
|
|
const XIntDotPair *pp2 = (const XIntDotPair *)p2;
|
|
if((p1->nFrom==pp2->nFrom && p1->nTo==pp2->nTo) ||
|
|
(p1->nFrom==pp2->nTo && p1->nTo==pp2->nFrom))
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
|
|
int XAecRoof::GetEdgeData(XPointList &lstVertices, DList<XIntDotPair> &lstEdgeData) const
|
|
{
|
|
int nTotalFaceNum=m_lstSlopeFaces.Length();
|
|
if(!nTotalFaceNum)
|
|
return RTERROR;
|
|
|
|
for(int i=0; i<nTotalFaceNum; i++) {
|
|
const XPointList &slopeFace = m_lstSlopeFaces[i];
|
|
ASSERT(slopeFace.Length()>=3);
|
|
const XPoint &ptLast=slopeFace[0];
|
|
int nLast=0;
|
|
if(lstVertices.FindPoint(ptLast)) {
|
|
nLast=lstVertices.CurPosition();
|
|
} else {
|
|
nLast=lstVertices.Length();
|
|
lstVertices.Append(new XPoint(ptLast));
|
|
}
|
|
int nFirst=nLast;
|
|
for(int j=1; j<=slopeFace.Length(); j++) {
|
|
int nCurIndex=0;
|
|
if(j==slopeFace.Length()) {
|
|
nCurIndex = nFirst;
|
|
} else {
|
|
const XPoint &ptCur=slopeFace[j];
|
|
if(lstVertices.FindPoint(ptCur)) {
|
|
nCurIndex=lstVertices.CurPosition();
|
|
} else {
|
|
nCurIndex=lstVertices.Length();
|
|
lstVertices.Append(new XPoint(ptCur));
|
|
}
|
|
}
|
|
XIntDotPair edge(nLast, nCurIndex);
|
|
if(!lstEdgeData.FindNode(&edge, CompareForFindNode))
|
|
lstEdgeData.Append(new XIntDotPair(edge));
|
|
nLast = nCurIndex;
|
|
}
|
|
}
|
|
return RTNORM;
|
|
}
|
|
|
|
|