Тема: Recreate boundery - создание контура для AcDbHatch

Подскажите, пожалуйста, неопытному программисту, как найти внешний контур вокруг штриховки. Методы GetLoopAt в двух представлениях не помогают – не все штриховки имеют контур. Каким другим способом я программно могу реализовать опцию Recreate boundary с опций штриховки? :(

Re: Recreate boundery - создание контура для AcDbHatch

когда-то Александр Ривилис мне в этом помог, чтоб не гонять тебя по форуму выкладываю функцию

void HatchBoundary(AcDbObjectId objId, std::vector<AcGePoint3dArray> &ptArrVect)
{
    const double epx = 1e-3;
    AcGePoint3dArray ptArray; 
    AcGeIntArray n1, n2; 

    AcDbObjectPointer<AcDbHatch> pHatch(objId,AcDb::kForRead);
    if (pHatch.openStatus () != Acad::eOk) return;

    int nLoop = pHatch->numLoops();
    long loopType;
    for (int i=0; i < nLoop; i++) 
    {
        ptArray.setLogicalLength(0);n1.setLogicalLength(0);n2.setLogicalLength(0);
        if (pHatch->loopTypeAt( i ) & AcDbHatch::kPolyline) 
        {
            AcGePoint2dArray  vertices;
            AcGeDoubleArray   bulges;
            if (pHatch->getLoopAt(i,loopType,vertices,bulges) != Acad::eOk) return;

            AcDbPolyline *pPoly = new AcDbPolyline(vertices.length());
            pPoly->setDatabaseDefaults (pHatch->dat abase());
            for (int j=0; j < vertices.length(); j++) 
                pPoly->addVertexAt (j,vertices[j],(bulges.length()<vertices.length()) ? 0.0:bulges[j]);
            pPoly->setClosed (!(loopType & AcDbHatch::kNotClosed));
            pPoly->setNormal (pHatch->normal());
            pPoly->setElevation (pHatch->elevation());
            pPoly->getGripPoints(ptArray,n1,n2);
            ptArrVect.push_back(ptArray);
            delete pPoly;
        } 
        else 
        {
            AcGeVoidPointerArray edgePtrs;
            AcGeIntArray edgeTypes;
            pHatch->getLoopAt(i, loopType,edgePtrs, edgeTypes );
            AcGeCompositeCurve2d compCurve(edgePtrs);
            AcGeInterval interval;  compCurve.getInterval( interval );
            AcGePoint2dArray vertices;
            AcGeDoubleArray  parms;
         
            compCurve.getSamplePoints(interval.lowerBound(),interval.upperBound(),epx,vertices,parms);
            if (vertices.length () > 0) 
            {
                AcDbPolyline *pPoly = new AcDbPolyline(vertices.length());
                pPoly->setDatabaseDefaults (pHatch->dat abase());
                for (int j=0; j < vertices.length(); j++) 
                    pPoly->addVertexAt (j,vertices[j],0.0);

                pPoly->setClosed (Adesk::kTrue);
                pPoly->setNormal (pHatch->normal());
                pPoly->setElevation (pHatch->elevation());
                pPoly->getGripPoints(ptArray,n1,n2);
                ptArrVect.push_back(ptArray);
                delete pPoly;
            }
        }
    }
    return;
}

значит, на вход идет ObjectId штриховки, а на выход идут наборы точек граничных контуров (один набор, если штриховка простая, несколько, если есть островки и прочая пакость.)
ну и дальше выбирай какой тебе нужен, если их несколько.
единственный минус, это дуговые сегменты, но у меня они нигде не используются :)

Re: Recreate boundery - создание контура для AcDbHatch

Как не стыдно не пользоваться поиском по форуму! Здесь обрабатываются и дуги: https://www.caduser.ru/forum/post146966.html#p146966

Re: Recreate boundery - создание контура для AcDbHatch

Большое спосибо, Николай.
А дуги мы игнорируем =). Но думаю потом они несомненно пригодятся.

Re: Recreate boundery - создание контура для AcDbHatch

Александр Ривилис

а можно создать точный контур по указанной точке внутри фигуры, образованной множеством разных элементов (полилиний, линий и т.п.)? Ведь эта задача близкородственна решенной здесь...
Ведь уже давно известно, что фирменная Boundary не создает в общем случае точных контуров, часто безнадежно зависает или даже не создает их вообще.

