• objectarx 填充的分割


    主要思路:找到填充边界集合:vecBo,然后把面积最大的边界找出来:bo1,用分割曲线和bo1通过boundary命令构成两个新的最大封闭边界,左边的记为 boLeft(红色部分),右边的记为boRight(绿色部分),在vecBo边界集合分开为:boLeft内部的边界,和boRight内部的边界。这样在分别填充的时候,就能有正确的填充边界集合。

    下面放出代码:
    通过选择填充求得填充边界集合:

    static void GetHatchBo(AcDbHatch *pHatch,vector<AcDbEntity*>&vecBo)
        {
            Acad::ErrorStatus es;
    
            Adesk::Int32 LoopType;
    
            AcGeVoidPointerArray edgeptrAry;
            AcGeIntArray edgeTypesAry;
    
            AcGePoint2dArray vertices;
            AcGeDoubleArray bulges;
    
            //获得填充边界的数目
            int LoopNum = pHatch->numLoops();
    
            for (int i = 0; i < LoopNum; i++)
            {
                //获取边界类型
                LoopType = pHatch->loopTypeAt(i);
                //如果边界是多义线
                if (LoopType & AcDbHatch::kPolyline)
                {
                    //取得边界定义数据(polyline)的顶点数组和凸度数组,它们是一一对应的
                    es = pHatch->getLoopAt(i, LoopType, vertices, bulges);
                    acutPrintf(L"
    多段线");
                    //是不是根据这些顶点数组和凸度数组构造一条AcDb多义线取决于你
                    AcDbPolyline *pl = new AcDbPolyline();
    
                    GetPolyline(vertices, bulges, pl);
    
                    vecBo.push_back(pl);
                }
                else
                {
                    //几乎可以取得除polyline外的所有边界定义数据
                    //第三个参数返回值是无值指针数组
                    //第四个参数返回值是组成边界的每一条边的类型
                    //它们也是一一对应的关系
                    es = pHatch->getLoopAt(i, LoopType, edgeptrAry, edgeTypesAry);
    
                    //遍历,因为每一条边界又可能由多种AcGe曲线构成
                    for (int j = 0; j < edgeTypesAry.length(); j++)
                    {
    
                        if (edgeTypesAry[j] == AcDbHatch::kLine)//直线
                        {
                            AcGeLineSeg2d *LnSeg = (AcGeLineSeg2d *)edgeptrAry[j];
                            acutPrintf(L"
    直线");
                            AcGePoint2d pt1 = LnSeg->startPoint();
                            AcGePoint2d pt2 = LnSeg->endPoint();
    
                            AcDbLine *line = new AcDbLine(AcGePoint3d(pt1.x,pt1.y,0), AcGePoint3d(pt2.x, pt2.y, 0));
    
                            vecBo.push_back(line);
                        }
                        //圆弧
                        else if (edgeTypesAry[j] == AcDbHatch::kCirArc)
                        {
                            AcGeCircArc2d *cirArc = (AcGeCircArc2d *)edgeptrAry[j];
                            acutPrintf(L"
    圆弧");
                            //可以根据数学圆弧构造相应的AcDb圆弧,取决于你(以下同)
                            AcGePoint2d center = cirArc->center();
                            double ra = cirArc->radius();
                            double angle1 = cirArc->startAng();
                            double angle2 = cirArc->endAng();
                            AcDbCircle *cir = new AcDbCircle(AcGePoint3d(center.x, center.y, 0), AcGeVector3d::kZAxis, ra);
    
                            vecBo.push_back(cir);
    
                        }
                        else if (edgeTypesAry[j] == AcDbHatch::kEllArc)//椭圆弧
                        {
                            AcGeEllipArc2d *ellArc = (AcGeEllipArc2d *)edgeptrAry[j];
                            acutPrintf(L"
    椭圆弧");
    
                            AcGePoint2d center = ellArc->center();
                            AcGeVector2d majorVec = ellArc->majorAxis();
                            double angle1 = ellArc->startAng();
                            double angle2 = ellArc->endAng();
                            double rad = ellArc->majorRadius();
                            double rad2 = ellArc->minorRadius();
                            
    
                            AcDbEllipse *ell = new AcDbEllipse(AcGePoint3d(center.x, center.y, 0), 
                                AcGeVector3d::kZAxis, AcGeVector3d(majorVec.x,majorVec.y,0), rad / rad2, angle1, angle2);
                            vecBo.push_back(ell);
                        }
                        else if (edgeTypesAry[j] == AcDbHatch::kSpline)//NURBS曲线
                        {
                            AcGeNurbCurve2d *spline = (AcGeNurbCurve2d *)edgeptrAry[j];
                            acutPrintf(L"
    NURBS曲线");
    
                            AcDbSpline * spl = NULL;
    
                            createSpline(*spline, spl, 0);
    
                            vecBo.push_back(spl);
    
                        }
                    }
                }
            
                vertices.removeAll();
                bulges.removeAll();
                edgeptrAry.removeAll();
                edgeTypesAry.removeAll();
            }
        }
    获得填充边界集合

     分割曲线构造新多段线:

    if (pEnt2->isA() == AcDbPolyline::desc()) {
    
                AcDbPolyline * plTemp = AcDbPolyline::cast(pEnt2);
    
                AcGeDoubleArray dbArr;
                AcGePoint2dArray pt2dArr;
    
                int indexS = 0, indexE = 0;
    
                GetCollOfPl(plTemp, dbArr, pt2dArr);
                //获得两个交点的索引用来构造新的多段线
                GetIndexOfPl(plTemp, pt2dArr, ptArr, indexS, indexE);
    
                AcDbPolyline *newPl = new AcDbPolyline();
    
                newPl->addVertexAt(newPl->numVerts(), AcGePoint2d(ptArr[0].x, ptArr[0].y), 0, 0, 0);
    
                for (int i=indexS;i<=indexE;i++)
                {
                    newPl->addVertexAt(newPl->numVerts(), pt2dArr[i], dbArr[i], 0, 0);
    
                }
                newPl->addVertexAt(newPl->numVerts(), AcGePoint2d(ptArr[1].x, ptArr[1].y), 0, 0, 0);
    
                newPl->setColorIndex(4);
    
                PostToModelSpace(newPl);
    
                newPl->close();
    
            }
    截取分隔曲线

     构造左右边界:红色部分最大边界和绿色部分最大边界

    static bool  GetBoundary(const AcGePoint3d & seedPoint, AcDbVoidPtrArray& ptrArr)
        {
    
            ErrorStatus es = acedTraceBoundary(seedPoint, false, ptrArr);
    
            if (es != Acad::eOk) {
                acutPrintf(L"
    boundary=%d", es);
                return false;
            }
            return true;
        }
    View Code

    判断vecBo边界集合的边界是否在左右边界内部:
    主要是获得内部图形的点集,然后把左边边界内部的一点分别与这个点集中的点构成直线,如果直线和左边边界相交时有1个以上交点,就说明这个边界不在左边界内部。

    static bool JudgeXj(CONST AcGePoint3dArray & ptArr, AcDbEntity *pEnt,const AcGePoint3d &innerPt) {
    
            AcDbLine * l = new AcDbLine();
    
            l->setStartPoint(innerPt);
    
            AcGePoint3dArray ptTemp;
    
            for (int i = 0; i < ptArr.length(); i++)
            {
                l->setEndPoint(ptArr[i]);
    
                l->intersectWith(pEnt, AcDb::kOnBothOperands, ptTemp);
    
                if (ptTemp.length() >= 1) {
                    
                    delete l;
                    l = NULL;
    
                    return true;
                }        
            }
            return false;
        }
    判断边界是否在左边边界内部

    完整代码见附件:

  • 相关阅读:
    Java开发桌面程序学习(12)——Javafx 悬浮窗提示 tooptip
    Java开发桌面程序学习(11)——javafx 鼠标点击,右击,双击
    Web前端—— JQuery迷你版实现以及使用
    Web前端——表单提交和Js添加选项
    Web前端——JavaScript练习
    Web前端——JavaScript笔记
    <亲测>CentOS7中使用yum安装Nginx的方法
    Linux 软件安装到 /usr,/usr/local/ 还是 /opt 目录?
    <亲测>centos安装 .net core 2.1
    <亲测>CentOS7 安装mysql8.0(YUM方式)
  • 原文地址:https://www.cnblogs.com/HelloQLQ/p/12435092.html
Copyright © 2020-2023  润新知