找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1443|回复: 1

[分享] GeUtilities

[复制链接]

已领礼包: 1268个

财富等级: 财源广进

发表于 2014-7-12 08:22:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
#include "stdafx.h"
#include "stdarx.h"

#include <MATH.H>

#include "GeUtilities.h"
#include "BrUtilities.h"
#include "CreateDbObj.h"
#include "DbUtilities.h"

void getPntsFromSpline(AcDbSpline *spl,AcGePoint3dArray& pnts)
{
        int i,num;
        if (spl->hasFitData()) {
                num = spl->numFitPoints();
                pnts.setLogicalLength(num);
                for (i=0; i<num; i++) {
                        spl->getFitPointAt(i,pnts[i]);
                }
        } else {
                int degree;
                Adesk::Boolean bTmp;
                AcGePoint3dArray tPnts;
                AcGeDoubleArray weights,knots;
                double dTmp,dTol;
                spl->getNurbsData(degree,bTmp,bTmp,bTmp,tPnts,knots,weights,dTmp,dTol);
                num = knots.length();
                pnts.setLogicalLength(num);
                int j = 0;
                spl->getPointAtParam(knots[0],pnts[0]);
                for (i=1; i<num; i++) {
                        if (fabs(knots[i]-knots[i-1]) > dTol) {
                                j++;
                                spl->getPointAtParam(knots[i],pnts[j]);
                        }
                }
                pnts.setLogicalLength(j+1);
        }
}

void getPntsFromSpline(AcDbSpline *spl,AcGePoint3dArray& pnts,int pointnum)
{
        int i,num;
        if (spl->hasFitData()) {
                num = spl->numFitPoints();
                pnts.setLogicalLength(num);
                for (i=0; i<num; i++) {
                        spl->getFitPointAt(i,pnts[i]);
                }
        } else {
                int degree;
                Adesk::Boolean bTmp;
                AcGePoint3dArray tPnts;
                AcGeDoubleArray weights,knots;
                double dTmp,dTol;
                spl->getNurbsData(degree,bTmp,bTmp,bTmp,tPnts,knots,weights,dTmp,dTol);
                num = knots.length();
                if (num<pointnum && pointnum>2) {
                        double minKnot,maxKnot,step;
                        minKnot = knots[0];
                        maxKnot = knots[num-1];
                        step = (maxKnot-minKnot)/(pointnum-1);
                        knots.setLogicalLength(pointnum);
                        num = pointnum;
                        knots[0] = minKnot;
                        for (i=1; i<num; i++) {
                                knots[i] = knots[i-1] + step;
                        }
                }
                pnts.setLogicalLength(num);
                int j = 0;
                spl->getPointAtParam(knots[0],pnts[0]);
                for (i=1; i<num; i++) {
                        if (fabs(knots[i]-knots[i-1]) > dTol) {
                                j++;
                                spl->getPointAtParam(knots[i],pnts[j]);
                        }
                }
                pnts.setLogicalLength(j+1);
        }
}

bool
getPntsFromCurve(AcDbCurve *pCurve,
                                 AcGePoint3dArray& pnts,
                                 int numPoint)
{
        if (   numPoint<0
                || numPoint==1
                || !pCurve->isA()) return false;
       
        pnts.setLogicalLength(0);
        AcDbSpline *spl;
        if (pCurve->getSpline(spl) == Acad::eOk) {
                if (numPoint==0) {
                        getPntsFromSpline(spl,pnts);
                } else {
                        getPntsFromSpline(spl,pnts,numPoint);
                }
                delete spl;
                return true;
        }
       
        if (pCurve->isKindOf(AcDbLine::desc())) { // LINE
                AcDbLine *pLine;
                pLine = AcDbLine::cast(pCurve);
                if (numPoint==0) {
                        pnts.append(pLine->startPoint());
                        pnts.append(pLine->endPoint());
                } else {
                        double start,step;
                        AcGePoint3d pnt;
                        pLine->getStartParam(start);
                        pLine->getEndParam(step);
                        step = (step-start)/(numPoint-1);
                        for (register i=0; i<numPoint; i++) {
                                pLine->getPointAtParam(start,pnt);
                                pnts.append(pnt);
                                start = start + step;
                        }
                }
                return true;
        }
       
        if (pCurve->isKindOf(AcDbPolyline::desc())) { // LWPOLYLINE
                AcDbPolyline *pPLine;
                AcGePoint3d pnt;
                pPLine = AcDbPolyline::cast(pCurve);
                int len;
                len = pPLine->numVerts();
                for (register i=0; i<len; i++) {
                        pPLine->getPointAt(i,pnt);
                        pnts.append(pnt);
                }
                return true;
        }  
       
        return false;
}

bool
getPntsFromCurve(AcGeCurve3d *pCurve,
                                 AcGePoint3dArray& pnts,
                                 int numPoint)
{
        if (   numPoint<0
                || numPoint==1 ) return false;

        pnts.setLogicalLength(0);

        AcGe::EntityId type;
        type = pCurve->type();

        AcGeCurve3d *pNative;
        bool bNative = false;
        if (type == AcGe::kExternalCurve3d) {
                if (((AcGeExternalCurve3d*)pCurve)->isNativeCurve(pNative)) {
                        bNative = true;
                        type = pNative->type();
                } else {
                        return false;
                }
        } else {
                pNative = pCurve;
        }

        switch(type) {
        case AcGe::kLineSeg3d :
                if (numPoint==0) {
                        pnts.setLogicalLength(2);
                        pNative->hasStartPoint(pnts[0]);
                        pNative->hasEndPoint(pnts[1]);
                } else {
                        pNative->getSamplePoints(numPoint,pnts);
                }
                break;
        case AcGe::kCircArc3d :
        case AcGe::kEllipArc3d :
                if (numPoint == 0) {
                        pNative->getSamplePoints(9,pnts);
                } else {
                        pNative->getSamplePoints(numPoint,pnts);
                }
                break;
        case AcGe::kNurbCurve3d :
                getPntsFromSpline(*(AcGeNurbCurve3d*)pNative,pnts,numPoint);
                break;
        case AcGe::kPolyline3d :
                AcGePolyline3d *pPoly;
                pPoly = (AcGePolyline3d*)pNative;
                int i,len;
                len = pPoly->numControlPoints();
                pnts.setLogicalLength(len);
                for (i=0; i<len; i++) {
                        pnts[i]  = pPoly->controlPointAt(i);
                }
                break;
        default:
                if (bNative) delete pNative;
                return false;
        }

        if (bNative) delete pNative;
       
        return true;
}

int minArr(const AcGeDoubleArray& arr)
{
        int pos=0,i;
        double min = arr[0];
        for(i=1;i<arr.length();i++) {
                if(arr[i]<min) {
                        min = arr[i];
                        pos = i;
                }
        }
        return pos;
}

int maxArr(const AcGeDoubleArray& arr)
{
        int pos=0,i;
        double max = arr[0];
        for(i=1;i<arr.length();i++) {
                if(arr[i]>max) {
                        max = arr[i];
                        pos = i;
                }
        }
        return pos;
}

int Round(const double& x)
{
        if (x>0) {
                return int(x+0.5f);
        } else {
                return int(x-0.5f);
        }
}

double triangleArea(const AcGePoint2d& p1, const AcGePoint2d& p2, const AcGePoint2d& p3)
{
        double area;
        AcGeMatrix3d mat1;

        mat1.setCoordSystem(AcGePoint3d(0.0f,0.0f,0.0f),AcGeVector3d(p1.x,p2.x,p3.x),
                AcGeVector3d(p1.y,p2.y,p3.y),AcGeVector3d(1.0f,1.0f,1.0f));
       
        area = mat1.det()/2.0;

        return area;

}


double triangleArea(const AcGePoint3d& p1, const AcGePoint3d& p2, const AcGePoint3d& p3)
{
        double area,a1,a2,a3;
        AcGeMatrix3d mat1;

        mat1.setCoordSystem(AcGePoint3d(0.0f,0.0f,0.0f),AcGeVector3d(p1.x,p2.x,p3.x),
                AcGeVector3d(p1.y,p2.y,p3.y),AcGeVector3d(1.0f,1.0f,1.0f));       
        a1 = mat1.det();

        mat1.setCoordSystem(AcGePoint3d(0.0f,0.0f,0.0f),AcGeVector3d(p1.y,p2.y,p3.y),
                AcGeVector3d(p1.z,p2.z,p3.z),AcGeVector3d(1.0f,1.0f,1.0f));       
        a2 = mat1.det();

        mat1.setCoordSystem(AcGePoint3d(0.0f,0.0f,0.0f),AcGeVector3d(p1.z,p2.z,p3.z),
                AcGeVector3d(p1.x,p2.x,p3.x),AcGeVector3d(1.0f,1.0f,1.0f));       
        a3 = mat1.det();

        area = sqrt(a1*a1+a2*a2+a3*a3)/2.0;

        return area;
}

void reverse(ChGePnts2dArray& pntsArr)
{
        int i,len;
        len = pntsArr.length();
        for (i=0; i<len; i++) {
                pntsArr[i].reverse();
        }
        if (len>1) {
                pntsArr.reverse();
        }
}

void reverse(ChGePnts3dArray& pntsArr)
{
        int i,len;
        len = pntsArr.length();
        for (i=0; i<len; i++) {
                pntsArr[i].reverse();
        }
        if (len>1) {
                pntsArr.reverse();
        }
}

// 判断矢量vec1到vec2的方向是否为顺时针
Adesk::Boolean isClockwise(const AcGeVector2d& vec1, const AcGeVector2d& vec2)
{
        AcGeVector3d vec3d1(vec1.x,vec1.y,0),vec3d2(vec2.x,vec2.y,0);
       
        Adesk::Boolean bRet;
        bRet = AcGeVector3d::kZAxis.isCodirectionalTo(
                vec3d2.crossProduct(vec3d1));

        return bRet;
}

// 判断点是否在直线的右手边
Adesk::Boolean isClockwise(const AcGeLine2d& line, const AcGePoint2d& pnt)
{
        AcGePoint2d perpPnt;
        AcGeLine2d perpLine,dirLine;

        line.getPerpLine(pnt,perpLine);
        line.intersectWith(perpLine,perpPnt);
        dirLine.set(perpPnt,pnt);

        return !perpLine.direction().isCodirectionalTo(dirLine.direction());
}

// 判断点是否在直线的右手边
Adesk::Boolean isClockwise(const AcGePoint2d& pnt,const AcGePoint2d& p1,const AcGePoint2d& p2)
{
        AcGePoint2d perpPnt;
        AcGeLine2d perpLine,dirLine;
        AcGeLine2d line(p1,p2);

        line.getPerpLine(pnt,perpLine);
        line.intersectWith(perpLine,perpPnt);
        dirLine.set(perpPnt,pnt);

        return !perpLine.direction().isCodirectionalTo(dirLine.direction());
}

// 判断曲面上点相对曲线的方向,true右或false左
bool isClockwise(const AcGeNurbSurface& surf,const AcGePoint3dArray& curve,const AcGePoint3d& dirPnt)
{
        // 参数平面上的点
        AcGePoint2dArray curve2d;
        AcGePoint2d dirPnt2d;
        AcGePoint3d pnt;

        int i,len;
        len = curve.length();
        if (!len) return false;
        AcGePoint2d tParam2d;
        for (i=0; i<len; i++) {
                pnt = surf.closestPointTo(curve[i]);
                surf.isOn(pnt,tParam2d);
                curve2d.append(tParam2d);
        }
       
        pnt = surf.closestPointTo(dirPnt);
        surf.isOn(pnt,dirPnt2d);
//        dirPnt2d = surf.paramOf(pnt);

        bool bDirRight = false;
        AcGeNurbCurve2d spl(curve2d);
        if (isClockwise(dirPnt2d,spl)) {
                bDirRight = true;
        }

        return bDirRight;
}

// 由三点得到平面,当返回值Acad::eOk时返回的pln才有意义
Acad::ErrorStatus getPlaneFrom3Pnts(const AcGePoint3dArray& pnts,AcGePlane& pln)
{
        if(pnts.length()!=3) return Acad::eInvalidInput;
       
        AcGeVector3d vec1,vec2;
        AcGePoint3d p1,p2,p;

        vec1 = pnts[1]-pnts[0];
        vec2 = pnts[2]-pnts[0];
        vec1 = vec1.crossProduct(vec2);
       
        pln.set(pnts[0],vec1);
        pln.get(p1,p,p2);

        if(p1.isEqualTo(AcGePoint3d(0.0f,0.0f,0.0f))) return  Acad::eInvalidInput;
        else return Acad::eOk;
}

// 由三点得到平面,当返回值Acad::eOk时返回的pln才有意义
Acad::ErrorStatus getPlaneFrom3Pnts(const AcGePoint3d& pp1, const AcGePoint3d& pp2,
                                                                        const AcGePoint3d& pp3,AcGePlane& pln)
{
        AcGePoint3dArray pnts;
        pnts.append(pp1);
        pnts.append(pp2);
        pnts.append(pp3);

        AcGeVector3d vec1,vec2;
        AcGePoint3d p1,p2,p;

        vec1 = pnts[1]-pnts[0];
        vec2 = pnts[2]-pnts[0];
        vec1 = vec1.crossProduct(vec2);
       
        pln.set(pnts[0],vec1);
        pln.get(p1,p,p2);

        if(p1.isEqualTo(AcGePoint3d(0.0f,0.0f,0.0f))) return  Acad::eInvalidInput;
        else return Acad::eOk;
}


// 判断点相对于线段的位置,平面                       
int pointPosToLine(const AcGePoint2d& p,const AcGePoint2d& p1,const AcGePoint2d& p2)
{
        AcGeVector2d vec1,vec2;
        double angle;

        if(p.isEqualTo(p1)) return 1;                // 点与线段第一点重合
        if(p.isEqualTo(p2)) return 2;                // 点与线段第二点重合

        vec1 = p1-p;
        vec2 = p2-p;
        angle = vec1.angleTo(vec2);

        if(fabs(angle-PI)<TOL) return 0;                                // 点在线段上
        else if(angle<TOL) return 3;                        // 点在线段延长线上
        else return -1;                                                // 点在线段外
       
}


// 判断点相对于线段的位置,空间
int pointPosToLine(const AcGePoint3d& p,const AcGePoint3d& p1,const AcGePoint3d& p2)
{
        AcGeVector3d vec1,vec2;
        double angle;

        if(p.isEqualTo(p1)) return 1;                // 点与线段第一点重合
        if(p.isEqualTo(p2)) return 2;                // 点与线段第二点重合

        vec1 = p1-p;
        vec2 = p2-p;
        angle = vec1.angleTo(vec2);

        if(fabs(angle-PI)<TOL) return 0;                                // 点在线段上
        else if(fabs(angle)<TOL) return 3;                        // 点在线段延长线上
        else return -1;                                                // 点在线段外
       
}



// 判断点相对于三角形的位置
int pointPosToTriangle(const AcGePoint2d& pnt,AcGePoint2dArray& pnts)
{
        int pos;

        if (pnts.length()<3) return -1; // 不是三角形

        if(pnt.isEqualTo(pnts[0])) return 1;                // 点与三角形第一点重合
        if(pnt.isEqualTo(pnts[1])) return 2;                // 点与三角形第二点重合
        if(pnt.isEqualTo(pnts[2])) return 3;                // 点与三角形第三点重合

        pos = pointPosToLine(pnt,pnts[0],pnts[1]);
        if(pos==0) return 4;
        else if(pos==3) return -1;

        pos = pointPosToLine(pnt,pnts[1],pnts[2]);
        if(pos==0) return 5;
        else if(pos==3) return -1;

        pos = pointPosToLine(pnt,pnts[2],pnts[0]);
        if(pos==0) return 6;
        else if(pos==3) return -1;

        if(isClockwise(pnt,pnts[0],pnts[1])) return -1;
        if(isClockwise(pnt,pnts[1],pnts[2])) return -1;
        if(isClockwise(pnt,pnts[2],pnts[0])) return -1;
                                                                                                                                                    
        return 0;
}

// 由面积等比原则,通过三角形p1p2p3内一点p4,及对应得三角形r1r2r3,得出对应的点r4
bool mapPointInTriangle(AcGePoint2dArray& pnts1,AcGePoint2dArray& pnts2)
{
        if (pnts1.length()!=4 || pnts2.length()!=4) return false;

        double sigma[3],A,B,C,D,E,F,x,y;

        sigma[0] = triangleArea(pnts1[0],pnts1[1],pnts1[3]);
        sigma[1] = triangleArea(pnts1[1],pnts1[2],pnts1[3]);
        sigma[2] = triangleArea(pnts1[2],pnts1[0],pnts1[3]);

        A = (pnts2[1].y-pnts2[2].y)*sigma[2] - (pnts2[2].y-pnts2[0].y)*sigma[1];
        B = (pnts2[1].x-pnts2[2].x)*sigma[2] - (pnts2[2].x-pnts2[0].x)*sigma[1];
        C = (pnts2[1].x*pnts2[2].y-pnts2[2].x*pnts2[1].y)*sigma[2] -
                (pnts2[2].x*pnts2[0].y-pnts2[0].x*pnts2[2].y)*sigma[1];
        D = (pnts2[0].y-pnts2[1].y)*sigma[1] - (pnts2[1].y-pnts2[2].y)*sigma[0];
        E = (pnts2[0].x-pnts2[1].x)*sigma[1] - (pnts2[1].x-pnts2[2].x)*sigma[0];
        F = (pnts2[0].x*pnts2[1].y-pnts2[1].x*pnts2[0].y)*sigma[1] -
                (pnts2[1].x*pnts2[2].y-pnts2[2].x*pnts2[1].y)*sigma[0];
        x = (C*E-B*F)/(B*D-A*E);
        y = (C*D-A*F)/(B*D-A*E);
        pnts2[3].set(x,y);

        return true;
}