Re: Recreate boundery - создание контура для AcDbHatch

Александр пишет:

а можно создать точный контур по указанной точке внутри фигуры, образованной множеством разных элементов (полилиний, линий и т.п.)? Ведь эта задача близкородственна решенной здесь...

Ведь уже давно известно, что фирменная Boundary не создает в общем случае точных контуров, часто безнадежно зависает или даже не создает их вообще.

Эта задача на два порядка сложнее, чем решенная здесь. Она сродни созданию своего аналога команды _BOUNDARY.

Re: Recreate boundery - создание контура для AcDbHatch

Александр Ривилис пишет:

Эта задача на два порядка сложнее, чем решенная здесь. Она сродни созданию своего аналога команды _BOUNDARY.

да, всем, кто делает штриховки, работает с площадями, подсчитывает, вырезает и т.д. и т.п. нужна нормальная альтернатива BOUNDARY.
О проблемах с BOUNDARY говорят на этом и др. форумах как минимум с 2002 года. Есть много решений близких задач - определение положения точки внутри контуров, выделение элементов внутри контуров, здешняя задача восстановления границы штриховок и т.п.
Только вот создания самой границы нет...

Re: Recreate boundery - создание контура для AcDbHatch

Александр пишет:

да, всем, кто делает штриховки, работает с площадями, подсчитывает, вырезает и т.д. и т.п. нужна нормальная альтернатива BOUNDARY.
О проблемах с BOUNDARY говорят на этом и др. форумах как минимум с 2002 года. Есть много решений близких задач - определение положения точки внутри контуров, выделение элементов внутри контуров, здешняя задача восстановления границы штриховок и т.п.
Только вот создания самой границы нет...

Александр. Вы программист? Предложите алгоритм создания такого контура, который был бы хотя бы такой же эффективный, как в команде BOUNDARY и я с удовольствием его реализую. Что касается близости задач, то по сложности они отличаются на порядки. Более того, для определения находится ли точка внутри контура в AutoCAD есть методы, которые позволяют реализовать такой алгоритм достаточно просто. Для создания контура вокруг точки таких алгоритмов нет (да и быть не может).

(изменено: Александр, 21 августа 2009г. 19:54:32)

Re: Recreate boundery - создание контура для AcDbHatch

Александр Ривилис пишет:

Александр. Вы программист? Предложите алгоритм создания такого контура, который был бы хотя бы такой же эффективный, как в команде BOUNDARY и я с удовольствием его реализую. Что касается близости задач, то по сложности они отличаются на порядки. Более того, для определения находится ли точка внутри контура в AutoCAD есть методы, которые позволяют реализовать такой алгоритм достаточно просто. Для создания контура вокруг точки таких алгоритмов нет (да и быть не может).

Нет, я не программист, не математик, не алгоритмист... Только пользователь AutoCAD, MicroStation и пр. Если бы знать алгоритм команды BOUNDARY, то, может быть, его можно было бы уточнить?
Допустим, пока можно обойтись без окружностей, сплайнов, дуг и пр. И, допустим, рассмотрим пока самый простой вариант - линии/полилинии на пересечениях разбиты.
Боюсь спороть ерунду, но рискну: из указанной точки в горизонтальном направлении, например, находим ближайшую линию/полилинию. Находим примыкающие к ее концам другие линии/полилинии. Если не оба конца примыкают, то ее отбрасываем и ищем другую ближайшую. Из примыкающих оставляем только ближайшие к указанной точке и только те, оба конца которых примыкают к другим линиям/полилиниям. И так далее - пока не произойдет замыкание. Если не произойдет - значит такого контура нет (линии немного не примкнуты или т.п.).
Как-то так, наверное...
Тут показали с помощью Autodesk Map - создается топологическая площадная модель из любого множества полилиний, образующих замкнутые фигуры (мгновенно-<1 сек.). А из этой топологической модели создают замкнутые полилинии (мгновенно-<1 сек.). Получающиеся контуры абсолютно точно повторяют исходные линии/полилинии и строятся для всех - даже самых непроходимых для BOUNDARY случаев.
Получается, что в самом Autodesk'е какой-то хороший алгоритм есть...
Сказали, что в ГИС-приложениях под MicroStation есть команды - быстро и точно создают Shape из набора полилиний. Shape потом можно заменить на полилинии (Smartline). Т.е. задача практически решаема...