// 由等比原则,通过, 线段p1p2内一点p3,及对应的线段r1r2,得出r1r2上对应的点r3
void mapPointInLine(AcGePoint2dArray& pnts1,AcGePoint2dArray& pnts2)
{
        double sc;
       
        sc = (pnts1[2]-pnts1[0]).length()/(pnts1[1]-pnts1[0]).length();
       
        pnts2[2] = pnts2[0] + (pnts2[1]-pnts2[0])*sc;
}

// 由等比原则,通过, 线段p1p2内一点p3,及对应的线段r1r2,得出r1r2上对应的点r3
void mapPointInLine(AcGePoint3dArray& pnts1,AcGePoint2dArray& pnts2)
{
        double sc;

        sc = (pnts1[2]-pnts1[0]).length()/(pnts1[1]-pnts1[0]).length();
       
        pnts2[2] = pnts2[0] + (pnts2[1]-pnts2[0])*sc;
}

// 由等比原则,通过, 线段p1p2内一点p3,及对应的线段r1r2,得出r1r2上对应的点r3
void mapPointInLine(AcGePoint2dArray& pnts1,AcGePoint3dArray& pnts2)
{
        double sc;

        sc = (pnts1[2]-pnts1[0]).length()/(pnts1[1]-pnts1[0]).length();

        pnts2[2] = pnts2[0] + (pnts2[1]-pnts2[0])*sc;
       
}


bool mapPointTriangle(AcGePoint2dArray& pnts, AcGePoint2dArray& mpnts, bool bIfMapOut)
{
        if (pnts.length()!=4 || mpnts.length()!=4) return false;
       
        int pos;
       
        pos = pointPosToTriangle(pnts[3],pnts);
        if (pos>0) {
                mapPointOnTriangle(pnts,pos,mpnts);
                return true;
        } else if (pos==0) {
                mapPointInTriangle(pnts,mpnts);
                return true;
        } else {
                if (bIfMapOut) {
                        mapPointInTriangle(pnts,mpnts);
                }
        }
       
        return false;
}


// 三角形上(内,顶点,边),得出其映射点
bool mapPointOnTriangle(AcGePoint2dArray& pnts, int pos, AcGePoint2dArray& mpnts)
{
        if (pos<1 || pos>6) return false;
        if (pnts.length()!=4 || mpnts.length()!=4) return false;

        AcGePoint2dArray line,mline;
        line.setLogicalLength(3);
        mline.setLogicalLength(3);

        switch(pos) {
        case 1:
                mpnts[3] = mpnts[0];
                break;
        case 2:
                mpnts[3] = mpnts[1];
                break;
        case 3:
                mpnts[3] = mpnts[2];
                break;
        case 4:
                line[0] = pnts[0];
                line[1] = pnts[1];
                line[2] = pnts[3];
                mline[0] = mpnts[0];
                mline[1] = mpnts[1];
                mapPointInLine(line,mline);
                mpnts[3] = mline[2];
                break;
        case 5:
                line[0] = pnts[1];
                line[1] = pnts[2];
                line[2] = pnts[3];
                mline[0] = mpnts[1];
                mline[1] = mpnts[2];
                mapPointInLine(line,mline);
                mpnts[3] = mline[2];
                break;
        case 6:
                line[0] = pnts[2];
                line[1] = pnts[0];
                line[2] = pnts[3];
                mline[0] = mpnts[2];
                mline[1] = mpnts[0];
                mapPointInLine(line,mline);
                mpnts[3] = mline[2];
                break;
        }

        return true;
}

Adesk::Boolean isOnCurve(const AcGePoint2d& pnt, const AcGeNurbCurve2d& curve,const double& tol)
{
        AcGePoint2d tmpp;
        AcGeVector2dArray derivs;
        AcGeVector2d vec;
        tmpp = curve.closestPointTo(pnt);
        if(tmpp.distanceTo(pnt)<tol) return true;

        return false;
}

Adesk::Boolean isOnCurve(const AcGePoint2d& pnt, const AcGePolyline2d& ply,const double& tol)
{
        double dist;
        int i,len;
        AcGeLineSeg2d line;

        len = ply.numFitPoints();

        for (i=0; i<len-1; i++) {
                line.set(ply.fitPointAt(i),ply.fitPointAt(i+1));
                dist = line.distanceTo(pnt);
                if (dist < tol) return true;
        }
       
        return false;
}

Adesk::Boolean isClockwise(const AcGePoint2d& pnt, const AcGePolyline2d& ply)
{
        AcGePoint2d closestPnt,tmpPnt;
        AcGeVector2d vec,vec2,vec3;

        double dist,min;
        int i,len,minIndex;
        AcGeLineSeg2d lineseg;
        len = ply.numFitPoints();
        closestPnt = ply.fitPointAt(0);
        min = pnt.distanceTo(closestPnt);
        minIndex = 0;
        for (i=0; i<len-1; i++) {
                lineseg.set(ply.fitPointAt(i),ply.fitPointAt(i+1));
                tmpPnt = lineseg.closestPointTo(pnt);
                dist = pnt.distanceTo(tmpPnt);
                if (dist < min) {
                        minIndex = i;
                        min = dist;
                        closestPnt = tmpPnt;
                }
        }
        vec = pnt - closestPnt;

        if (len == 2) {
                vec2 = ply.fitPointAt(1) - ply.fitPointAt(0);
                return isClockwise(vec2,vec);
        }

        if (!closestPnt.isEqualTo(ply.fitPointAt(minIndex))
                && !closestPnt.isEqualTo(ply.fitPointAt(minIndex+1))) {
                // 最近点不是顶点
                vec2 = ply.fitPointAt(minIndex+1) - ply.fitPointAt(minIndex);
                return isClockwise(vec2,vec);
        }

        if (closestPnt.isEqualTo(ply.fitPointAt(minIndex+1))) {
                minIndex = minIndex + 1;
        }

        if (   minIndex == 0 || minIndex == len-1 ) {
                if (ply.fitPointAt(0).isEqualTo(ply.fitPointAt(len-1))) {
                        vec2 = closestPnt - ply.fitPointAt(len-2);
                        vec3 = ply.fitPointAt(1) - closestPnt;
                } else {
                        if (minIndex == 0) {
                                vec2 = ply.fitPointAt(1) - closestPnt;
                        } else {
                                vec2 = closestPnt - ply.fitPointAt(len-2);
                        }
                        return isClockwise(vec2,vec);
                }
        } else {
                vec2 = ply.fitPointAt(minIndex) - ply.fitPointAt(minIndex-1);
                vec3 = ply.fitPointAt(minIndex+1) - ply.fitPointAt(minIndex);
        }

        if (isClockwise(vec2,vec3)) {
                if (isClockwise(vec2,vec) && isClockwise(vec3,vec)) {
                        return Adesk::kTrue;
                } else {
                        return Adesk::kFalse;
                }
        } else {
                if (isClockwise(vec2,vec) || isClockwise(vec3,vec)) {
                        return Adesk::kTrue;
                } else {
                        return Adesk::kFalse;
                }
        }
}


Adesk::Boolean isClockwise(const AcGePoint2d& pnt, const AcGeNurbCurve2d& spl)
{
        AcGePoint2d closedPnt;
        double param;
        AcGePointOnCurve2d pntOncrv;
        AcGeVector2d vec,vec2,vec3;

        spl.getClosestPointTo(pnt,pntOncrv);
        param = pntOncrv.parameter();
        closedPnt = pntOncrv.point();
        vec = pnt-closedPnt;

        if (   param == spl.startParam()
                || param == spl.endParam()) {
                if (spl.startPoint().isEqualTo(spl.endPoint())) {
                        vec2 = pntOncrv.deriv(1,spl.endParam());
                        vec3 = pntOncrv.deriv(1,spl.startParam());
                } else {
                        vec2 = pntOncrv.deriv(1);
                        return isClockwise(vec2,vec);
                }
        } else {
                AcGeDoubleArray params;
                spl.getParamsOfG1Discontinuity(params);
               
                if (params.contains(param)) {
                        // 该点为方向矢量不连续点
                        vec3 = pntOncrv.deriv(1);
                        AcGeNurbCurve2d splCopy(spl);
                        splCopy.hardTrimByParams(splCopy.startParam(),param);
                        pntOncrv.setCurve(splCopy);
                        vec2 = pntOncrv.deriv(1,param);
                } else {
                        vec2 = pntOncrv.deriv(1);
                        return isClockwise(vec2,vec);
                }
        }

        if (isClockwise(vec2,vec3)) {
                if (isClockwise(vec2,vec) && isClockwise(vec3,vec)) {
                        return Adesk::kTrue;
                } else {
                        return Adesk::kFalse;
                }
        } else {
                if (isClockwise(vec2,vec) || isClockwise(vec3,vec)) {
                        return Adesk::kTrue;
                } else {
                        return Adesk::kFalse;
                }
        }
}

/*
// verify if point is on the right of curve
Adesk::Boolean isClockwise(const AcGePoint2d& pnt, const AcGeCurve2d& crv)
{
        AcGePoint2d tmpp;
        AcGeVector2d deriv;
        AcGeVector2d vec;
        AcGePointOnCurve2d pntOnCrv;

        crv.getClosestPointTo(pnt,pntOnCrv);
        tmpp = pntOnCrv.point();

        double param1,len;
        AcGeInterval intrvl;
        crv.getInterval(intrvl);
        param1 = pntOnCrv.parameter();
        vec = pnt-tmpp;
        len = crv.length(intrvl.lowerBound(),intrvl.upperBound())/1000;
        double param2,param3;
        if (   crv.length(param1,intrvl.upperBound()) < len
                || crv.length(intrvl.lowerBound(),param1) < len) {
                // 最近点在曲线尾或头
                if ( !crv.evalPoint(intrvl.lowerBound()).isEqualTo(
                          crv.evalPoint(intrvl.upperBound()))) {
                        deriv = pntOnCrv.deriv(1);
                        return isClockwise(deriv,vec);
                } else {
                        param1 = intrvl.lowerBound();
                        param2 = crv.paramAtLength(intrvl.upperBound(),len,Adesk::kFalse);
                        param3 = crv.paramAtLength(param1,len);
                }
        } else {
                param2 = crv.paramAtLength(param1,len,Adesk::kFalse);
                param3 = crv.paramAtLength(param1,len);
        }

        AcGeVector2d vec2,vec3;
        vec2 = tmpp - crv.evalPoint(param2);
        vec3 = crv.evalPoint(param3) - tmpp;

        if (isClockwise(vec2,vec3)) {
                if (!isClockwise(vec2,vec) || !isClockwise(vec3,vec)) {
                        return Adesk::kFalse;
                } else {
                        return Adesk::kTrue;
                }
        } else {
                if (isClockwise(vec2,vec) || isClockwise(vec3,vec)) {
                        return Adesk::kTrue;
                } else {
                        return Adesk::kFalse;
                }
        }
}
*/

Adesk::Boolean isCurveStartPoint(const AcGePoint2d& pnt, const AcGeCurve2d& curve,const double& tol)
{
        AcGePoint2d stPoint;
        curve.hasStartPoint(stPoint);

        if(pnt.distanceTo(stPoint)<tol) return true;
        return false;
}

Adesk::Boolean isCurveEndPoint(const AcGePoint2d& pnt, const AcGeCurve2d& curve,const double& tol)
{
        AcGePoint2d edPoint;
        curve.hasEndPoint(edPoint);

        if(pnt.distanceTo(edPoint)<tol) return true;
        return false;
}

int pointPosToExLoop(const AcGePoint2d& point,const ChGeLoop2d& loop,const double& tol)
{
        int len=loop.length();
        AcGeNurbCurve2d curve;
        for(int i=0;i<len;i++) {
                curve = AcGeNurbCurve2d(loop[i]);
                if(isCurveStartPoint(point,curve,tol)) return (i+1);
        }
        for(i=0;i<len;i++) {
                curve = AcGeNurbCurve2d(loop[i]);
                if(isOnCurve(point,curve,tol)) return len+(i+1);
                if(isClockwise(point,curve)) return -1;
        }

        return 0;
}

int pointPosToInLoop(const AcGePoint2d& point,const ChGeLoop2d& loop,const double& tol)
{
        int len=loop.length();
        AcGeNurbCurve2d curve;
        for(int i=0;i<len;i++) {
                curve = AcGeNurbCurve2d(loop[i]);
                if(isCurveStartPoint(point,curve,tol)) return (i+1);
        }
        for(i=0;i<len;i++) {
                curve = AcGeNurbCurve2d(loop[i]);
                if(isOnCurve(point,curve,tol)) return len+(i+1);
                if(!isClockwise(point,curve)) return -1;
        }

        return 0;
}


// 当param=param2=0时,表示全部段
bool getPntsFromSpline(const AcGeNurbCurve3d& curve,AcGePoint3dArray& pnts, const int& intNum,const double& param,const double& param2,const bool& bExt)
{
        double tol = AcGeContext::gTol.equalPoint();
        double stP,edP;
        bool bRev = false; // 参数1是否大于参数2,缺省false
        if (fabs(param-param2)<=tol && fabs(param2)<=tol) {
                stP = curve.startParam();
            edP = curve.endParam();
        } else {
                if (fabs(param-param2)<=tol) {
                        return false;
                } else if (param > param2) {
                        bRev = true;
                        stP = param2;
                        edP = param;
                } else {
                        bRev = false;
                        stP = param;
                        edP = param2;
                }
                if (!bExt) {
                        AcGeInterval intrVal;
                        curve.getInterval(intrVal);
                        if (!intrVal.contains(stP)) return false;
                        if (!intrVal.contains(edP)) return false;
                }
        }

        AcGeKnotVector cknots;
        AcGeDoubleArray params;
        int i,j,pos,pos2;
        cknots = curve.knots();
        cknots.getDistinctKnots(params);
        pos = insertKnot(params,stP);
        pos2 = insertKnot(params,edP);

        AcGePoint3dArray dummy;
        int startPos,endPos;
        startPos = pos;
        endPos = pos2;

        double step,tmpVal;
        for (i=startPos; i<endPos; i++) {
                step = (params[i+1]-params[i])/(intNum+1);
                tmpVal = params[i];
                dummy.append(curve.evalPoint(tmpVal));
                for (j=1; j<intNum+1; j++) {
                        tmpVal = tmpVal + step;
                        dummy.append(curve.evalPoint(tmpVal));
                }
        }
        dummy.append(curve.evalPoint(params[endPos]));
        if (bRev) {
                dummy.reverse();
        }
        pnts = dummy;

        return true;
}


// 当param=param2=0时,表示全部段
bool getPntsFromSpline(const AcGeNurbCurve2d& curve,AcGePoint2dArray& pnts, const int& intNum,const double& param,const double& param2,const bool& bExt)
{
        double tol = AcGeContext::gTol.equalPoint();
        double stP,edP;
        bool bRev = false;  // 是否参数1大于参数2,缺省false
        if (fabs(param-param2)<=tol && fabs(param2)<=tol) {
                stP = curve.startParam();
            edP = curve.endParam();
        } else {
                if (fabs(param-param2)<=tol) return false;
                if (param > param2) {
                        bRev = true;
                        stP = param2;
                        edP = param;
                } else {
                        bRev = false;
                        stP = param;
                        edP = param2;
                }
                if (!bExt) {
                        AcGeInterval intrVal;
                        curve.getInterval(intrVal);
                        if (!intrVal.contains(param)) return false;
                        if (!intrVal.contains(param2)) return false;
                }
        }

        AcGeKnotVector cknots;
        AcGeDoubleArray params;
        int i,j,pos,pos2;
        cknots = curve.knots();
        cknots.getDistinctKnots(params);
        pos = insertKnot(params,stP);
        pos2 = insertKnot(params,edP);

        AcGePoint2dArray dummy;
        int startPos,endPos;
        startPos = pos;
        endPos = pos2;

        double step,tmpVal;
        for (i=startPos; i<endPos; i++) {
                step = (params[i+1]-params[i])/(intNum+1);
                tmpVal = params[i];
                dummy.append(curve.evalPoint(tmpVal));
                for (j=1; j<intNum+1; j++) {
                        tmpVal = tmpVal + step;
                        dummy.append(curve.evalPoint(tmpVal));
                }
        }
        dummy.append(curve.evalPoint(params[endPos]));
        if (bRev) {
                dummy.reverse();
        }
        pnts = dummy;

        return true;
}


bool getPntsFromSpline(AcGePoint2dArray& pnts,const AcGeNurbCurve2d& curve,const double& param,const double& param2,const bool& bExt)
{
        double tol = AcGeContext::gTol.equalPoint();
        double stP,edP;
        bool bRev = false;  // 是否参数1大于参数2,缺省false
        if (fabs(param-param2)<=tol && fabs(param2)<=tol) {
                stP = curve.startParam();
            edP = curve.endParam();
        } else {
                if (fabs(param-param2)<=tol) return false;
                if (param > param2) {
                        bRev = true;
                        stP = param2;
                        edP = param;
                } else {
                        bRev = false;
                        stP = param;
                        edP = param2;
                }
                if (!bExt) {
                        AcGeInterval intrVal;
                        curve.getInterval(intrVal);
                        if (!intrVal.contains(param)) return false;
                        if (!intrVal.contains(param2)) return false;
                }
        }

        AcGeKnotVector cknots;
        AcGeDoubleArray params;
        int i,pos,pos2;
        cknots = curve.knots();
        cknots.getDistinctKnots(params);
        pos = insertKnot(params,stP);
        pos2 = insertKnot(params,edP);

        AcGePoint2dArray dummy;
        int startPos,endPos;
        startPos = pos;
        endPos = pos2;

        for (i=startPos; i<endPos+1; i++) {
                dummy.append(curve.evalPoint(params[i]));
        }


        if (bRev) {
                dummy.reverse();
        }
        pnts = dummy;

        return true;
}

bool getPntsFromSpline(AcGePoint3dArray& pnts,const AcGeNurbCurve3d& curve,const double& param,const double& param2,const bool& bExt)
{
        double tol = AcGeContext::gTol.equalPoint();
        double stP,edP;
        bool bRev = false;  // 是否参数1大于参数2,缺省false
        if (fabs(param-param2)<=tol && fabs(param2)<=tol) {
                stP = curve.startParam();
            edP = curve.endParam();
        } else {
                if (fabs(param-param2)<=tol) return false;
                if (param > param2) {
                        bRev = true;
                        stP = param2;
                        edP = param;
                } else {
                        bRev = false;
                        stP = param;
                        edP = param2;
                }
                if (!bExt) {
                        AcGeInterval intrVal;
                        curve.getInterval(intrVal);
                        if (!intrVal.contains(param)) return false;
                        if (!intrVal.contains(param2)) return false;
                }
        }

        AcGeKnotVector cknots;
        AcGeDoubleArray params;
        int i,pos,pos2;
        cknots = curve.knots();
        cknots.getDistinctKnots(params);
        pos = insertKnot(params,stP);
        pos2 = insertKnot(params,edP);

        AcGePoint3dArray dummy;
        int startPos,endPos;
        startPos = pos;
        endPos = pos2;

        for (i=startPos; i<endPos+1; i++) {
                dummy.append(curve.evalPoint(params[i]));
        }

        if (bRev) {
                dummy.reverse();
        }
        pnts = dummy;

        return true;
}


bool isPartOfCurve(const AcGePoint3dArray& crv1,const AcGePoint3dArray& crv2, const double& tol)
{
        if (!crv1.length() || !crv2.length()) return false;

        double dist;
        AcGeNurbCurve3d dummy(crv2);

        int i,num;
        num = crv1.length();

        for (i=0; i<num; i++) {
                dist = dummy.distanceTo(crv1[i]);
                if (dist>tol) return false;
        }

        return true;
}


bool isPartOfCurve(const AcGePoint3dArray& crv1,const AcGeCurve3d& crv2, const double& tol)
{
        double dist;

        int i,num;
        num = crv1.length();
        if (num==0) return false;

        for (i=0; i<num; i++) {
                dist = crv2.distanceTo(crv1[i]);
                if (dist>tol) return false;
        }

        return true;
}

bool isPartOfCurve(const AcGeNurbCurve3d& crv1,const AcGeCurve3d& crv2, const double& tol)
{
        AcGePoint3dArray pnts1;
        getPntsFromSpline(crv1,pnts1);
        double dist;

        int i,num;
        num = pnts1.length();
        if (num==0) return false;

        for (i=0; i<num; i++) {
                dist = crv2.distanceTo(pnts1[i]);
                if (dist>tol) return false;
        }

        return true;
}


bool isPartOfCurve(const AcGePoint2dArray& crv1,const AcGePoint2dArray& crv2, const double& tol)
{
        if (!crv1.length() || !crv2.length()) return false;

        double dist;
        AcGeNurbCurve2d dummy(crv2);

        int i,num;
        num = crv1.length();

        for (i=0; i<num; i++) {
                dist = dummy.distanceTo(crv1[i]);
                if (dist>tol) return false;
        }

        return true;
}


bool isPartOfCurve(const AcGePoint2dArray& crv1,const AcGeCurve2d& crv2, const double& tol)
{
        double dist;

        int i,num;
        num = crv1.length();
        if (num==0) return false;

        for (i=0; i<num; i++) {
                dist = crv2.distanceTo(crv1[i]);
                if (dist>tol) return false;
        }

        return true;
}

bool isPartOfCurve(const AcGeNurbCurve2d& crv1,const AcGeCurve2d& crv2, const double& tol)
{
        AcGePoint2dArray pnts1;
        getPntsFromSpline(crv1,pnts1);
        double dist;

        int i,num;
        num = pnts1.length();
        if (num==0) return false;

        for (i=0; i<num; i++) {
                dist = crv2.distanceTo(pnts1[i]);
                if (dist>tol) return false;
        }

        return true;
}

// 在节点数组中添加节点参数,形成新的节点数组,从小到大的顺序,返回其在新节点数组中的位置
int insertKnot(AcGeDoubleArray& knots,const double& val)
{
        int i,len;
        if (knots.find(val,i)) return i;

        len = knots.length();
        for (i=0; i<len; i++) {
                if (val < knots[i]) {
                        knots.insertAt(i,val);
                        return i;
                }
        }
        knots.insertAt(i,val);
        return i;
}

void getJoinedCurveFromPntsArray(const ChGeCurve2dPntsArray& curves, AcGeNurbCurve2d& curve)
{
        AcGePoint2dArray pnts;
        AcGeNurbCurve2d tmpCrv;

        int i,len;
        len = curves.length();
        if (len) {
                curve = AcGeNurbCurve2d(curves[0]);
        }
        for (i=1; i<len; i++) {
                tmpCrv = AcGeNurbCurve2d(curves[i]);
                curve.joinWith(tmpCrv);
        }
}

void getJoinedCurveFromPntsArray(const ChGeCurve3dPntsArray& curves, AcGeNurbCurve3d& curve)
{
        AcGePoint3dArray pnts;
        AcGeNurbCurve3d tmpCrv;

        int i,len;
        len = curves.length();
        if (len) {
                curve = AcGeNurbCurve3d(curves[0]);
        }
        for (i=1; i<len; i++) {
                tmpCrv = AcGeNurbCurve3d(curves[i]);
                curve.joinWith(tmpCrv);
        }
}

void getPolylineFromPntsArray(const ChGeCurve2dPntsArray& curves, AcGePolyline2d& curve)
{
        AcGePoint2dArray pnts;

        int i,len;
        len = curves.length();
        if (len>0) {
                pnts.append(curves.first());
        }
        for (i=1; i<len; i++) {
                pnts.removeLast();
                pnts.append(curves[i]);
        }

        curve = AcGePolyline2d(pnts);
}


void getPolylineFromPntsArray(const ChGeCurve3dPntsArray& curves, AcGePolyline3d& curve)
{
        AcGePoint3dArray pnts;
       
        int i,len;
        len = curves.length();
        if (len>0) {
                pnts.append(curves.first());
        }
        for (i=1; i<len; i++) {
                pnts.removeLast();
                pnts.append(curves[i]);
        }
       
        curve = AcGePolyline3d(pnts);
}

bool getPntsArrayFromJoinedCurve(const AcGeNurbCurve2d& curve,
                                                                 ChGeCurve2dPntsArray& curves,
                                                                 const int& intNum,
                                                                 const double& param,
                                                                 const double& param2,
                                                                 const bool& bExt)
{
        double tol = AcGeContext::gTol.equalPoint();
        double stP,edP;
        bool bRev = false;  // 是否参数1大于参数2,缺省false
        if (fabs(param-param2)<=tol && fabs(param2)<=tol) {
                stP = curve.startParam();
            edP = curve.endParam();
        } else {
                if (fabs(param-param2)<=tol) return false;
                if (param > param2) {
                        bRev = true;
                        stP = param2;
                        edP = param;
                } else {
                        bRev = false;
                        stP = param;
                        edP = param2;
                }
                if (!bExt) {
                        AcGeInterval intrVal;
                        curve.getInterval(intrVal);
                        if (!intrVal.contains(param)) return false;
                        if (!intrVal.contains(param2)) return false;
                }
        }

        AcGePoint2dArray pnts;
        AcGeDoubleArray params;
        curve.getParamsOfC1Discontinuity(params);
        curves.setLogicalLength(0);
        if (!bExt) {
                insertKnot(params,curve.startParam());
                insertKnot(params,curve.endParam());
        }

        int pos;
        pos = insertKnot(params,stP);
        if (pos>0) {
                params.removeSubArray(0,pos-1);
        }
        pos = insertKnot(params,edP);
        if (pos<params.length()-1) {
                params.removeSubArray(pos+1,params.length()-1);
        }

        int i,len;
        len = params.length();
        for (i=0; i+1<len; i++) {
                pnts.setLogicalLength(0);
                getPntsFromSpline(curve,pnts,intNum,params[i],params[i+1],bExt);
                if (pnts.length()) {
                        if (bRev) pnts.reverse();
                        curves.append(pnts);
                }
        }
        if (bRev) curves.reverse();
        return true;
}


bool getPntsArrayFromJoinedCurve(ChGeCurve2dPntsArray& curves,
                                                                 const AcGeNurbCurve2d& curve,
                                                                 const double& param,
                                                                 const double& param2,
                                                                 const bool& bExt)
{
        double tol = AcGeContext::gTol.equalPoint();
        double stP,edP;
        bool bRev = false;  // 是否参数1大于参数2,缺省false
       
        curves.setLogicalLength(0);
/*
        AcGe::EntityId entId;
        if (curve.isDegenerate(entId)) {
                if (entId == AcGe::kPointEnt2d) {
                        return false;
                }
        }
*/

        if (fabs(param-param2)<=tol && fabs(param2)<=tol) {
                AcGeInterval intrvl;
                curve.getInterval(intrvl);
                stP = intrvl.lowerBound();
                edP = intrvl.upperBound();
//                stP = curve.startParam();
//            edP = curve.endParam();
        } else {
                if (fabs(param-param2)<=tol) return false;
                if (param > param2) {
                        bRev = true;
                        stP = param2;
                        edP = param;
                } else {
                        bRev = false;
                        stP = param;
                        edP = param2;
                }
                if (!bExt) {
                        AcGeInterval intrVal;
                        curve.getInterval(intrVal);
                        if (!intrVal.contains(param)) return false;
                        if (!intrVal.contains(param2)) return false;
                }
        }

        AcGePoint2dArray pnts;
        AcGeDoubleArray params;
        curve.getParamsOfC1Discontinuity(params);
        curves.setLogicalLength(0);
        if (!bExt) {
                insertKnot(params,curve.startParam());
                insertKnot(params,curve.endParam());
        }

        int pos;
        pos = insertKnot(params,stP);
        if (pos>0) {
                params.removeSubArray(0,pos-1);
        }
        pos = insertKnot(params,edP);
        if (pos<params.length()-1) {
                params.removeSubArray(pos+1,params.length()-1);
        }

        int i,len;
        len = params.length();
        for (i=0; i+1<len; i++) {
                pnts.setLogicalLength(0);
                getPntsFromSpline(pnts,curve,params[i],params[i+1],bExt);
                if (pnts.length()) {
                        if (bRev) pnts.reverse();
                        curves.append(pnts);
                }
        }
        if (bRev) curves.reverse();
        return true;
}

bool getPntsArrayFromJoinedCurve(ChGeCurve3dPntsArray& curves,
                                                                 const AcGeNurbCurve3d& curve,
                                                                 const double& param,
                                                                 const double& param2,
                                                                 const bool& bExt)
{
        double tol = AcGeContext::gTol.equalPoint();
        double stP,edP;
        bool bRev = false;  // 是否参数1大于参数2,缺省false

        curves.setLogicalLength(0);
/*
        AcGe::EntityId entId;
        if (curve.isDegenerate(entId)) {
                if (entId == AcGe::kPointEnt3d) {
                        return false;
                }
        }
*/

        if (fabs(param-param2)<=tol && fabs(param2)<=tol) {
                AcGeInterval intrvl;
                curve.getInterval(intrvl);
                stP = intrvl.lowerBound();
                edP = intrvl.upperBound();
//                stP = curve.startParam();
//            edP = curve.endParam();
        } else {
                if (fabs(param-param2)<=tol) return false;
                if (param > param2) {
                        bRev = true;
                        stP = param2;
                        edP = param;
                } else {
                        bRev = false;
                        stP = param;
                        edP = param2;
                }
                if (!bExt) {
                        AcGeInterval intrVal;
                        curve.getInterval(intrVal);
                        if (!intrVal.contains(param)) return false;
                        if (!intrVal.contains(param2)) return false;
                }
        }

        AcGePoint3dArray pnts;
        AcGeDoubleArray params;
        curve.getParamsOfC1Discontinuity(params);
        curves.setLogicalLength(0);
        if (!bExt) {
                insertKnot(params,curve.startParam());
                insertKnot(params,curve.endParam());
        }

        int pos;
        pos = insertKnot(params,stP);
        if (pos>0) {
                params.removeSubArray(0,pos-1);
        }
        pos = insertKnot(params,edP);
        if (pos<params.length()-1) {
                params.removeSubArray(pos+1,params.length()-1);
        }

        int i,len;
        len = params.length();
        for (i=0; i+1<len; i++) {
                pnts.setLogicalLength(0);
                getPntsFromSpline(pnts,curve,params[i],params[i+1],bExt);
                if (pnts.length()) {
                        if (bRev) pnts.reverse();
                        curves.append(pnts);
                }
        }
        if (bRev) curves.reverse();
        return true;
}


// 转换3d点数组为2d点数组
void points3dTo2d(const AcGePoint3dArray& pnts3d,AcGePoint2dArray& pnts2d)
{
        int i,len;
        len = pnts3d.length();
        pnts2d.setLogicalLength(len);

        for (i=0; i<len; i++) {
                pnts2d[i] = AcGePoint2d(pnts3d[i].x,pnts3d[i].y);
        }
}

// 转换2d点数组为3d点数组
void points2dTo3d(const AcGePoint2dArray& pnts2d,AcGePoint3dArray& pnts3d,const double& z)
{
        int i,len;
        len = pnts2d.length();
        pnts3d.setLogicalLength(len);

        for (i=0; i<len; i++) {
                pnts3d[i] = AcGePoint3d(pnts2d[i].x,pnts2d[i].y,z);
        }
}

void curve3dTo2d(const AcGeNurbCurve3d& crv,AcGeNurbCurve2d& crv2d)
{
        int degree;
        Adesk::Boolean rational,periodic;
        AcGeKnotVector knots;
        AcGePoint3dArray controlPoints;
        AcGePoint2dArray controlPoints2d;
        AcGeDoubleArray weights;
       
        crv.getDefinitionData(degree,rational,periodic,knots,controlPoints,weights);
        points3dTo2d(controlPoints,controlPoints2d);
        crv2d = AcGeNurbCurve2d(degree,knots,controlPoints2d,weights,periodic);
}

int joinPntsArrayWithPnts(ChGePnts2dArray& pntsArr, const AcGePoint2dArray& pnts)
{
        int pos = -1;
       
        for (int j=0,LenArr=pntsArr.length(); j<LenArr; j++) {
                if (pnts.first().isEqualTo(pntsArr[j].last())) {
                        pos = j+1;
                        break;
                }
        }
        if (pos != -1) {
                pntsArr.insertAt(pos,pnts);
        }
        return pos;
}

int joinPntsArrayWithPntsArray(ChGePnts2dArray& pntsArr, const ChGePnts2dArray& pntsArr2)
{
        AcGePoint2d fp,lp;
        int pos = -1;
        fp = pntsArr2.first().first();
        lp = pntsArr2.last().last();
       
        bool bRev=false;
        int j,LenArr;
        LenArr = pntsArr.length();
        for (j=0; j<LenArr; j++) {
                if (fp.isEqualTo(pntsArr[j].last())) {
                        pos = j+1;
                        break;
                }
                if (lp.isEqualTo(pntsArr[j].last())) {
                        bRev = true;
                        pos = j+1;
                        break;
                }
        }
        if (pos != -1) {
                LenArr = pntsArr2.length();
                if (!bRev) {
                        for (j=LenArr-1; j>-1; j--) {
                                pntsArr.insertAt(pos,pntsArr2[j]);
                        }
                } else {
                        for (j=0; j<LenArr; j++) {
                                pntsArr.insertAt(pos,pntsArr2[j]);
                                pntsArr[pos].reverse();
                        }
                }
        }
        return pos;
}


void Loop2dTo3d(const ChGeLoop2d& loop2d, ChGeLoop3d& loop3d, double z)
{
        int i,len;

        len = loop2d.length();
        loop3d.setLogicalLength(len);
        for (i=0; i<len; i++) {
                points2dTo3d(loop2d[i],loop3d[i],z);
        }
}

void Loop3dTo2d(const ChGeLoop3d& loop3d, ChGeLoop2d& loop2d)
{
        int i,len;
       
        len = loop3d.length();
        loop2d.setLogicalLength(len);
        for (i=0; i<len; i++) {
                points3dTo2d(loop3d[i],loop2d[i]);
        }
}

void Loops2dTo3d(const ChGeLoop2dArray& loops2d,
                                 ChGeLoop3dArray& loops3d, double z)
{
        int i,len;
       
        len = loops2d.length();
        loops3d.setLogicalLength(len);
        for (i=0; i<len; i++) {
                Loop2dTo3d(loops2d[i],loops3d[i],z);
        }
}

void Loops3dTo2d(const ChGeLoop3dArray& loops3d,
                                 ChGeLoop2dArray& loops2d)
{
        int i,len;
       
        len = loops3d.length();
        loops2d.setLogicalLength(len);
        for (i=0; i<len; i++) {
                Loop3dTo2d(loops3d[i],loops2d[i]);
        }
}

// 整理Loop, 去掉数组中前后相等的点, 去掉点数为1的数组,
// 如果最终不能形成loop则返回kFalse
Adesk::Boolean regenLoop(ChGeLoop2d& loop)
{
        if (loop.isEmpty()) return Adesk::kFalse;
        if (!loop.first().first().isEqualTo(loop.last().last())) return false;

        int i,len,j,jlen;
        len = loop.length();
        for (i=0; i<len; i++) {
                jlen = loop[i].length();
                for (j=jlen-1; j>0; j--) {
                        if (loop[i].at(j).isEqualTo(loop[i].at(j-1))) {
                                loop[i].removeAt(j);
                        }
                }
        }

        for (i=0; i<len-1; i++) {
                if (!loop[i].last().isEqualTo(loop[i+1].first())) {
                        return Adesk::kFalse;
                }
        }

        return Adesk::kTrue;       
}

Acad::ErrorStatus
getLoopsFromRegion(AcDbRegion *pRg, ChGeLoop3dArray& loops)
{
        short marker;
        AcGePoint3d pickpnt;
        AcGeMatrix3d vxform;
        int numIds;
        AcDbFullSubentPath *subentIds;
        AcDbFullSubentPathArray subentIdArr;
        AcBrFace *pBrFace;
        AcBrLoopPointerArray pBrLoops;

        loops.setLogicalLength(0);
        marker = 0;
        do {
                marker++;
                pRg->getSubentPathsAtGsMarker(AcDb::kFaceSubentType,marker,
                        pickpnt,vxform,numIds,subentIds);
                if (numIds==0) break;
                for (register j=0; j<numIds; j++) {
                        if ( !subentIdArr.contains(subentIds[j]) ) {
                                subentIdArr.append(subentIds[j]);
                        }
                }
                delete [] subentIds;
        } while(true);

        numIds = subentIdArr.length();
        if (numIds==0) return Acad::eWrongObjectType;

        int i;
        ChGeLoop3dArray retLoops;
        for (i=0; i<numIds; i++) {
                pBrFace = new AcBrFace;
                pBrFace->setSubentPath(subentIdArr[i]);
                getBrLoopsFromBrFace(pBrFace,pBrLoops);
                getGeLoopsFromBrLoops(pBrLoops,retLoops);
                loops.append(retLoops);
                int j,jlen;
                jlen = pBrLoops.length();
                for (j=0; j<jlen; j++) {
                        delete (AcBrLoop*)(pBrLoops[j]);
                }
                pBrLoops.setLogicalLength(0);
                retLoops.setLogicalLength(0);
                delete pBrFace;
        }

        int len;
        len = loops.length();
        for (i=0; i<len; i++) {
                int j,jlen,klen;
                jlen = loops[i].length();
                for (j=jlen-1; j>-1; j--) {
                        klen = loops[i].at(j).length();
                        if (klen<2) loops[i].removeAt(j);
                }
        }


        return Acad::eOk;
}


Acad::ErrorStatus
booleanOper(const ChGeLoop2d& loop1, const ChGeLoop2d& loop2,
                        ChGeLoop2dArray& retLoops,AcDb::BoolOperType op)
{
        AcDbRegion *pRg1,*pRg2;
        Acad::ErrorStatus es;

        es = createRegion(loop1,pRg1);
        if (es != Acad::eOk) return es;

        es = createRegion(loop2,pRg2);
        if (es != Acad::eOk) {
                delete pRg1;
                return es;
        }

        AcGePoint3dArray pnts3d;
        pRg1->intersectWith(pRg2,AcDb::kOnBothOperands,pnts3d,0,0);

        es = pRg1->booleanOper(op,pRg2);
        if (es != Acad::eOk) return es;

        acdbHostApplicationServices()->workingDatabase()->
                addAcDbObject(pRg1);

        ChGeLoop3dArray loops;
        es = getLoopsFromRegion(pRg1,loops);
        pRg1->erase ();
        pRg1->close();

        if (es != Acad::eOk) return es;
        Loops3dTo2d(loops,retLoops);

        if (retLoops.length() == 1) {
                if (   (retLoops[0].length()==loop1.length())
                        && pnts3d.length()==0 ) {
                        return Acad::eNotHandled;
                        }
        }


        return Acad::eOk;
}


Acad::ErrorStatus
trimLoopByCurve(const ChGeLoop2d& loop,const ChGePnts2dArray& curve,
                                ChGeLoop2d& retLoop, Adesk::Boolean bTrimRight, Adesk::Boolean bAntiClock)
{
        retLoop.setLogicalLength(0);
        Acad::ErrorStatus es;

        ChGePnts2dArray retCurve;
        es = trimCurveByLoop(curve,loop,retCurve);
        if (es != Acad::eOk) {
                return es;
        }

        AcGeNurbCurve2d loopCrv;
        getJoinedCurveFromPntsArray(loop,loopCrv);

        double param1,param2;
        loopCrv.isOn(retCurve.first().first(),param1);
        loopCrv.isOn(retCurve.last().last(),param2);
        retCurve.first().first() = loopCrv.evalPoint(param1);
        retCurve.last().last() = loopCrv.evalPoint(param2);

        ChGePnts2dArray retPntsArray;
        if (bAntiClock) {
                if (bTrimRight) {
                        if (param1<param2) {
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,loopCrv.startParam(),param1);
                                retLoop.append(retPntsArray);
                                retLoop.append(retCurve);
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,param2,loopCrv.endParam());
                                retLoop.append(retPntsArray);
                        } else {
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,param2,param1);
                                retLoop.append(retPntsArray);
                                retLoop.append(retCurve);
                        }
                } else {
                        if (param1<param2) {
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,param1,param2);
                                retLoop.append(retPntsArray);
                                reverse(retCurve);
                                retLoop.append(retCurve);
                        } else {
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,loopCrv.startParam(),param2);
                                retLoop.append(retPntsArray);
                                reverse(retCurve);
                                retLoop.append(retCurve);
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,param1,loopCrv.endParam());
                                retLoop.append(retPntsArray);
                        }
                }
        } else {
                if (bTrimRight) {
                        if (param1<param2) {
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,param1,param2);
                                retLoop.append(retPntsArray);
                                reverse(retCurve);
                                retLoop.append(retCurve);
                        } else {
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,loopCrv.startParam(),param2);
                                retLoop.append(retPntsArray);
                                reverse(retCurve);
                                retLoop.append(retCurve);
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,param1,loopCrv.endParam());
                                retLoop.append(retPntsArray);
                        }
                } else {
                        if (param1<param2) {
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,loopCrv.startParam(),param1);
                                retLoop.append(retPntsArray);
                                retLoop.append(retCurve);
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,param2,loopCrv.endParam());
                                retLoop.append(retPntsArray);
                        } else {
                                getPntsArrayFromJoinedCurve(retPntsArray,loopCrv,param2,param1);
                                retLoop.append(retPntsArray);
                                retLoop.append(retCurve);
                        }
                }
        }

        return Acad::eOk;
}

Acad::ErrorStatus
trimCurveByLoop(const ChGePnts2dArray& curve,const ChGeLoop2d& loop,
                                ChGePnts2dArray& retCurve)
{
        retCurve.setLogicalLength(0);
        Acad::ErrorStatus es;
       
        AcDbRegion *pRg;
        es = createRegion(loop,pRg);
        if (es != Acad::eOk)
                return es;
       
        AcGeNurbCurve2d crv;
        getJoinedCurveFromPntsArray(curve,crv);
        AcDbSpline *pSpl;
        createSpline(crv,pSpl);
        AcGePoint3dArray pnts3d;
        pRg->intersectWith(pSpl,AcDb::kOnBothOperands,pnts3d,0,0);
        delete pSpl;
       
        int len;
        len = pnts3d.length(); // 交点个数
        if ( len > 2) {
                delete pRg;
                return Acad::eNotHandled;
        }
       
        double param1,param2;
       
       
        acdbHostApplicationServices()->workingDatabase()->
                addAcDbObject(pRg);
       
        AcBrFace *pBrFace;
        getBrFaceFromRegion(pRg,pBrFace);
        AcBr::Relation rel;
       
        AcGePoint2d pnt2d;
       
        if (len==0) {
                double tol;
                AcGeNurbCurve2d loopCrv;
                getJoinedCurveFromPntsArray(loop,loopCrv);
                pnt2d = crv.evalPoint(crv.endParam()/2);
                pBrFace->getPointRelationToFace(AcGePoint3d(pnt2d.x,pnt2d.y,0),rel);
                if (rel == AcBr::kInside) {
                        retCurve = curve;
                } else {
                        tol = loopCrv.distanceTo(pnt2d);
                        if (tol < TOL5) {
                                retCurve = curve;
                        }
                }
                pRg->erase();
                pRg->close();
                delete pBrFace;
                return Acad::eNotHandled;
        }
       
        if (len==1) {
                pnt2d = curve.first().first();
                pBrFace->getPointRelationToFace(AcGePoint3d(pnt2d.x,pnt2d.y,0),rel);
                if (rel == AcBr::kInside) {
                        param1 = crv.startParam();
                        crv.isOn(AcGePoint2d(pnts3d[0].x,pnts3d[0].y),param2);
                } else {
                        crv.isOn(AcGePoint2d(pnts3d[0].x,pnts3d[0].y),param1);
                        param2 = crv.endParam();
                }
                if (param1 == param2) {
                        // 全部被剪切
                        pRg->erase();
                        pRg->close();
                        delete pBrFace;
                        return Acad::eOk;
                }
        } else if (len==2) {
                crv.isOn(AcGePoint2d(pnts3d[0].x,pnts3d[0].y),param1);
                crv.isOn(AcGePoint2d(pnts3d[1].x,pnts3d[1].y),param2);
                pnt2d = crv.evalPoint((param1+param2)/2);
                pBrFace->getPointRelationToFace(AcGePoint3d(pnt2d.x,pnt2d.y,0),rel);
                if (rel != AcBr::kInside) {
                        pRg->erase();
                        pRg->close();
                        delete pBrFace;
                        return Acad::eNotHandled;
                }
                if (param1>param2) {
                        double tmp;
                        tmp = param1;
                        param1 = param2;
                        param2 = tmp;
                }
        }
       
        pRg->erase();
        pRg->close();
        delete pBrFace;
        getPntsArrayFromJoinedCurve(retCurve,crv,param1,param2);

        return Acad::eOk;
}


/*
bool trimLoopByLoops(const ChGeLoop2d& loop, const ChGeLoop2dArray& loops,ChGeLoop2dArray& retLoops,bool bAnticlock,bool bTrimRight)
{
        if (loop.length()==0 || loops.length()==0) return false;

        retLoops.setLogicalLength(0);

        bool ret;
        ChGePnts2dArray retPntsArr;
        ChGeLoop2dArray trimmedLoops,trimmedLoops2,innerLoops,tmpLoops;
        int i,len,j,jlen;
        len = loops.length();
        trimmedLoops.append(loop);
        for (i=0; i<len; i++) {
                jlen = trimmedLoops.length();
                trimmedLoops2.setLogicalLength(0);
                for (j=0; j<jlen; j++)  {
                        ret = trimClosedCurvebyClosedCurve(
                                trimmedLoops[j],loops[i],retPntsArr,bTrimRight,bAnticlock);
                        if (ret) {
                                if (retPntsArr.length()!=0) {
                                        // 部分被剪切
                                        getLoopsFromPntsArr(tmpLoops,retPntsArr);
                                        trimmedLoops2.append(tmpLoops);
                                }
                        } else {
                                if (retPntsArr.length() == trimmedLoops[j].length()) {
                                        // 未被剪切
                                        AcGeNurbCurve2d crv;
                                        getJoinedCurveFromPntsArray(trimmedLoops[j],crv);
                                        Adesk::Boolean bTmp;
                                        bTmp = isClockwise(loops[i].first().first(),crv);
                                        if (bAnticlock) {
                                                if (!bTmp) {
                                                        innerLoops.append(loops[i]);
                                                }
                                        } else {
                                                if (bTmp) {
                                                        innerLoops.append(loops[i]);
                                                }
                                        }
                                        trimmedLoops2.append(trimmedLoops[j]);
                                } else {
                                        // 输入参数错误
                                        return false;
                                }
                        }
                }
                trimmedLoops = trimmedLoops2;
                if (trimmedLoops.length()==0) {
                        return true;
                }
        }

        retLoops = trimmedLoops;
        if (innerLoops.length()) {
                retLoops.append(innerLoops);
        }

        return true;
}
*/

// 从点数组的数组提取loops
bool getLoopsFromPntsArr(ChGeLoop2dArray& loops2d,const ChGeCurve2dPntsArray& pntsArr)
{
        int i,len;
        len = pntsArr.length();
        loops2d.setLogicalLength(0);
        if (len==0) {
                return false;
        } else if (len==1) {
                if (pntsArr[0].length()>1 && pntsArr[0].first().isEqualTo(pntsArr[0].last())) {
                        loops2d.append(pntsArr);
                        return true;
                } else {
                        return false;
                }
        } else {
                ChGeLoop2d loop;
                loop.append(pntsArr[0]);
                for (i=1; i<len; i++) {
                        while(pntsArr[i-1].last().isEqualTo(pntsArr[i].first())) {
                                loop.append(pntsArr[i]);
                                i++;
                                if (i>=len) break;
                        }
                        if (loop.length())        loops2d.append(loop);
                        loop.setLogicalLength(0);
                        if (i!=len) {
                                loop.append(pntsArr[i]);
                        }
                }
                if (loop.length()) {
                        loops2d.append(loop);
                }
                if (loops2d.length()>1) {
                        if (loops2d.first().first().first().isEqualTo(loops2d.last().last().last())) {
                                loops2d[loops2d.length()].append(loops2d.first());
//                                loops2d.last().append(loops2d.first());
                                loops2d.removeFirst();
                        }
                }
        }

        len = loops2d.length();
        for (i=len-1; i>-1; i--) {
                if (!loops2d[i].first().first().isEqualTo(loops2d[i].last().last())) {
                        loops2d.removeAt(i);
                }
        }

        if (loops2d.length())        return true;
        else                                        return false;
}

bool isEqual(const ChGeLoop2d& loop1,const ChGeLoop2d& loop2)
{
        int i,len;
        len = loop1.length();
        if (loop2.length() != len) return false;
        for (i=0; i<len; i++) {
                if (!isEqual(loop1[i],loop2[i])) return false;
        }
        return true;
}

bool isEqual(const AcGePoint2dArray& pnts1,const AcGePoint2dArray& pnts2)
{
        int i,len;
        len = pnts1.length();
        if (pnts2.length() != len) return false;
        for (i=0; i<len; i++) {
                if (!pnts1[i].isEqualTo(pnts2[i])) return false;
        }
        return true;
}


bool isEqual(const ChGeLoop2dArray& loops1,const ChGeLoop2dArray& loops2)
{
        int i,len;
        len = loops1.length();
        if (loops2.length() != len) return false;
        for (i=0; i<len; i++) {
                if (!isEqual(loops1[i],loops2[i])) return false;
        }
        return true;
}

bool getParamsFromPnts(const AcGeNurbSurface& surf,const AcGePoint3dArray& pnts,AcGePoint2dArray& params)
{
        if (!pnts.length()) return false;

        int i,len;
        len = pnts.length();
        AcGePoint3dArray tmpPnts;
        tmpPnts.append(pnts.first());
        for (i=1; i<len; i++) {
                if (!tmpPnts.last().isEqualTo(pnts[i])) {
                        tmpPnts.append(pnts[i]);
                }
        }

        len = tmpPnts.length();
        params.setLogicalLength(len);
        AcGePoint3d pnt3d;
        for (i=0; i<len; i++) {
                pnt3d = surf.closestPointTo(tmpPnts[i]);
                surf.isOn(pnt3d,params[i]);
//                params[i] = surf.paramOf(pnt3d);
        }

        if (len>2) {
                // 判断曲面的奇异性,是否有边退化为点
                AcGeInterval intrvlX,intrvlY;
                surf.getEnvelope(intrvlX,intrvlY);
                int nSigularity=0;
                AcGePoint3d p1,p2,p3,p4,oSigularity;
                AcGePoint2d param;
                p1 = surf.evalPoint(param.set(intrvlX.lowerBound(),intrvlY.lowerBound()));
                p2 = surf.evalPoint(param.set(intrvlX.upperBound(),intrvlY.lowerBound()));
                p3 = surf.evalPoint(param.set(intrvlX.upperBound(),intrvlY.upperBound()));
                p4 = surf.evalPoint(param.set(intrvlX.lowerBound(),intrvlY.upperBound()));
                if (p1.isEqualTo(p2)) {
                        nSigularity = 1;
                        oSigularity = p1;
                } else if (p2.isEqualTo(p3)) {
                        nSigularity = 2;
                        oSigularity = p2;
                } else if (p3.isEqualTo(p4)) {
                        nSigularity = 3;
                        oSigularity = p3;
                } else if (p4.isEqualTo(p1)) {
                        nSigularity = 4;
                        oSigularity = p4;
                }

                if (nSigularity) {
                        AcGeLine2d l2;
                        AcGeLineSeg2d l1;
                        AcGePoint2d tp1,tp2;
                        switch(nSigularity) {
                        case 1:
                                tp1.set(intrvlX.lowerBound(),intrvlY.lowerBound());
                                tp2.set(intrvlX.upperBound(),intrvlY.lowerBound());
                                l1.set(tp1,tp2);
                                break;
                        case 2:
                                tp1.set(intrvlX.upperBound(),intrvlY.lowerBound());
                                tp2.set(intrvlX.upperBound(),intrvlY.upperBound());
                                l1.set(tp1,tp2);
                                break;
                        case 3:
                                tp1.set(intrvlX.upperBound(),intrvlY.upperBound());
                                tp2.set(intrvlX.lowerBound(),intrvlY.upperBound());
                                l1.set(tp1,tp2);
                                break;
                        case 4:
                                tp1.set(intrvlX.lowerBound(),intrvlY.upperBound());
                                tp2.set(intrvlX.lowerBound(),intrvlY.lowerBound());
                                l1.set(tp1,tp2);
                                break;
                        }

                        // 针对数组的首位进行判断
                        if (tmpPnts.first().isEqualTo(oSigularity)) {
                                l2.set(params.at(1),params.at(2));
                                if (!l1.intersectWith(l2,params.first())) {
                                        double s1;
                                        s1 = (tmpPnts[0]-tmpPnts[1]).length() / (tmpPnts[1]-tmpPnts[2]).length();
                                        params[0] = params[1] + (params[1]-params[2])*s1;
                                        params[0] = l1.closestPointTo(params[0]);
                                }
                        }
                        // 针对数组的第二位进行判断
                        if (tmpPnts.at(1).isEqualTo(oSigularity)) {
                                l2.set(params.at(0),params.at(2));
                                if (!l1.intersectWith(l2,params[1])) {
                                        double s1;
                                        s1 = (tmpPnts[1]-tmpPnts[0]).length() / (tmpPnts[2]-tmpPnts[0]).length();
                                        params[1] = params[0] + (params[2]-params[0])*s1;
                                        params[1] = l1.closestPointTo(params[1]);
                                }
                        }

                        // 针对其他
                        for (i=2; i<len; i++) {
                                if (tmpPnts.at(i).isEqualTo(oSigularity)) {
                                        l2.set(params.at(i-1),params.at(i-2));
                                        if (!l1.intersectWith(l2,params.first())) {
                                                double s1;
                                                s1 = (tmpPnts[i-1]-tmpPnts[i-2]).length() / (tmpPnts[i-1]-tmpPnts[i-2]).length();
                                                params[i] = params[i-1] + (params[i-1]-params[i-2])*s1;
                                                params[i] = l1.closestPointTo(params[i]);
                                        }
                                }
                        }
                }
        }

        return true;
}


bool getPntsFromParams(const AcGeNurbSurface& surf,const AcGePoint2dArray& params,AcGePoint3dArray& pnts)
{
        if (!params.length()) return false;

        int i,len;
        len = params.length();
        pnts.setLogicalLength(len);
        for (i=0; i<len; i++) {
                pnts[i] = surf.evalPoint(params[i]);
        }

        return true;
}

bool getParamsArrayFromPntsArray(const AcGeNurbSurface& surf,const ChGePnts3dArray& pntsArr,ChGePnts2dArray& paramsArr, bool bLoop)
{
        if (!pntsArr.length()) return false;

        int i,len,j,jlen;
        AcGePoint2d param;
        len = pntsArr.length();
        paramsArr.setLogicalLength(len);
        AcGePoint3d pnt3d;
        for (i=0; i<len; i++) {
                jlen = pntsArr[i].length();
/*
                if (jlen == 1) {
                        paramsArr[i].setLogicalLength(1);
                        continue;
                }
*/
                for (j=0; j<jlen; j++) {
                        pnt3d = surf.closestPointTo(pntsArr[i].at(j));
                        surf.isOn(pnt3d,param);
//                        param = surf.paramOf(pnt3d);
                        paramsArr[i].append(param);
                }
        }

        // 判断曲面的奇异性,是否有边退化为点
        AcGeInterval intrvlX,intrvlY;
        surf.getEnvelope(intrvlX,intrvlY);
        int nSigularity=0;
        AcGePoint3d p1,p2,p3,p4,oSigularity;
//        AcGePoint2d param;
        p1 = surf.evalPoint(param.set(intrvlX.lowerBound(),intrvlY.lowerBound()));
        p2 = surf.evalPoint(param.set(intrvlX.upperBound(),intrvlY.lowerBound()));
        p3 = surf.evalPoint(param.set(intrvlX.upperBound(),intrvlY.upperBound()));
        p4 = surf.evalPoint(param.set(intrvlX.lowerBound(),intrvlY.upperBound()));
        if (p1.isEqualTo(p2)) {
                nSigularity = 1;
                oSigularity = p1;
        } else if (p2.isEqualTo(p3)) {
                nSigularity = 2;
                oSigularity = p2;
        } else if (p3.isEqualTo(p4)) {
                nSigularity = 3;
                oSigularity = p3;
        } else if (p4.isEqualTo(p1)) {
                nSigularity = 4;
                oSigularity = p4;
        }
               
        if (nSigularity) {
                AcGeLine2d l2;
                AcGeLineSeg2d l1;
                AcGePoint2d tp1,tp2;
                switch(nSigularity) {
                case 1:
                        tp1.set(intrvlX.lowerBound(),intrvlY.lowerBound());
                        tp2.set(intrvlX.upperBound(),intrvlY.lowerBound());
                        l1.set(tp1,tp2);
                        break;
                case 2:
                        tp1.set(intrvlX.upperBound(),intrvlY.lowerBound());
                        tp2.set(intrvlX.upperBound(),intrvlY.upperBound());
                        l1.set(tp1,tp2);
                        break;
                case 3:
                        tp1.set(intrvlX.upperBound(),intrvlY.upperBound());
                        tp2.set(intrvlX.lowerBound(),intrvlY.upperBound());
                        l1.set(tp1,tp2);
                        break;
                case 4:
                        tp1.set(intrvlX.lowerBound(),intrvlY.upperBound());
                        tp2.set(intrvlX.lowerBound(),intrvlY.lowerBound());
                        l1.set(tp1,tp2);
                        break;
                }

                AcGePoint3dArray tmpPnts;
                AcGePoint2dArray params;
                for (i=0; i<len; i++) {
                        // 针对数组的首位进行判断
                        tmpPnts = pntsArr[i];
                        params = paramsArr[i];
                        if (tmpPnts[0].isEqualTo(oSigularity)) {
                                l2.set(params[1],params[2]);
                                if (!l1.intersectWith(l2,params[0])) {
                                        double s1;
                                        s1 = (tmpPnts[0]-tmpPnts[1]).length() / (tmpPnts[1]-tmpPnts[2]).length();
                                        params[0] = params[1] + (params[1]-params[2])*s1;
                                        params[0] = l1.closestPointTo(params[0]);
                                }
                        }
                        // 针对数组的第二位进行判断
                        if (tmpPnts[1].isEqualTo(oSigularity)) {
                                l2.set(params[0],params[1]);
                                if (!l1.intersectWith(l2,params[1])) {
                                        double s1;
                                        s1 = (tmpPnts[1]-tmpPnts[0]).length() / (tmpPnts[2]-tmpPnts[0]).length();
                                        params[1] = params[0] + (params[2]-params[0])*s1;
                                        params[1] = l1.closestPointTo(params[1]);
                                }
                        }
                       
                        jlen = tmpPnts.length();
                        // 针对其他
                        for (j=2; j<jlen; j++) {
                                if (tmpPnts[j].isEqualTo(oSigularity)) {
                                        l2.set(params[j-1],params[j-2]);
                                        if (!l1.intersectWith(l2,params[j])) {
                                                double s1;
                                                s1 = (tmpPnts[j-1]-tmpPnts[j-2]).length() / (tmpPnts[j-1]-tmpPnts[j-2]).length();
                                                params[j] = params[j-1] + (params[j-1]-params[i-2])*s1;
                                                params[j] = l1.closestPointTo(params[j]);
                                        }
                                }
                        }
                        paramsArr[i] = params;
                }
        }

        if (bLoop) {
                len = paramsArr.length();
                if (len<1) return false;
                AcGePoint2dArray params;
                params.setLogicalLength(2);
                if (!paramsArr.first().first().isEqualTo(paramsArr.last().last())) {
                        if (pntsArr.first().first().isEqualTo(oSigularity)) {
                                params[0] = paramsArr.last().last();
                                params[1] = paramsArr.first().first();
                                paramsArr.append(params);
                        } else {
                                paramsArr.last().append(paramsArr.first().first());
                        }
                }
                for (i=0; i<len-1; i++) {
                        if (!paramsArr[i].last().isEqualTo(paramsArr[i+1].first())) {
                                if (pntsArr[i].last().isEqualTo(oSigularity)) {
                                        params[0] = paramsArr[i].last();
                                        params[1] = paramsArr[i+1].first();
                                        paramsArr.insertAt(i+1,params);
                                        i++;
                                        len++;
                                } else {
                                        paramsArr[i].append(paramsArr[i+1].first());
                                }
                        }
                }
        }

        return true;
}


bool getPntsArrayFromParamsArray(const AcGeNurbSurface& surf,const ChGePnts2dArray& paramsArr,ChGePnts3dArray& pntsArr)
{
        if (!paramsArr.length()) return false;

        int i,len,j,jlen;
        len = paramsArr.length();
        pntsArr.setLogicalLength(len);
        for (i=0; i<len; i++) {
                jlen = paramsArr[i].length();
                pntsArr[i].setLogicalLength(jlen);
                for (j=0; j<jlen; j++) {
                        (pntsArr[i])[j] = surf.evalPoint(paramsArr[i].at(j));
                }
        }

        return true;
}

bool getLoopFromIntervalXY(const AcGeInterval& intrvX, const AcGeInterval& intrvY,ChGeLoop2d& loop, int nX, int nY)
{
        if (!intrvX.isBounded() || !intrvY.isBounded()) return false;
        if (nX<1 || nY<1) return false;
       
        AcGePoint2dArray pnts2d;
        AcGePoint2d        tmpPnt;
        double minX,maxX,minY,maxY,stepX,stepY;
        int i;
        minX = intrvX.lowerBound();
        maxX = intrvX.upperBound();
        minY = intrvY.lowerBound();
        maxY = intrvY.upperBound();
        stepX = intrvX.length()/nX;
        stepY = intrvY.length()/nY;

        loop.setLogicalLength(0);
       
        pnts2d.setLogicalLength(nX+1);
        tmpPnt.y = minY;
        for (i=0; i<nX+1; i++) {
                tmpPnt.x = minX+i*stepX;
                pnts2d[i] = tmpPnt;
        }
        loop.append(pnts2d);
        pnts2d.setLogicalLength(nY+1);
        tmpPnt.x = maxX;
        for (i=0; i<nY+1; i++) {
                tmpPnt.y = minY+i*stepY;
                pnts2d[i] = tmpPnt;
        }
        loop.append(pnts2d);
        pnts2d.setLogicalLength(nX+1);
        tmpPnt.y = maxY;
        for (i=0; i<nX+1; i++) {
                tmpPnt.x = maxX-i*stepX;
                pnts2d[i] = tmpPnt;
        }
        loop.append(pnts2d);
        pnts2d.setLogicalLength(nY+1);
        tmpPnt.x = minX;
        for (i=0; i<nY+1; i++) {
                tmpPnt.y = maxY-i*stepY;
                pnts2d[i] = tmpPnt;
        }
        loop.append(pnts2d);

/*
        pnts2d[0].set(intrvX.lowerBound(),intrvY.upperBound());
        pnts2d[1].set(intrvX.lowerBound(),intrvY.lowerBound());
        loop[0] = pnts2d;
        pnts2d[0].set(intrvX.lowerBound(),intrvY.lowerBound());
        pnts2d[1].set(intrvX.upperBound(),intrvY.lowerBound());
        loop[1] = pnts2d;
        pnts2d[0].set(intrvX.upperBound(),intrvY.lowerBound());
        pnts2d[1].set(intrvX.upperBound(),intrvY.upperBound());
        loop[2] = pnts2d;
        pnts2d[0].set(intrvX.upperBound(),intrvY.upperBound());
        pnts2d[1].set(intrvX.lowerBound(),intrvY.upperBound());
        loop[3] = pnts2d;
*/

        return true;
}


bool isHead(const AcGePoint3dArray& curve, const AcGePoint3d& dirPnt)
{
        AcGeNurbCurve3d crv(curve);
        AcGePoint3d pnt;

        pnt = crv.closestPointTo(dirPnt);
        double p1;
        crv.isOn(pnt,p1);
        if (p1 < crv.endParam()/2 ) {
                return true;
        } else {
                return false;
        }

}

bool evalShapeCenterAndArea(const ChGeLoop2d& loop, AcGePoint2d& center, double& area)
{
        if (loop.length()==0) return false;

        double dA,Sx=0,Sy=0,A=0;
        AcGePoint2d p1,p2;

        int i,len,jlen;

        len = loop.length();
        for (i=0; i<len; i++) {
                jlen = loop[i].length();
                for (register j=1; j<jlen; j++) {
                        p2 = loop[i].at(j);
                        p1 = loop[i].at(j-1);

                        dA = (p2.x - p1.x) * (p2.y + p1.y) / 2;
                        A += dA;
                        Sy += dA * (p2.x + p1.x) / 2;
                        Sx += dA * (p2.y + p1.y) / 4;
                }
        }
        if (fabs(A) < TOL5) return false;

        center.set(Sy/A,Sx/A);
        area = fabs(A);

        return true;
}

bool evalShapeCenterAndArea(const AcGePoint2dArray& vertexs, AcGePoint2d& center, double& area)
{
        if (vertexs.length()==0) return false;

        double dA,Sx=0,Sy=0,A=0;

        int i,len;

        len = vertexs.length();
        for (i=1; i<len; i++) {
                dA = (vertexs[i].x - vertexs[i-1].x)
                        * (vertexs[i].y + vertexs[i-1].y) / 2;
                A += dA;
                Sy += dA * (vertexs[i].x + vertexs[i-1].x) / 2;
                Sx += dA * (vertexs[i].y + vertexs[i-1].y) / 4;
        }
        dA = (vertexs.first().x - vertexs.last().x)
                * (vertexs.first().y + vertexs.last().y) / 2;
        A += dA;
        Sy += dA * (vertexs.first().x + vertexs.last().x) / 2;
        Sx += dA * (vertexs.first().y + vertexs.last().y) / 4;

        if (fabs(A) < TOL5) return false;

        center.set(Sy/A,Sx/A);
        area = fabs(A);

        return true;
}

// 图形是否以某条线为轴对称
bool isAxialSymmetric(const AcGePoint2dArray& vertexs, const AcGeLine2d& line)
{
        if (vertexs.length()<2) return false;

        AcGePoint2d symPnt;
        int i,len;
        AcGePoint2dArray vertexsCopy;

        len = vertexs.length();
        for (i=0; i<len; i++) {
                vertexsCopy = vertexs;
                symPnt = vertexs[i];
                symPnt.mirror(line);
                vertexsCopy.removeAt(i);
                if (!vertexs.contains(symPnt)) {
                        return false;
                }
        }

        return true;
}


Acad::ErrorStatus
getBaseSurface(AcDbEntity* pSurf,
                           AcGeNurbSurface& baseSurf,
                           Adesk::Boolean* pbIsSame)
{
       
        // 得到曲面的BrFace
        AcBr::ErrorStatus brEs;
        AcBrFace *pFace;
        brEs = getBrEntityFromEnt(pSurf,
                AcDb::kFaceSubentType,(AcBrEntity*&)pFace);
       
        if (brEs != AcBr::eOk)
                return Acad::eInvalidInput;
       
        // 得到曲面的ExternalBoundedSurface
        Adesk::UInt32 num;
        AcGeExternalBoundedSurface exsurf,**ppNurbs=NULL;
        if (pbIsSame) {
                Adesk::Boolean bIsSame;
                pFace->getOrientToSurface(bIsSame);
                *pbIsSame = bIsSame;
        }
       
        pFace->getSurfaceAsTrimmedNurbs(num,ppNurbs);
        if (num>1) {
                delete [] ppNurbs;
                return Acad::eWrongObjectType;
        } else if (num==0) {
                return Acad::eWrongObjectType;               
        }
        delete pFace;
        exsurf = *ppNurbs[0];
        delete [] ppNurbs;
       
        // 得到曲面的BaseSurface
        AcGeNurbSurface *pBaseSurf=NULL;
        exsurf.getBaseSurface((AcGeSurface*&)pBaseSurf);
        baseSurf = *pBaseSurf;
        delete pBaseSurf;
       
        return Acad::eOk;
}



Acad::ErrorStatus
getBaseSurfaceAndLoops(AcDbEntity* pSurf,
                                           AcGeNurbSurface& baseSurf,
                                           ChGeLoop3dArray& loops,
                                           Adesk::Boolean* pbIsSame)
{
       
        // 得到曲面的BrFace
        AcBr::ErrorStatus brEs;
        AcBrFace *pFace;
        brEs = getBrEntityFromEnt(pSurf,
                AcDb::kFaceSubentType,(AcBrEntity*&)pFace);

        if (brEs != AcBr::eOk)
                return Acad::eInvalidInput;

        // 得到原曲面的loops
        AcBrLoopPointerArray Loops;
        getBrLoopsFromBrFace(pFace,Loops);
        loops.setLogicalLength(0);
        getGeLoopsFromBrLoops(Loops,loops);
        int i,len;
        len = Loops.length();
        for (i=0; i<len; i++) {
                delete (AcBrLoop*)(Loops[i]);
        }


        // 得到曲面的ExternalBoundedSurface
        Adesk::UInt32 num;
        AcGeExternalBoundedSurface exsurf,**ppNurbs=NULL;
        if (pbIsSame) {
                Adesk::Boolean bIsSame;
                pFace->getOrientToSurface(bIsSame);
                *pbIsSame = bIsSame;
        }

        pFace->getSurfaceAsTrimmedNurbs(num,ppNurbs);
        if (num>1) {
                delete [] ppNurbs;
                return Acad::eWrongObjectType;
        } else if (num==0) {
                return Acad::eWrongObjectType;               
        }
        delete pFace;
        exsurf = *ppNurbs[0];
        delete [] ppNurbs;
       
        // 得到曲面的BaseSurface
        AcGeNurbSurface *pBaseSurf=NULL;
        exsurf.getBaseSurface((AcGeSurface*&)pBaseSurf);
        baseSurf = *pBaseSurf;
        delete pBaseSurf;
       
        return Acad::eOk;
}


/*
bool getLoopFromVertexs(const AcGePoint2dArray& vertexs, const AcGePoint2d& ptInLoop, ChGeLoop2d& loop)
{
        int i,len;
        len = vertexs.length();
        if (len<3) return false;

        AcGePoint2d pt;
        pt.set(ptInLoop.x,-1.7e308);
        AcGeRay2d ptRay(ptInLoop,pt);

        AcGePoint2d intPt,maxYPt,tmpPt;         // 交点, Y值最大的交点
        int maxYPtIndex;                         // 交点所在直线的索引号
        AcGeLineSeg2d *pLineSeg;       
        AcGeVoidPointerArray pLines; // 所有的直线段

        pLines.setLogicalLength(len-1);
        for (i=1; i<len; i++) {
                pLineSeg = new AcGeLineSeg2d(vertexs[i-1],vertexs[i]);
                pLines[i-1] = pLineSeg;
        }

        // 得到与射线的交点Y值最大的直线索引号和交点
        maxYPtIndex = -1;
        len = pLines.length();
        for (i=0; i<len; i++) {
                pLineSeg = (AcGeLineSeg2d*) pLines[i];
                if (ptRay.intersectWith(*pLineSeg,intPt)) {
                        if (maxYPtIndex == -1) {
                                maxYPtIndex = i;
                                maxYPt = intPt;
                        } else {
                                if (maxYPt.y < intPt.y) {
                                        maxYPtIndex = i;
                                        maxYPt = intPt;
                                }
                        }
                }
        }
        if (maxYPtIndex == -1) {
                // 不存在这样的点则表示不存在包含ptInLoop的Loop存在
                return false;
        }

        // 将交点所在直线段分为两段(可能的话)
        pLineSeg = (AcGeLineSeg2d*) pLines[maxYPtIndex];
        if (pLineSeg->endPoint().isEqualTo(maxYPt)) {
                maxYPtIndex++;
                if (maxYPtIndex==len) {
                        maxYPtIndex = 0;
                }
        } else if (!pLineSeg->startPoint().isEqualTo(maxYPt)) {
                tmpPt = pLineSeg->startPoint();
                pLineSeg->set(maxYPt,pLineSeg->endPoint());
                pLineSeg = new AcGeLineSeg2d(tmpPt,maxYPt);
                pLines.insertAt(maxYPtIndex,pLineSeg);
                maxYPtIndex++;
        }

        AcGePoint2dArray validVertexs;        // 所有有效顶点
        validVertexs.append(maxYPt);

        // 整理直线数组,以index所在的直线段为头
        AcGeVoidPointerArray realLines;
        len = pLines.length();
        for (i=maxYPtIndex; i<len; i++) {
                realLines.append(pLines[i]);
        }
        for (i=0; i<maxYPtIndex; i++) {
                realLines.append(pLines[i]);
        }

        AcGePoint2dArray intPts;                // 所有与当前直线的交点
        AcGeIntArray         intIndexs;                // 所有交点所在的直线索引号
        AcGeLineSeg2d *pTmpLine, *pOverLap;
        Adesk::Boolean         bRet;
        int j;
        len = pLines.length();
        pLineSeg = (AcGeLineSeg2d*) realLines[0];
        for (i=2; i<len; i++) {
                pTmpLine = (AcGeLineSeg2d*) realLines[i];
                if (pLineSeg->overlap(pTmpLine,(AcGeLinearEnt2d*&)pOverLap)) {
                        // 判断重合
                        if (pOverLap->direction().isCodirectionalTo(pTmpLine->direction())) {
                                intPts.append(pOverLap->endPoint());
                                intIndexs.append(i);
                        } else {
                                intPts.append(pOverLap->startPoint());
                        }
                        intIndexs.append(i);
                        delete pOverLap;
                } else {
                        // 判断相交
                        bRet = pLineSeg->intersectWith(pTmpLine,intPt);
                        if (!bRet) continue;

                        if (intPt.isEqualTo(pTmpLine->endPoint())) {
                                if (i==len-1) {
                                        intIndexs.append(0);
                                } else {
                                        intIndexs.append(i+1);
                                }
                        } else {
                                intIndexs.append(i);
                        }
                        intPts.append(intPt);
                }
        }

        len = intPts.length();
        if (len==0) continue;
        double param,minParam;
        int minIndex;
        minParam = pLineSeg->paramOf(intPts[0]);
        minIndex = 0;
        for (i=1; i<len; i++) {
                param = pLineSeg->paramOf(intPts[i]);
                if (param<minParam) {
                        minParam = param;
                        minIndex = i;
                }
        }
        intIndexs.removeAt(minIndex);
        intPt = intPts[minIndex];


        return true;
}*/


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-7-12 08:23:02 | 显示全部楼层
#ifndef GE_UTILITIES_H
#define GE_UTILITIES_H

//////////////////////////////////////////////////////////////////////////
//
// 与图形和几何实体等相关的函数
//
// Note:
//               
//////////////////////////////////////////////////////////////////////////


#include "TypeDef.h"

#ifdef _DBXEXP_
#define DLLIMPEXP __declspec(dllexport)
#else
#define DLLIMPEXP
#endif

/*
*        Purpose:
*                get points from spline entity.
*        Argument:
*                spl                [in], spline entity pointer.
*                pnts        [out], return points.
*/
extern DLLIMPEXP void
getPntsFromSpline(AcDbSpline *spl,AcGePoint3dArray& pnts);


/*
*        Purpose:
*                get points from spline entity.
*        Argument:
*                spl                [in], spline entity pointer.
*                pointnum[in], the needed point num.
*                pnts        [out], return points.
*/
extern DLLIMPEXP void
getPntsFromSpline(AcDbSpline *spl,AcGePoint3dArray& pnts,int pointnum);



/*
*        Purpose:
*                获取曲线的特征点
*        Argument:
*                pCurve                [in], curve pointer.
*                pnts                [out], return points.
*                numPoint        [in], 需要获取的特征点数,
*                                        为0时取曲线所有节点处值.
*        Return:
*                true 成功得到曲线上的特征点,
*                false输入参数错误或不支持的曲线类型.
*/
extern DLLIMPEXP bool
getPntsFromCurve(AcDbCurve *pCurve,
                                 AcGePoint3dArray& pnts,
                                 int numPoint=0);


/*
*        Purpose:
*                获取曲线的特征点
*        Argument:
*                pCurve                [in], curve pointer.
*                pnts                [out], return points.
*                numPoint        [in], 需要获取的特征点数,
*                                        为0时取曲线所有节点处值.
*        Return:
*                true 成功得到曲线上的特征点,
*                false输入参数错误或不支持的曲线类型.
*/
extern DLLIMPEXP bool
getPntsFromCurve(AcGeCurve3d *pCurve,
                                 AcGePoint3dArray& pnts,
                                 int numPoint=0);

/*
*        Purpose:
*                求数组中最小的数组元素位置索引从0开始,返回索引.
*        Argument:
*                arr                [in], 数组.
*        Return:
*                索引值.
*/
extern DLLIMPEXP int
minArr(const AcGeDoubleArray& arr);


/*
*        Purpose:
*                求数组中最大的数组元素位置索引从0开始,返回索引.
*        Argument:
*                arr                [in], 数组.
*        Return:
*                索引值.
*/
extern DLLIMPEXP int
maxArr(const AcGeDoubleArray& arr);


/*
*        Purpose:
*                返回该浮点数最接近的整数.
*        Argument:
*                x                [in], 浮点数.
*        Return:
*                最接近的整数.
*/
extern DLLIMPEXP int
Round(const double& x);


/*
*        Purpose:
*                由三点得到平面,当返回值Acad::eOk时返回的pln才有意义.
*        Argument:
*                pnts        [in], 三点坐标.
*                pln                [out], 返回平面.
*        Return:
*                Acad::eOk 成功.
*/
extern DLLIMPEXP Acad::ErrorStatus
getPlaneFrom3Pnts(const AcGePoint3dArray& pnts,AcGePlane& pln);


/*
*        Purpose:
*                由三点得到平面,当返回值Acad::eOk时返回的pln才有意义.
*        Argument:
*                p1                [in], 三点坐标.
*                p2                [in], 三点坐标.
*                p3                [in], 三点坐标.
*                pln                [out], 返回平面.
*        Return:
*                Acad::eOk 成功.
*/
extern DLLIMPEXP Acad::ErrorStatus
getPlaneFrom3Pnts(const AcGePoint3d& p1, const AcGePoint3d& p2,
                                  const AcGePoint3d& p3,AcGePlane& pln);


/*
*        Purpose:
*                由平面三点求三角形面积,p1,p2,p3呈逆时针排列.
*        Argument:
*                p1                [in], 三点坐标.
*                p2                [in], 三点坐标.
*                p3                [in], 三点坐标.
*        Return:
*                三角形面积.
*/
extern DLLIMPEXP double
triangleArea(const AcGePoint2d& p1,
                         const AcGePoint2d& p2,
                         const AcGePoint2d& p3);



/*
*        Purpose:
*                由平面三点求三角形面积,p1,p2,p3呈逆时针排列.
*        Argument:
*                p1                [in], 三点坐标.
*                p2                [in], 三点坐标.
*                p3                [in], 三点坐标.
*        Return:
*                三角形面积.
*/
extern DLLIMPEXP double
triangleArea(const AcGePoint3d& p1, const AcGePoint3d& p2, const AcGePoint3d& p3);


/*
*        Purpose:
*                 倒转点数组的数组.
*        Argument:
*                pntsArr                [in][out], 点数组的数组.
*        Return:
*                三角形面积.
*/
extern DLLIMPEXP void
reverse(ChGePnts2dArray& pntsArr);

/*
*        Purpose:
*                 倒转点数组的数组.
*        Argument:
*                pntsArr                [in][out], 点数组的数组.
*        Return:
*                三角形面积.
*/
extern DLLIMPEXP void
reverse(ChGePnts3dArray& pntsArr);

/*
*        Purpose:
*                判断矢量从vec1到vec2是否顺时针.
*        Argument:
*                vec1        [in], 矢量1.
*                vec2        [in], 矢量2.
*        Return:
*                顺时针返回kTrue,否则返回kFalse.
*/
extern DLLIMPEXP Adesk::Boolean
isClockwise(const AcGeVector2d& vec1, const AcGeVector2d& vec2);



/*
*        Purpose:
*                判断点pnt是否在直线line的右手边.
*        Argument:
*                line        [in], 直线.
*                pnt                [in], 点.
*        Return:
*                在右手边返回true,否则返回false.
*/
extern DLLIMPEXP Adesk::Boolean
isClockwise(const AcGeLine2d& line, const AcGePoint2d& pnt);



/*
*        Purpose:
*                判断点pnt是否在直线p1p2的右手边.
*        Argument:
*                p1                [in], 直线第一点.
*                p2                [in], 直线第二点.
*                pnt                [in], 点.
*        Return:
*                在右手边返回true,否则返回false.
*/
extern DLLIMPEXP Adesk::Boolean
isClockwise(const AcGePoint2d& pnt,const AcGePoint2d& p1,const AcGePoint2d& p2);



/*
*        Purpose:
*                判断曲面上点相对曲线的方向.
*        Argument:
*                surf                [in], 曲面.
*                curve                [in], 曲面上曲线点数组.
*                dirPnt                [in], 曲面上点.
*        Return:
*                在右手边返回true,否则返回false.
*/
extern  DLLIMPEXP bool
isClockwise(const AcGeNurbSurface& surf,const AcGePoint3dArray& curve,const AcGePoint3d& dirPnt);



/*
*        Purpose:
*                判断点相对于线段的位置. 2d
*        Argument:
*                p                [in], 需判断的点.
*                p1                [in], 线段的第一点.
*                p2                [in], 线段的第二点.
*        Return:
*                点在线段上,return 0;
*                点与线段第一点重合,return 1;
*                点与线段第二点重合,return 2;
*                点在线段延长线上,return 3;
*                点在线段外,return -1;
*/
extern DLLIMPEXP int
pointPosToLine(const AcGePoint2d& p,const AcGePoint2d& p1,const AcGePoint2d& p2);


/*
*        Purpose:
*                判断点相对于线段的位置. 3d
*        Argument:
*                p                [in], 需判断的点.
*                p1                [in], 线段的第一点.
*                p2                [in], 线段的第二点.
*        Return:
*                点在线段上,return 0;
*                点与线段第一点重合,return 1;
*                点与线段第二点重合,return 2;
*                点在线段延长线上,return 3;
*                点在线段外,return -1;
*/
extern DLLIMPEXP int
pointPosToLine(const AcGePoint3d& p,const AcGePoint3d& p1,const AcGePoint3d& p2);



/*
*        Purpose:
*                判断点pnt相对于三角形pnts的位置.
*        Argument:
*                pnt                [in], 需判断的点.
*                pnts        [in], 三角形三顶点, 点逆时针排列p1p2p3.
*        Return:
*                点与三角形顶点重合,对应p1p2p3分别返回1,2,3;
*                点在三角形边上,对应p1p2,p2p3,p3p1分别返回4,5,6;
*                点三角形内,返回0;
*                点三角形外,返回-1;
*/
extern DLLIMPEXP int
pointPosToTriangle(const AcGePoint2d& pnt,AcGePoint2dArray& pnts);


/*
*        Purpose:
*                由面积等比原则,通过三角形p1p2p3内一点p4,及对应得三角形
*                r1r2r3,得出对应的点r4.
*        Argument:
*                pnts1        [in], 三角形顶点p1p2p3及其内一点p4数组.
*                pnts2        [in][out], 三角形顶点r1r2r3及其内一点r4数组,
*                                其中r4为返回值.
*/
extern DLLIMPEXP bool
mapPointInTriangle(AcGePoint2dArray& pnts1,AcGePoint2dArray& pnts2);

/*
*        Purpose:
*                由面积等比原则,通过三角形p1p2p3内或上一点p4,及对应得三角形
*                r1r2r3,得出对应的点r4.
*        Argument:
*                pnts1        [in], 三角形顶点p1p2p3及其内一点p4数组.
*                pnts2        [in][out], 三角形顶点r1r2r3及其内一点r4数组,
*                                其中r4为返回值.
*                bIfMapOut [in], 当点在三角形外时,是否认为是其内的点来计算
*  Return:
*                成功true, 输入参数不正确或点在三角形外false
*                当bIfMapOut=true时,会得出一个结果,但仍然返回false
*/
extern DLLIMPEXP bool
mapPointTriangle(AcGePoint2dArray& pnts1,AcGePoint2dArray& pnts2, bool bIfMapOut=false);


/*
*        Purpose:
*                由面积等比原则,通过线段p1p2内一点p3及对应的线段r1r2,
*                得出r1r2上对应的点r3.
*        Argument:
*                pnts1        [in], 线段顶点p1p2及其内一点p3数组,
*                                注意p3必须是线段内的点.
*                pnts2        [in][out], 线段顶点r1r2及其内一点r3数组,
*                                其中r3为返回值.
*/
extern DLLIMPEXP void
mapPointInLine(AcGePoint2dArray& pnts1,AcGePoint2dArray& pnts2);


/*
*        Purpose:
*                由面积等比原则,通过线段p1p2内一点p3及对应的线段r1r2,
*                得出r1r2上对应的点r3.
*        Argument:
*                pnts1        [in], 线段顶点p1p2及其内一点p3数组,
*                                注意p3必须是线段内的点.
*                pnts2        [in][out], 线段顶点r1r2及其内一点r3数组,
*                                其中r3为返回值.
*/
extern DLLIMPEXP void
mapPointInLine(AcGePoint3dArray& pnts1,AcGePoint2dArray& pnts2);

/*
*        Purpose:
*                由面积等比原则,通过线段p1p2内一点p3及对应的线段r1r2,
*                得出r1r2上对应的点r3.
*        Argument:
*                pnts1        [in], 线段顶点p1p2及其内一点p3数组,
*                                注意p3必须是线段内的点.
*                pnts2        [in][out], 线段顶点r1r2及其内一点r3数组,
*                                其中r3为返回值.
*/
extern DLLIMPEXP void
mapPointInLine(AcGePoint2dArray& pnts1,AcGePoint3dArray& pnts2);


/*
*        Purpose:
*                由面积等比原则,通过三角形p1p2p3上(顶点或边上)一点p4,
*                及对应得三角形r1r2r3,得出对应的点r4.
*        Argument:
*                pnts        [in], 三角形顶点p1p2p3及需判断点p数组.
*                                三角形顶点逆时针排列.
*                pos                [in], p4在三角形上的位置, 由pointPosToTriangle()得到
*                mpnts        [in][out], 映射三角形顶点mp1mp2mp3及映射点mp数组,
*                                其中mp为返回值.
*        Return:
*                true 点是在三角形上
*/
extern DLLIMPEXP bool
mapPointOnTriangle(AcGePoint2dArray& pnts, int pos, AcGePoint2dArray& mpnts);


/*
*        Purpose:
*                verify if point is on curve.
*        Argument:
*                pnt                [in], point positon.
*                curve        [in], nurbcurve.
*                tol                [in], tolerance.
*        Return:
*                kTrue 点是在曲线上
*/
extern DLLIMPEXP Adesk::Boolean
isOnCurve(const AcGePoint2d& pnt, const AcGeNurbCurve2d& curve,const double& tol=AcGeContext::gTol.equalPoint());

/*
*        Purpose:
*                verify if point is on curve.
*        Argument:
*                pnt                [in], point position.
*                ply            [in], polyline.
*                tol                [in], tolerance.
*        Return:
*                kTrue 点是在多段线上
*/
extern DLLIMPEXP Adesk::Boolean
isOnCurve(const AcGePoint2d& pnt, const AcGePolyline2d& ply,const double& tol=AcGeContext::gTol.equalPoint());

/*
*        Purpose:
*                verify if point is on the right of polyline curve.
*        Argument:
*                pnt                [in], point positon.
*                ply                [in], curve.
*        Return:
*                kTrue if point on the right of curve, otherwise kFalse.
*/
extern DLLIMPEXP Adesk::Boolean
isClockwise(const AcGePoint2d& pnt, const AcGePolyline2d& ply);

/*
*        Purpose:
*                verify if point is on the right of curve.
*        Argument:
*                pnt                [in], point positon.
*                spl                [in], curve.
*        Return:
*                kTrue if point on the right of curve, otherwise kFalse.
*/
extern DLLIMPEXP Adesk::Boolean
isClockwise(const AcGePoint2d& pnt, const AcGeNurbCurve2d& spl);


/*
/ *
*        Purpose:
*                verify if point is on the right of curve.
*        Argument:
*                pnt                [in], point positon.
*                crv                [in], curve.
*        Return:
*                kTrue if point on the right of curve, otherwise kFalse.
* /
extern DLLIMPEXP Adesk::Boolean
isClockwise(const AcGePoint2d& pnt, const AcGeCurve2d& crv);
*/



/*
*        Purpose:
*                verify if point is equal to the start point of curve.
*        Argument:
*                pnt                [in], point positon.
*                curve        [in], curve.
*                tol                [in], tolerance.
*        Return:
*                true if point equal to the start point of curve, otherwise false.
*/
extern DLLIMPEXP Adesk::Boolean
isCurveStartPoint(const AcGePoint2d& pnt, const AcGeCurve2d& curve,const double& tol=1.e-10);



/*
*        Purpose:
*                verify if point is equal to the end point of curve.
*        Argument:
*                pnt                [in], point positon.
*                curve        [in], curve.
*                tol                [in], tolerance.
*        Return:
*                true if point equal to the start point of curve, otherwise false.
*/
extern DLLIMPEXP Adesk::Boolean
isCurveEndPoint(const AcGePoint2d& pnt, const AcGeCurve2d& curve,const double& tol=1.e-10);



/*
*        Purpose:
*                verify the postion of point compare to exterior loop,
*                whose direction is counter clockwise.
*        Argument:
*                pnt                [in], point position.
*                loop        [in], loop, who include 2d curves.
*                tol                [in], tolerance.
*        Return:
*                0         if point in the interior loop
*                (i+1)     if point is equal to the ith curve's start point, i is the index of curve in loop
*                NUM+(i+1) if point is on the ith curve, NUM is the num of curve in loop
*                -1        if point is out of the exterior loop
*/
extern DLLIMPEXP int
pointPosToExLoop(const AcGePoint2d& point,const ChGeLoop2d& loop,const double& tol);


/*
*        Purpose:
*                verify the postion of point compare to interior loop,
*                whose direction is clockwise.
*        Argument:
*                pnt                [in], point position.
*                loop        [in], loop, who include 2d curves.
*                tol                [in], tolerance.
*        Return:
*                0         if point in the interior loop
*                (i+1)     if point is equal to the ith curve's start point, i is the index of curve in loop
*                NUM+(i+1) if point is on the ith curve, NUM is the num of curve in loop
*                -1        if point is out of the interior loop
*/
extern DLLIMPEXP int
pointPosToInLoop(const AcGePoint2d& point,const ChGeLoop2d& loop,const double& tol=1.e-10);



/*
*        Purpose:
*                get the feature point array from nurbcurve.
*                当param=param2=0时,表示全部段.
*                当param<param2时,得到的点数组方向与曲线同,否则相反,
*                注意param==param2但不等于0时返回错误
*        Argument:
*                curve        [in], spline curve.
*                intNum        [in], 两特征点中插值点数 default=0.
*                param        [in], start param        default=0.0f
*                param2        [in], end param          default=0.0f
*                bExt        [in], 是否使用扩展参数,即给出的参数范围
*                                不在原曲线interval中也可以default=false.
*                pnts        [out], the feature points of spline.
*        Return:
*                true success, false failure.
*/
extern DLLIMPEXP bool
getPntsFromSpline(const AcGeNurbCurve3d& curve,AcGePoint3dArray& pnts, const int& intNum=0,const double& param=0.0f,const double& param2=0.0f,const bool& bExt=false);


/*
*        Purpose:
*                get the feature point array from nurbcurve.
*                当param=param2=0时,表示全部段.
*                当param<param2时,得到的点数组方向与曲线同,否则相反,
*                注意param==param2但不等于0时返回错误
*        Argument:
*                curve        [in], spline curve.
*                intNum        [in], 两特征点中插值点数 default=0.
*                param        [in], start param        default=0.0f
*                param2        [in], end param          default=0.0f
*                bExt        [in], 是否使用扩展参数,即给出的参数范围
*                                不在原曲线interval中也可以default=false.
*                pnts        [out], the feature points of spline.
*        Return:
*                true success, false failure.
*/
extern DLLIMPEXP bool
getPntsFromSpline(const AcGeNurbCurve2d& curve,AcGePoint2dArray& pnts, const int& intNum=0,const double& param=0.0f,const double& param2=0.0f,const bool& bExt=false);


/*
*        Purpose:
*                get the feature point array from nurbcurve.
*                当param=param2=0时,表示全部段.
*                当param<param2时,得到的点数组方向与曲线同,否则相反,
*                注意param==param2但不等于0时返回错误
*                插值点是自动计算,当原曲线段上特征点数不小于CURVE_FEATUREPOINT_NUM则不加入插值点
*                否则,当只有两个特征点时插入两个插值点,其他情况分别在头和尾与相邻特征点间插入一个插值点
*        Argument:
*                curve        [in], spline curve.
*                param        [in], start param        default=0.0f
*                param2        [in], end param          default=0.0f
*                bExt        [in], 是否使用扩展参数,即给出的参数范围
*                                不在原曲线interval中也可以default=false.
*                pnts        [out], the feature points of spline.
*        Return:
*                true success, false failure.
*/
extern DLLIMPEXP bool
getPntsFromSpline(AcGePoint2dArray& pnts,const AcGeNurbCurve2d& curve,const double& param=0.0f,const double& param2=0.0f,const bool& bExt=false);



/*
*        Purpose:
*                get the feature point array from nurbcurve.
*                当param=param2=0时,表示全部段.
*                当param<param2时,得到的点数组方向与曲线同,否则相反,
*                注意param==param2但不等于0时返回错误
*                插值点是自动计算,当原曲线段上特征点数不小于CURVE_FEATUREPOINT_NUM则不加入插值点
*                否则,当只有两个特征点时插入两个插值点,其他情况分别在头和尾与相邻特征点间插入一个插值点
*        Argument:
*                curve        [in], spline curve.
*                param        [in], start param        default=0.0f
*                param2        [in], end param          default=0.0f
*                bExt        [in], 是否使用扩展参数,即给出的参数范围
*                                不在原曲线interval中也可以default=false.
*                pnts        [out], the feature points of spline.
*        Return:
*                true success, false failure.
*/
extern DLLIMPEXP bool
getPntsFromSpline(AcGePoint3dArray& pnts,const AcGeNurbCurve3d& curve,const double& param=0.0f,const double& param2=0.0f,const bool& bExt=false);



/*
*        Purpose:
*                verify if crv1 is part of crv2.
*        Argument:
*                crv1        [in], spline curve1's points.
*                crv2        [in], spline curve2's points.
*                gtol        [in], the tolerance
*        Return:
*                true if it is.
*/
extern DLLIMPEXP bool
isPartOfCurve(const AcGePoint2dArray& crv1,const AcGePoint2dArray& crv2, const double& tol=AcGeContext::gTol.equalPoint());


/*
*        Purpose:
*                verify if crv1 is part of crv2.
*        Argument:
*                crv1        [in], spline curve1's points.
*                crv2        [in], spline curve2.
*                gtol        [in], the tolerance
*        Return:
*                true if it is.
*/
extern DLLIMPEXP bool
isPartOfCurve(const AcGePoint2dArray& crv1,const AcGeCurve2d& crv2, const double& tol=AcGeContext::gTol.equalPoint());



/*
*        Purpose:
*                verify if crv1 is part of crv2.
*        Argument:
*                crv1        [in], spline curve1.
*                crv2        [in], spline curve2.
*                gtol        [in], the tolerance
*        Return:
*                true if it is.
*/
extern DLLIMPEXP bool
isPartOfCurve(const AcGeNurbCurve2d& crv1,const AcGeCurve2d& crv2, const double& tol=AcGeContext::gTol.equalPoint());



/*
*        Purpose:
*                verify if crv1 is part of crv2.
*        Argument:
*                crv1        [in], spline curve1's points.
*                crv2        [in], spline curve2's points.
*                gtol        [in], the tolerance
*        Return:
*                true if it is.
*/
extern DLLIMPEXP bool
isPartOfCurve(const AcGePoint3dArray& crv1,const AcGePoint3dArray& crv2, const double& tol=AcGeContext::gTol.equalPoint());



/*
*        Purpose:
*                verify if crv1 is part of crv2.
*        Argument:
*                crv1        [in], spline curve1's points.
*                crv2        [in], spline curve2.
*                gtol        [in], the tolerance
*        Return:
*                true if it is.
*/
extern DLLIMPEXP bool
isPartOfCurve(const AcGePoint3dArray& crv1,const AcGeCurve3d& crv2, const double& tol=AcGeContext::gTol.equalPoint());


/*
*        Purpose:
*                verify if crv1 is part of crv2.
*        Argument:
*                crv1        [in], spline curve1.
*                crv2        [in], spline curve2.
*                gtol        [in], the tolerance
*        Return:
*                true if it is.
*/
extern DLLIMPEXP bool
isPartOfCurve(const AcGeNurbCurve3d& crv1,const AcGeCurve3d& crv2, const double& tol=AcGeContext::gTol.equalPoint());



/*
*        Purpose:
*                在节点数组中添加节点参数,形成新的节点数组,从小到大的顺序,
*                返回其在新节点数组中的位置.
*        Argument:
*                knots        [in][out], knots array.
*                val                [in], knot value.
*        Return:
*                the index of val in new knots array.
*/
extern DLLIMPEXP int
insertKnot(AcGeDoubleArray& knots,const double& val);



/*
*        Purpose:
*                从曲线点数组得到一条joined曲线.
*        Argument:
*                curves        [in], curves end-joined-with-end
*                curve        [out], return curve.
*/
extern DLLIMPEXP void
getJoinedCurveFromPntsArray(const ChGeCurve2dPntsArray& curves, AcGeNurbCurve2d& curve);



/*
*        Purpose:
*                从曲线点数组得到一条joined曲线.
*        Argument:
*                curves        [in], curves end-joined-with-end
*                curve        [out], return curve.
*/
extern DLLIMPEXP void
getJoinedCurveFromPntsArray(const ChGeCurve3dPntsArray& curves, AcGeNurbCurve3d& curve);


/*
*        Purpose:
*                从曲线点数组得到一条Polyline2d曲线.
*        Argument:
*                curves        [in], curves end-joined-with-end
*                curve        [out], return curve.
*/
extern DLLIMPEXP void
getPolylineFromPntsArray(const ChGeCurve2dPntsArray& curves, AcGePolyline2d& curve);


/*
*        Purpose:
*                从曲线点数组得到一条Polyline3d曲线.
*        Argument:
*                curves        [in], curves end-joined-with-end
*                curve        [out], return curve.
*/
extern DLLIMPEXP void
getPolylineFromPntsArray(const ChGeCurve3dPntsArray& curves, AcGePolyline3d& curve);


/*
*        Purpose:
*                从joined曲线得到曲线点数组的数组.
*                当param=param2=0时,表示全部段.
*                当param<param2时,得到的点数组方向与曲线同,否则相反,
*                注意param==param2但不等于0时返回错误
*        Argument:
*                curve        [in], curves end-joined-with-end.
*                intNum        [in], 两特征点中插值点数 default=0.
*                param        [in], start param        default=0.0f.
*                param2        [in], end param          default=0.0f.
*                bExt        [in], 是否使用扩展参数,即给出的参数范围不在原曲线
*                                interval中也可以default=false
*                curves        [out], points array.
*        Return:
*                true if success, false otherwise.
*/
extern DLLIMPEXP bool
getPntsArrayFromJoinedCurve(const AcGeNurbCurve2d& curve, ChGeCurve2dPntsArray& curves, const int& intNum=0,const double& param=0.0f,const double& param2=0.0f,const bool& bExt=false);




/*
*        Purpose:
*                从joined曲线得到曲线点数组的数组.
*                当param=param2=0时,表示全部段.
*                当param<param2时,得到的点数组方向与曲线同,否则相反,
*                注意param==param2但不等于0时返回错误
*                与上区别在于插值点是自动计算,当原曲线段上特征点数不小于
*                CURVE_FEATUREPOINT_NUM则不加入插值点, 否则,当只有两个
*                特征点时插入两个插值点,其他情况分别在头和尾与相邻特征点间
*                插入一个插值点.
*        Argument:
*                curve        [in], curves end-joined-with-end.
*                param        [in], start param        default=0.0f.
*                param2        [in], end param          default=0.0f.
*                bExt        [in], 是否使用扩展参数,即给出的参数范围不在原曲线
*                                interval中也可以default=false
*                curves        [out], points array.
*        Return:
*                true if success, false otherwise.
*/
extern DLLIMPEXP bool
getPntsArrayFromJoinedCurve(ChGeCurve2dPntsArray& curves, const AcGeNurbCurve2d& curve, const double& param=0.0f,const double& param2=0.0f,const bool& bExt=false);


/*
*        Purpose:
*                从joined曲线得到曲线点数组的数组.
*                当param=param2=0时,表示全部段.
*                当param<param2时,得到的点数组方向与曲线同,否则相反,
*                注意param==param2但不等于0时返回错误
*                与上区别在于插值点是自动计算,当原曲线段上特征点数不小于
*                CURVE_FEATUREPOINT_NUM则不加入插值点, 否则,当只有两个
*                特征点时插入两个插值点,其他情况分别在头和尾与相邻特征点间
*                插入一个插值点.
*        Argument:
*                curve        [in], curves end-joined-with-end.
*                param        [in], start param        default=0.0f.
*                param2        [in], end param          default=0.0f.
*                bExt        [in], 是否使用扩展参数,即给出的参数范围不在原曲线
*                                interval中也可以default=false
*                curves        [out], points array.
*        Return:
*                true if success, false otherwise.
*/
extern DLLIMPEXP bool
getPntsArrayFromJoinedCurve(ChGeCurve3dPntsArray& curves, const AcGeNurbCurve3d& curve, const double& param=0.0f,const double& param2=0.0f,const bool& bExt=false);


/*
*        Purpose:
*                转换3d点数组为2d点数组.
*        Argument:
*                pnts3d        [in], 3d points array.
*                pnts2d        [out], 2d points array.
*/
extern DLLIMPEXP void
points3dTo2d(const AcGePoint3dArray& pnts3d,AcGePoint2dArray& pnts2d);


/*
*        Purpose:
*                转换2d点数组为3d点数组.
*        Argument:
*                pnts2d        [in], 2d points array.
*                z                [in], 3d z-axis coordinate default=0.0f.
*                pnts3d        [out], 3d points array.
*/
extern DLLIMPEXP void
points2dTo3d(const AcGePoint2dArray& pnts2d,AcGePoint3dArray& pnts3d,const double& z=0.0f);


/*
*        Purpose:
*                转换Loop2d为Loop3d.
*        Argument:
*                loop2d        [in], loop2d.
*                z                [in], 3d z-axis coordinate default=0.0f.
*                loop3d        [out], loop3d.
*        Return:
*                true if success, false otherwise.
*/
extern DLLIMPEXP void
Loop2dTo3d(const ChGeLoop2d& loop2d, ChGeLoop3d& loop3d, double z=0);

/*
*        Purpose:
*                转换Loop3d为Loop2d.
*        Argument:
*                loop3d        [in], loop3d.
*                loop2d        [out], loop2d.
*/
extern DLLIMPEXP void
Loop3dTo2d(const ChGeLoop3d& loop3d, ChGeLoop2d& loop2d);



/*
*        Purpose:
*                转换Loops2d为Loops3d.
*        Argument:
*                loops2d        [in], loops2d.
*                z                [in], 3d z-axis coordinate default=0.0f.
*                loops3d        [out], loops3d.
*/
extern DLLIMPEXP void
Loops2dTo3d(const ChGeLoop2dArray& loops2d,
                        ChGeLoop3dArray& loops3d, double z=0);


/*
*        Purpose:
*                转换Loops3d为Loops2d.
*        Argument:
*                loops3d        [in], loops3d.
*                loops2d        [out], loops2d.
*/
extern DLLIMPEXP void
Loops3dTo2d(const ChGeLoop3dArray& loops3d, ChGeLoop2dArray& loops2d);



/*
*        Purpose:
*                从region对象获取其Loops,该对象必须存在于数据库中,可以没有owner.
*        Argument:
*                pRg                [in], region对象指针.
*                loops        [out], 返回的loops.
*        Return:
*                Acad::eok, 成功
*                其他,失败, loops长度为0
*/
extern DLLIMPEXP Acad::ErrorStatus
getLoopsFromRegion(AcDbRegion *pRg, ChGeLoop3dArray& loops);




/*
*        Purpose:
*                loop1与loop2布尔操作
*        Argument:
*                loop1                [in], loop1.
*                loop2                [in], loop2.
*                op                        [in], bool operation.
*                retLoops        [out], 返回的loops.
*        Return:
*                Acad::eOk, 成功,  
*                Acad::eInvalideInput,loop1或loop2不是一个封闭图形
*                Acad::eNotHandled, 两个loop轮廓没有交点, 且bool操作对loop1没有影响
*                其他,失败, loops长度为0
*/
extern DLLIMPEXP Acad::ErrorStatus
booleanOper(const ChGeLoop2d& loop1, const ChGeLoop2d& loop2,
                        ChGeLoop2dArray& retLoops,AcDb::BoolOperType op);



/*
*        Purpose:
*                转换3dNurb曲线为2d.
*        Argument:
*                crv                [in], 3d nurb curve.
*                crv2d        [out], 2d nurb curve.
*/
extern DLLIMPEXP void
curve3dTo2d(const AcGeNurbCurve3d& crv,AcGeNurbCurve2d& crv2d);



/*
*        Purpose:
*                将点数组添加到点数组的数组中.
*                当点数组的数组中某一点数组A的最后一点等于该点数组的第一点时
*                插入到点数组的数组元素A的后面,并返回其位置索引,否则返回-1,
*                数组未被插入。
*        Argument:
*                pntsArr                [in], 点数组的数组.
*                pnts                [in], 点数组.
*                pntsArr                [out], 点数组的数组.
*        Return:
*                -1插入失败,否则为插入位置索引.
*/
extern DLLIMPEXP int
joinPntsArrayWithPnts(ChGePnts2dArray& pntsArr, const AcGePoint2dArray& pnts);



/*
*        Purpose:
*                将点数组添加到点数组的数组中.
*                当点数组的数组中某一点数组A的最后一点等于该点数组的第一点时
*                插入到点数组的数组元素A的后面,并返回其位置索引,否则返回-1,
*                数组未被插入。
*        Argument:
*                pntsArr                [in], 点数组的数组.
*                pnts                [in], 点数组.
*                pntsArr                [out], 点数组的数组.
*        Return:
*                -1插入失败,否则为插入位置索引.
*/
extern DLLIMPEXP int
joinPntsArrayWithPntsArray(ChGePnts2dArray& pntsArr, const ChGePnts2dArray& pntsArr2);




/*
*        Purpose:
*                曲线2剪切曲线1,保留曲线1在曲线2某边的部分和曲线2上的某些段,
*                形成与曲线1方向一致的曲线.
*        Argument:
*                curve1                [in], curve1.
*                curve2                [in], curve2.
*                bTrimRight        [in], true时保留左手边,否则保留右手边 default=true
*                retCurvePntsArray        [out], 曲线组的点数组的数组.
*        Return:
*    true两者之间有交点时剪切成功, 或曲线1整个被剪切掉(此时retCurvePntsArray为空)
*    false实际参数错误,或曲线1未被剪切(此时retCurvePntsArray与curve1相同)
*/
//extern DLLIMPEXP bool
//trimCurvebyCurve(const ChGeCurve2dPntsArray& curve1pntsArr,const ChGeCurve2dPntsArray& curve2pntsArr,ChGeCurve2dPntsArray& retCurvePntsArray,bool bTrimRight=true);


/*
*        Purpose:
*                用曲线2剪切曲线1,只保留曲线1上的部分.
*        Argument:
*                curve1pntsArr        [in], curve1.
*                curve2pntsArr        [in], curve2.
*                bTrimRight                [in], true时保留左手边,否则保留右手边
*                retCurvePntsArray        [out], 曲线组的点数组的数组.
*        Return:
*    true两者之间有交点时剪切成功, 或曲线1整个被剪切掉(此时retCurvePntsArray为空)
*    false实际参数错误,或曲线1未被剪切(此时retCurvePntsArray与curve1相同)
*/
//extern DLLIMPEXP bool
//trimCurvebyCurve2(const ChGeCurve2dPntsArray& curve1pntsArr,const ChGeCurve2dPntsArray& curve2pntsArr,ChGeCurve2dPntsArray& retCurvePntsArray,bool bTrimRight=true);


/*
*        Purpose:
*                曲线2剪切Closed曲线1,保留曲线1在曲线2某边的部分和曲线2上的
*                某些段,形成与曲线1方向一致的首尾相连的曲线组Loop.
*                曲线2不是首尾相接
*        Argument:
*                curve1pntsArr        [in], curve1.
*                curve2pntsArr        [in], curve2.
*                bTrimRight                [in], true时保留左手边,否则保留右手边
*                bAnticlock                [in], true曲线1为逆时针方向,false顺时针
*                retCurvePntsArray        [out], 曲线组的点数组的数组.
*        Return:
*    true两者之间有交点时剪切成功, 或曲线1整个被剪切掉(此时retCurvePntsArray为空)
*    false实际参数错误,或曲线1未被剪切(此时retCurvePntsArray与curve1相同)
*/
//extern DLLIMPEXP bool
//trimClosedCurvebyCurve(const ChGeCurve2dPntsArray& curve1pntsArr,const ChGeCurve2dPntsArray& curve2pntsArr,ChGeCurve2dPntsArray& retCurvePntsArray,bool bTrimRight=true,bool bAnticlock=true);



/*
*        Purpose:
*                曲线2剪切Closed曲线1,保留曲线1在曲线2某边的部分和曲线2上的
*                某些段,形成与曲线1方向一致的首尾相连的曲线组Loop.
*                曲线2不是首尾相接
*        Argument:
*                curve1pntsArr        [in], curve1.
*                curve2pntsArr        [in], curve2.
*                bTrimRight                [in], true时保留左手边,否则保留右手边
*                retCurvePntsArray        [out], 曲线组的点数组的数组.
*        Return:
*    true两者之间有交点时剪切成功, 或曲线1整个被剪切掉(此时retCurvePntsArray为空)
*    false实际参数错误,或曲线1未被剪切(此时retCurvePntsArray与curve1相同)
*/
//extern DLLIMPEXP bool
//trimClosedCurvebyCurve3(const ChGeCurve2dPntsArray& curve1pntsArr,const ChGeCurve2dPntsArray& curve2pntsArr,ChGeCurve2dPntsArray& retCurvePntsArray,bool bTrimRight=true);


/*
*        Purpose:
*                用曲线2剪切首尾相接的曲线1,只保留曲线1上的部分.
*        Argument:
*                curve1                [in], curve1.
*                curve2                [in], curve2.
*                bTrimRight        [in], true时保留左手边,否则保留右手边
*                retCurvePntsArray        [out], 曲线组的点数组的数组.
*        Return:
*    true两者之间有交点时剪切成功, 或曲线1整个被剪切掉(此时retCurvePntsArray为空)
*    false实际参数错误,或曲线1未被剪切(此时retCurvePntsArray与curve1相同)
*/
//extern DLLIMPEXP bool
//trimClosedCurvebyCurve2(const ChGeCurve2dPntsArray& curve1pntsArr,const ChGeCurve2dPntsArray& curve2pntsArr,ChGeCurve2dPntsArray& retCurvePntsArray,bool bTrimRight=true);



/*
*        Purpose:
*                用首尾相接的曲线2剪切首尾相接的曲线1,曲线1为逆时针或顺时针.
*                保留曲线1和曲线2上的部分,形成loop或loops.
*        Argument:
*                curve1pntsArr        [in], curve1.
*                curve2pntsArr        [in], curve2.
*                bTrimRight                [in], true时保留左手边,否则保留右手边
*                bAnticlock                [in], true曲线1为逆时针方向,false顺时针
*                retCurvePntsArray        [out], 曲线组的点数组的数组.
*        Return:
*    true两者之间有交点时剪切成功, 或曲线1整个被剪切掉(此时retCurvePntsArray为空)
*    false实际参数错误,或曲线1未被剪切(此时retCurvePntsArray与curve1相同)
*/
//extern DLLIMPEXP bool
//trimClosedCurvebyClosedCurve(const ChGeCurve2dPntsArray& curve1pntsArr,const ChGeCurve2dPntsArray& curve2pntsArr,ChGeCurve2dPntsArray& retCurvePntsArray,bool bTrimRight=true,bool bAnticlock=true);



/*
*        Purpose:
*                多个轮廓剪切轮廓1,其他的多个轮廓没有相交和包含关系.
*                保留轮廓1和其他轮廓上的部分,形成loop或loops
*        Argument:
*                loop                        [in], 轮廓1.
*                loops                        [in], 其他的多个轮廓.
*                bTrimRight                [in], true时保留左手边,否则保留右手边
*                bAnticlock                [in], true轮廓1为逆时针方向,false顺时针
*                retCurvePntsArray        [out], 曲线组的点数组的数组.
*        Return:
*                true轮廓1被完全剪切掉返回空或正常返回
*                false输入参数错误
*/
extern DLLIMPEXP bool
trimLoopByLoops(const ChGeLoop2d& loop, const ChGeLoop2dArray& loops,ChGeLoop2dArray& retLoops,bool bAnticlock=true,bool bTrimRight=true);



/*
*        Purpose:
*                从点数组的数组提取loops.
*                当p1,p2,p3,p4,p1,p5,p6,p7,p8,p5时可以提出两个LOOP.
*        Argument:
*                pntsArr                        [in], 点数组的数组.
*                loops2d                        [out], 返回loops
*        Return:
*                成功返回true,否则false
*/
extern DLLIMPEXP bool
getLoopsFromPntsArr(ChGeLoop2dArray& loops2d,const ChGeCurve2dPntsArray& pntsArr);



/*
*        Purpose:
*                判断两对象所含数据是否相等(ChGeLoop2d)
*        Argument:
*                loop1                        [in], loop1.
*                loop2                        [in], loop2
*        Return:
*                相等true,否则false.
*/
extern DLLIMPEXP bool
isEqual(const ChGeLoop2d& loop1,const ChGeLoop2d& loop2);




/*
*        Purpose:
*                判断两对象所含数据是否相等(AcGePoint2dArray)
*        Argument:
*                pnts1                        [in], points 1.
*                pnts2                        [in], points 2.
*        Return:
*                相等true,否则false.
*/
extern DLLIMPEXP bool
isEqual(const AcGePoint2dArray& pnts1,const AcGePoint2dArray& pnts2);




/*
*        Purpose:
*                判断两对象所含数据是否相等(ChGeLoop2dArray)
*        Argument:
*                loops1                        [in], loops 1.
*                loops2                        [in], loops 2.
*        Return:
*                相等true,否则false.
*/
extern DLLIMPEXP bool
isEqual(const ChGeLoop2dArray& loops1,const ChGeLoop2dArray& loops2);



/*
*        Purpose:
*                将曲面上点数组转换为参数数组.
*        Argument:
*                surf                        [in], 曲面.
*                pnts                        [in], 曲面上点数组.
*                params                        [out], 参数数组.
*        Return:
*                成功true,曲面和点数组空false.
*/
extern DLLIMPEXP bool
getParamsFromPnts(const AcGeNurbSurface& surf,const AcGePoint3dArray& pnts,AcGePoint2dArray& params);



/*
*        Purpose:
*                将曲面上参数数组转换为点数组.
*        Argument:
*                surf                        [in], 曲面.
*                params                        [in], 参数数组.
*                pnts                        [out], 曲面上点数组.
*        Return:
*                成功true,曲面和参数数组空false.
*/
extern DLLIMPEXP bool
getPntsFromParams(const AcGeNurbSurface& surf,const AcGePoint2dArray& params,AcGePoint3dArray& pnts);



/*
*        Purpose:
*                生成由(x1,x2)和(y1,y2)指定区域的外轮廓.
*        Argument:
*                intrvX                        [in], (x1,x2).
*                intrvY                        [in], (y1,y2).
*                loop                        [out], 外轮廓.
*                nX                                [in], 轮廓x方向边分段数.
*                nY                                [in], 轮廓y方向边分段数.
*        Return:
*                成功true,输入参数错误返回false.
*/
extern DLLIMPEXP bool
getLoopFromIntervalXY(const AcGeInterval& intrvX, const AcGeInterval& intrvY,ChGeLoop2d& loop, int nX=1, int nY=1);


/*
*        Purpose:
*                将曲面上点数组的数组转换为参数数组的数组.
*        Argument:
*                surf                        [in], 曲面.
*                pntsArr                        [in], 曲面上点数组的数组.
*                paramsArr                [out], 参数数组的数组.
*                bLoop                        [in[, 输入的参数数组是否构成Loop
*        Return:
*                成功true,曲面或点数组的数组空false.
*/
extern DLLIMPEXP bool
getParamsArrayFromPntsArray(const AcGeNurbSurface& surf,const ChGePnts3dArray& pntsArr,ChGePnts2dArray& paramsArr, bool bLoop=false);



/*
*        Purpose:
*                将曲面上参数数组的数组转换为点数组的数组.
*        Argument:
*                surf                        [in], 曲面.
*                paramsArr                [in], 参数数组的数组.
*                pntsArr                        [out], 曲面上点数组的数组.
*        Return:
*                成功true,曲面或参数数组的数组空false.
*/
extern DLLIMPEXP bool
getPntsArrayFromParamsArray(const AcGeNurbSurface& surf,const ChGePnts2dArray& paramsArr,ChGePnts3dArray& pntsArr);


/*
*        Purpose:
*                判断点是在曲线的靠近开始端还是结尾端.
*        Argument:
*                curve                [in], 曲线.
*                dirPnt                [in], 点.
*        Return:
*                true开始端,false结尾端.
*/
extern DLLIMPEXP bool
isHead(const AcGePoint3dArray& curve, const AcGePoint3d& dirPnt);



/*
*        Purpose:
*                得到轮廓的形心和面积.
*        Argument:
*                loop                [in], 轮廓.
*                center                [out], 形心.
*                area                [out], 面积.
*        Return:
*                true成功,false失败.
*/
extern DLLIMPEXP bool
evalShapeCenterAndArea(const ChGeLoop2d& loop, AcGePoint2d& center, double& area);


/*
*        Purpose:
*                得到轮廓的形心和面积.
*        Argument:
*                vertexs                [in], 轮廓顶点,按逆时针或顺时针排列.
*                center                [out], 形心.
*                area                [out], 面积.
*        Return:
*                true成功,false失败.
*/
extern DLLIMPEXP bool
evalShapeCenterAndArea(const AcGePoint2dArray& vertexs, AcGePoint2d& center, double& area);


/*
*        Purpose:
*                图形是否以某条线为轴对称.
*        Argument:
*                vertexs                [in], 图形顶点.
*                line                [in], 轴线.
*        Return:
*                true对称,false顶点数小于2或者不对称.
*/
extern DLLIMPEXP bool
isAxialSymmetric(const AcGePoint2dArray& vertexs, const AcGeLine2d& line);



/*
*        Purpose:
*                获取曲面基面.
*        Argument:
*                pSurf                [in], 曲面对象指针.
*                baseSurf        [out], 曲面基面.
*                pbIsSame        [out], 曲面方向是否与基面相同,if=NULL不返回.
*        Return:
*                eOk成功.
*/
extern DLLIMPEXP Acad::ErrorStatus
getBaseSurface(AcDbEntity* pSurf,
                           AcGeNurbSurface& baseSurf,
                           Adesk::Boolean* pbIsSame=NULL);


/*
*        Purpose:
*                获取曲面基面和Loops.
*        Argument:
*                pSurf                [in], 曲面对象指针.
*                baseSurf        [out], 曲面基面.
*                loops                [out], 曲面Loops.
*                pbIsSame        [out], 曲面方向是否与基面相同,if=NULL不返回.
*        Return:
*                eOk成功.
*/
extern DLLIMPEXP Acad::ErrorStatus
getBaseSurfaceAndLoops(AcDbEntity* pSurf,
                                           AcGeNurbSurface& baseSurf,
                                           ChGeLoop3dArray& loops,
                                           Adesk::Boolean* pbIsSame=NULL);



/*
*        Purpose:
*                用曲线来剪切Loop. 只适合于曲线与Loop交点数为2或没有交点的情况.
*        Argument:
*                loop                [in], Loop.
*                curve                [in], 曲线点数组.
*                retLoop                [out], 返回得Loop.
*                bTrimRight        [in], 剪切方向,缺省为剪切曲线右手边.
*                bAntiClock        [in], Loop是否逆时针.
*        Return:
*                eOk成功, 部分被剪切.
*                其他, 未被剪切, 或不能处理.
*/
extern DLLIMPEXP Acad::ErrorStatus
trimLoopByCurve(const ChGeLoop2d& loop,
                                const ChGePnts2dArray& curve,
                                ChGeLoop2d& retLoop,
                                Adesk::Boolean bTrimRight=true,
                                Adesk::Boolean bAntiClock=true);



/*
*        Purpose:
*                用Loop来剪切曲线. 只适合于曲线与Loop交点数小于3的情况.
*        Argument:
*                curve                [in], 曲线点数组.
*                loop                [in], Loop.
*                retCurve        [out], 返回的曲线点.
*        Return:
*                eOk成功, 全部或部分被剪切.
*                eNotHandled, 曲线与Loop交点数大于2,
*                        或者为0时retCurve的长度不为0,即未被剪切.
*/
extern DLLIMPEXP Acad::ErrorStatus
trimCurveByLoop(const ChGePnts2dArray& curve,
                                const ChGeLoop2d& loop,
                                ChGePnts2dArray& retCurve);


#endif // GE_UTILITIES_H
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2025-9-10 05:41 , Processed in 0.297997 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表