Тема: Определить,лежит ли один объект(регион) внутри другого?

Может кто-нибудь в курсе, есть ли стандартная функция в acad'е, которая позволят узнать, лежит ли один примитив (замкнутая полилиния, окружность) внутри другого.
Собственно задача состоит в том, что нужно перебрать порядка 1000 подобных примитивов, и узнать, лежит ли один внутри другого. Я написал функцию, которая это делает и для небольшого количества объектов работает нормально, однако по мере увеличения быстро съедает всю память и начинает тупить.

Public Function inside(ByVal obj1 As AcadLWPolyline, ByVal obj2 As AcadLWPolyline) As Boolean
    Dim i As Long
    Dim j As Long
    Static reg1 As Variant
    Static reg2 As Variant
    Dim reg1initialarea As Double
    Dim reg2initialarea As Double
    Dim notErasedObject As String
    Dim isInside As Boolean
    Dim curve1(0 To 0) As AcadEntity
    Dim curve2(0 To 0) As AcadEntity
    Set curve1(0) = obj1
    Set curve2(0) = obj2
    'тормозит здесь ->
    reg1 = ThisDrawing.ModelSpace.AddRegion(curve1)
    reg2 = ThisDrawing.ModelSpace.AddRegion(curve2)
    ' <- тормозит здесь
    reg1initialarea = reg1(0).Area
    reg2initialarea = reg2(0).Area
    If obj1.Area > obj2.Area Then
        reg1(0).Boolean acSubtraction, reg2(0)
        notErasedObject = "region1"
    Else
        reg2(0).Boolean acSubtraction, reg1(0)
        notErasedObject = "region2"
    End If
    isInside = False
    If notErasedObject = "region1" Then
        If reg1(0).Area <> reg1initialarea Then isInside = True
        reg1(0).Delete
    Else ' notErasedObject = "region2"
        If reg2(0).Area <> reg2initialarea Then isInside = True
        reg2(0).Delete
    End If
    If isInside = True Then
        If obj1.Area > obj2.Area Then inside = False
        If obj1.Area < obj2.Area Then inside = True
    End If
End Function

Функция работает корректно, на вход принимает полилинии/окружности, в теле создает временные переменные(регионы) и над ними проводит все операции. Тормозит в том месте, где создаются регионы.

    reg1 = ThisDrawing.ModelSpace.AddRegion(curve1)
    reg2 = ThisDrawing.ModelSpace.AddRegion(curve2)

Можно ли этот момент как-то обойти?

Re: Определить,лежит ли один объект(регион) внутри другого?

Можно. Не создавать новые примитивы. Попробуй так:

Public Enum IsInsideObjects
  FirstOutside = 0    ' первая линия снаружи
  SecondOutside = 1   ' вторая линия снаружи
  Intersected = 2     ' пересекаются
  ErrorComputing = -1 ' ошибка: либо полилинии не замкнуты, либо
                      ' у них разные OCS, либо Elevation, короче
                      ' провести подсчет невозможно
End Enum
Public Function IsInside(ByRef TestOutsideObj As AcadLWPolyline, _
    ByRef TestInsideObj As AcadLWPolyline) As Integer
' Функция проверки вхождения одной полилинии в другую.
' Параметры вызова:
'   TestOutsideObj  указатель на полилинию
'   TestInsideObj   то же
Dim ptMinPointOutside As AcadPoint, ptMaxPointOutside As AcadPoint
Dim ptMinPointInside As AcadPoint, ptMaxPointInside As AcadPoint
  If TestOutsideObj.Closed And _
      TestInsideObj.Closed And _
      TestOutsideObj.Normal = TestInsideObj.Normal And _
      TestOutsideObj.Elevation = TestInsideObj.Elevation Then
    If VarType(TestOutsideObj.IntersectWith(TestInsideObj, acExtendNone)) = vbEmpty Then
      IsInside = IsInsideObjects.Intersected
    ElseIf TestInsideObj.Area > TestOutsideObj.Area Then
      IsInside = IsInsideObjects.SecondOutside
    Else
      IsInside = IsInsideObjects.FirstOutside
    End If
  Else
    IsInside = IsInsideObjects.ErrorComputing
  End If
End Function

Re: Определить,лежит ли один объект(регион) внутри другого?

Эта функция будет работать в 2х случаях:
1 - объекты пересекаются
2 - объекты не пересекаются и один лежит внутри другого
НО, в случае, когда они не пересекаются и один не лежит внутри другого, то  результатом

TestOutsideObj.IntersectWith(TestInsideObj, acExtendNone)

также будет vbEmpty и мы не сможем отличить это от случая 2.
Вот в этом-то вся и загвоздка, что проделать мы это сможем только с помощью регионов. Единственный вариант создать все регионы для всех объектов сразу, причем (если примитивов N штук)в количестве N x N, т.к. в результате работы функции оба региона уничтожаются. Но для N = 600 - это уже проблема, памяти не хватает :( Поэтому-то я и ищу встроенную (то есть по памяти и юзабельности оптимизированную)функцию, которая бы  определяла бы это свойство.
Но все равно спасибо, если появятся ещё мысли - буду рад выслушать!

Re: Определить,лежит ли один объект(регион) внутри другого?

Мысли есть. К каждому объекту применять метод GetBoundingBox и сравнивать полученные точки. Меня "на прописать" попросту не хватило.

Re: Определить,лежит ли один объект(регион) внутри другого?

Спасибо! Об этом методе я не слышал... Если все-таки будут силы написать - буду благодарен!

Re: Определить,лежит ли один объект(регион) внутри другого?

Дык ета... Посмотри в справке-то. попробуй добавить проверку (выделена полужирным в коде) куда надобно, я пока пас. Я проверял работу на варианте

Public Enum enIsInsideObjects
  FirstOutside = 0    ' первая линия снаружи
  SecondOutside = 1   ' вторая линия снаружи
  Intersected = 2     ' пересекаются
  ErrorComputing = -1 ' ошибка: либо полилинии не замкнуты, либо
                      ' у них разные OCS, либо Elevation, короче
                      ' провести подсчет невозможно
End Enum
Public Function IsInside(ByRef TestOutsideObj As AcadLWPolyline, _
    ByRef TestInsideObj As AcadLWPolyline) As Integer
' Функция проверки вхождения одной полилинии в другую.
' Параметры вызова:
'   TestOutsideObj  указатель на полилинию
'   TestInsideObj   то же
Dim ptMinOutside As Variant, ptMaxOutside As Variant
Dim ptMinInside As Variant, ptMaxInside As Variant
  TestOutsideObj.GetBoundingBox ptMinOutside, ptMaxOutside
  TestInsideObj.GetBoundingBox ptMinInside, ptMaxInside
  If TestOutsideObj.Closed And _
      TestInsideObj.Closed And _
      TestOutsideObj.Normal(0) = TestInsideObj.Normal(0) And _
      TestOutsideObj.Normal(1) = TestInsideObj.Normal(1) And _
      TestOutsideObj.Normal(2) = TestInsideObj.Normal(2) And _
      TestOutsideObj.Elevation = TestInsideObj.Elevation _
      And _
[b]      ptMinOutside(0) <= ptMinInside(0) And _
      ptMinOutside(1) <= ptMinInside(1) And _
      ptMinOutside(2) <= ptMinInside(2) And _
      ptMaxOutside(0) >= ptMinInside(0) And _
      ptMaxOutside(1) >= ptMinInside(1) And _
      ptMaxOutside(2) >= ptMinInside(2) _[/b]
      Then
    If VarType(TestOutsideObj.IntersectWith(TestInsideObj, acExtendNone)) = vbEmpty Then
      IsInside = enIsInsideObjects.Intersected
    ElseIf TestInsideObj.Area > TestOutsideObj.Area Then
      IsInside = enIsInsideObjects.SecondOutside
    Else
      IsInside = enIsInsideObjects.FirstOutside
    End If
  Else
    IsInside = enIsInsideObjects.ErrorComputing
  End If
End Function
Private Sub TestInside(arrInside As Variant, arrOutside As Variant)
Dim LWPLine1 As AcadLWPolyline, LWPLine2 As AcadLWPolyline
Dim sMsg As String
  Set LWPLine1 = ThisDrawing.ModelSpace.AddLightWeightPolyline(arrOutside)
  LWPLine1.Closed = True
  Set LWPLine2 = ThisDrawing.ModelSpace.AddLightWeightPolyline(arrInside)
  LWPLine2.Closed = True
  ThisDrawing.Regen acAllViewports
  Select Case IsInside(LWPLine1, LWPLine2)
    Case enIsInsideObjects.ErrorComputing
      sMsg = "Ошибка вычислений"
    Case enIsInsideObjects.FirstOutside
      sMsg = "Первый снаружи"
    Case enIsInsideObjects.SecondOutside
      sMsg = "Второй снаружи"
    Case enIsInsideObjects.Intersected
      sMsg = "Объекты пересекаются"
  End Select
  MsgBox sMsg, vbOKOnly + vbInformation + vbApplicationModal, "Testing..."
End Sub
Public Sub FullTest()
Dim vertIn() As Double, vertOut() As Double
  ReDim vertOut(11)
  vertOut(0) = 1050.07: vertOut(1) = 311.717
  vertOut(2) = 772.378: vertOut(3) = 175.035
  vertOut(4) = 669.115: vertOut(5) = 442.819
  vertOut(6) = 850.523: vertOut(7) = 360.531
  vertOut(8) = 903.55: vertOut(9) = 745.47
  vertOut(10) = 1210.55: vertOut(11) = 497.212
  ReDim vertIn(7)
  vertIn(0) = 766.796: vertIn(1) = 682.708
  vertIn(2) = 733.306: vertIn(3) = 619.946
  vertIn(4) = 808.323: vertIn(5) = 579.916
  vertIn(6) = 844.652: vertIn(7) = 647.995
  TestInside vertOut, vertIn
  TestInside vertIn, vertOut
  '826.968 404.257 793.478 341.495 868.495 301.465 904.824 369.544
  '1002.79 554.885 969.304 492.123 1044.32 452.093 1080.65 520.172
End Sub

P.S. Ща придут спецы по VBA и разгромят меня в пух и прах :)

Re: Определить,лежит ли один объект(регион) внутри другого?

В общем проблему это не решает (т.к. могут быть случаи, когда BB одного полностью включает BB 2го, но при этом 2й не лежит в 1-м), но если добавить условие на BoundingBox, то количество итераций, в которых будут создаваться регионы уменьшится порядка на 2, соответственно, есть надежда, что памяти хватит :)
ЗЫ. Пусть приходят, интересно, что из этого получится ;) на самом деле, написано все корректно, хотя может и не совсем оптимально для  ВБА(потому как ты, наверное, привык писать на лиспе), но я бы сам написал примерно так же

Re: Определить,лежит ли один объект(регион) внутри другого?

Да, лисповик я:) Наверное, сильно заметно ;)
P.S. Проверка (которая выделена) была введена в одной из предпоследних версий макроса, потом я от нее отказался, потом восстановил. Фактически надо проверять (ЯТД) несколько условий:
- вхождение BoundingBox объекта TestOutsideObj внутрь TestInsideObj;
- вхождение BoundingBox объекта TestInsideObj внутрь TestOutsideObj;
- их совпадение (на фига, не очень понятно, но вдруг чего путное придумается ;))
И все эти проверки фактически это повторение этих несчастных строк с разными условиями сравнения. Муторно...

Re: Определить,лежит ли один объект(регион) внутри другого?

Не в том дело, что муторно. Смысл в том, что у меня алгоритм строится следующим образом:

  if ВВ Объекта 1 НЕ входит в ВВ объект 2
    inside = False
  else
    inside = insideReg(объект1, объект2)
  end if

А функция insideReg - уже работает с регионами как я и писал. Получается все равно медленно... :(
Фишка в том, что каждый раз при вызове этой функции долго выполняется только первый вызов создания регионов, а второй - почти мгновенно, то есть я думал заготовки под все эти регионы создать сразу, что решит вопрос времени, но вопрос с памятью останется. У меня её в очередной раз не хватило.. Короче, извороты это лишние, проблема должна решаться проще, с помощью стандартных средств, а эти костыли - корявое и ненужное средство... Может я, конечно, маловато знаю, но других способов я пока не вижу.
Может быть есть ещё функции, о которых мне стоит узнать? :)

Re: Определить,лежит ли один объект(регион) внутри другого?

А вся проблема на самом деле в том, что построение регионов, точно так же как булевские операции с ними, требуют при первом вызове подгрузки нескольких dll, отвечающих за это дело.
Идея есть, но у меня на ее реализацию на VBA точно ничего не хватит :( Берется алгоритм вхождения точки в контур (например, отсюда) и проверяется отсутствие пересечений (IntersectWith) и вхождение хотя бы одной вершины полилинии внутрь контура другой. Хотя почему бы не попробовать (если выполнять построение луча, то можно ;))

Option Explicit
Public Enum enIsInsideObjects
  FirstOutside = 0    ' первая линия снаружи
  SecondOutside = 1   ' вторая линия снаружи
  Intersected = 2     ' пересекаются
  ErrorComputing = -1 ' ошибка: либо полилинии не замкнуты, либо
                      ' у них разные OCS, либо Elevation, короче
                      ' провести подсчет невозможно
End Enum
Public Function PointInsideContur(Point As Variant, Bound As AcadObject) As Boolean
' Проверка на вхождение точки в контур. С построением временных примитивов
' Работает только в WCS при установленной Elevation = 0
' Возвращает True, если точка находится внутри контура Bound
Dim tmpPoint As Variant, tmpCoord(2) As Double
Dim tmpRay As AcadRay
Dim IntersectionPoints As Variant
  tmpCoord(0) = Point(0) + 100: tmpCoord(1) = Point(1)
  If UBound(Point) < 2 Then
    tmpCoord(2) = ThisDrawing.GetVariable("Elevation")
    ReDim Preserve Point(2)
    Point(2) = ThisDrawing.GetVariable("Elevation")
  Else
    tmpCoord(2) = Point(2)
  End If
  tmpPoint = tmpCoord
  Set tmpRay = ThisDrawing.ModelSpace.AddRay(Point, tmpPoint)
  IntersectionPoints = tmpRay.IntersectWith(Bound, acExtendNone)
  [i]
  ' Вот здесь у меня фигня какая-то получается. Слишком сильно спать хоцца...
  If VarType(IntersectionPoints) <> vbEmpty Then
    Select Case IntersectionPoints
      Case UBound(IntersectionPoints) < 0
        PointInsideContur = False
      Case CInt((UBound(IntersectionPoints) + 1) / 3) * 3 = UBound(IntersectionPoints) + 1
        PointInsideContur = False
      Case Else
        PointInsideContur = True
    End Select
  End If[/i]
End Function
Public Function IsInside(ByVal TestOutsideObj As AcadLWPolyline, _
    ByVal TestInsideObj As AcadLWPolyline) As Integer
' Функция проверки вхождения одной полилинии в другую.
' Параметры вызова:
'   TestOutsideObj  указатель на полилинию
'   TestInsideObj   то же
Dim ptMinOutside As Variant, ptMaxOutside As Variant
Dim ptMinInside As Variant, ptMaxInside As Variant
Dim vertOut As Variant, vertIn As Variant
  TestOutsideObj.GetBoundingBox ptMinOutside, ptMaxOutside
  TestInsideObj.GetBoundingBox ptMinInside, ptMaxInside
  If TestOutsideObj.Closed And _
      TestInsideObj.Closed And _
      TestOutsideObj.Normal(0) = TestInsideObj.Normal(0) And _
      TestOutsideObj.Normal(1) = TestInsideObj.Normal(1) And _
      TestOutsideObj.Normal(2) = TestInsideObj.Normal(2) And _
      TestOutsideObj.Elevation = TestInsideObj.Elevation _
      Then
    If VarType(TestOutsideObj.IntersectWith(TestInsideObj, acExtendNone)) = vbEmpty Then
      IsInside = enIsInsideObjects.Intersected
    Else
      vertOut = TestOutsideObj.Coordinate(0)
      vertIn = TestInsideObj.Coordinate(0)
      If PointInsideContur(vertIn, TestOutsideObj) Then
        IsInside = enIsInsideObjects.SecondOutside
      Else
        IsInside = enIsInsideObjects.FirstOutside
      End If
    End If
  Else
    IsInside = enIsInsideObjects.ErrorComputing
  End If
End Function
Private Sub TestInside(arrInside As Variant, arrOutside As Variant)
Dim LWPLine1 As AcadLWPolyline, LWPLine2 As AcadLWPolyline
Dim sMsg As String
  Set LWPLine1 = ThisDrawing.ModelSpace.AddLightWeightPolyline(arrOutside)
  LWPLine1.Closed = True
  Set LWPLine2 = ThisDrawing.ModelSpace.AddLightWeightPolyline(arrInside)
  LWPLine2.Closed = True
  ThisDrawing.Regen acAllViewports
  Select Case IsInside(LWPLine1, LWPLine2)
    Case enIsInsideObjects.ErrorComputing
      sMsg = "Ошибка вычислений"
    Case enIsInsideObjects.FirstOutside
      sMsg = "Первый снаружи"
    Case enIsInsideObjects.SecondOutside
      sMsg = "Второй снаружи"
    Case enIsInsideObjects.Intersected
      sMsg = "Объекты пересекаются"
  End Select
  MsgBox sMsg, vbOKOnly + vbInformation + vbApplicationModal, "Testing..."
End Sub
Public Sub FullTest()
Dim vertIn() As Double, vertOut() As Double
  ReDim vertOut(11)
  vertOut(0) = 1050.07: vertOut(1) = 311.717
  vertOut(2) = 772.378: vertOut(3) = 175.035
  vertOut(4) = 669.115: vertOut(5) = 442.819
  vertOut(6) = 850.523: vertOut(7) = 360.531
  vertOut(8) = 903.55: vertOut(9) = 745.47
  vertOut(10) = 1210.55: vertOut(11) = 497.212
  ReDim vertIn(7)
  vertIn(0) = 766.796: vertIn(1) = 682.708
  vertIn(2) = 733.306: vertIn(3) = 619.946
  vertIn(4) = 808.323: vertIn(5) = 579.916
  vertIn(6) = 844.652: vertIn(7) = 647.995
  TestInside vertOut, vertIn
  TestInside vertIn, vertOut
  '826.968 404.257 793.478 341.495 868.495 301.465 904.824 369.544
  '1002.79 554.885 969.304 492.123 1044.32 452.093 1080.65 520.172
End Sub

Re: Определить,лежит ли один объект(регион) внутри другого?

Заинтересовала проблема с памятью, а после вспомнил что сам использую
проверку на врезку регионов друг в друга, только для других целей.
Проверил данную проблему у себя, её не оказалось. Но как только ради
интереса сделал цикл в цикле и запустил на обработку файл 13Mb,
с 32800-ми контурами, наваленными друг на друга, и у меня не
хватило свободного места на винте.
Результат получил следующий: IV Пень, RIMM-1066 512Mb,
1 час работы - обработано 640 контуров, сожрано 45Mb оперативки и
675Mb на винте.
Выяснил, что винт жрёт Undo. Поэтому его необходимо отключать.
С оперативкой не поможет, но винт шерстить перестанет.
Отключить можно, только через SendCommand. В VBA ни каких методов для
этого нет, а системная переменная UNDOCTL только для чтения. Поэтому,
лучше вручную, перед запуском цикла.
В ниже приведённом коде, добавил данную строку перед самым циклом.
Кроме того снизил количество циклов в два раза, так как проверку
делаем обоюдно, сразу для обоих контуров, то нет смысла повторять её в
дальнейшем. Поэтому, Каждый последующий полигон проверяем начиная не с
первого, а со следующего, за проверяемым. То есть, с каждым проверенным
контуром мы уменьшаем число проверок на единицу.

Sub StartProg()
Dim acadObj As AcadEntity
Dim acadObjs(0) As AcadEntity
Dim SelPoligons As AcadSelectionSet
Dim CoordXY As Variant, RegionObj As Variant
Dim NewReg As Boolean
Dim StepN As Byte, Result As Byte
Dim I As Long, J As Long
Dim NReg As String
' Создаём временную коллекцию для проверяемых объектов
   With ActiveDocument
      For Each SelPoligons In .SelectionSets
         If SelPoligons.Name = "$SEL_POLIGONS" Then SelPoligons.Delete: Exit For
      Next SelPoligons
      Set SelPoligons = .SelectionSets.Add("$SEL_POLIGONS")
   End With
' Отфильтровываем объекты, с которыми метод создания регионов не работает
' или не замкнутые объекты. Желательно добавить фильтр и на необходимые слои.
   For Each acadObj In ActiveDocument.ModelSpace
      Select Case acadObj.ObjectName
       Case "AcDb3dPolyline", "AcDb2dPolyline", "AcDbPolyline", "AcDbSpline"
         If acadObj.ObjectName = "AcDbSpline" Then _
            CoordXY = acadObj.ControlPoints _
          Else: CoordXY = acadObj.Coordinates
         If acadObj.ObjectName = "AcDbPolyline" Then _
            StepN = UBound(acadObj.Coordinate(0)) + 1 _
          Else StepN = 3
         If CoordXY(UBound(CoordXY) + 1 - StepN) <> CoordXY(0) Or _
           CoordXY(UBound(CoordXY) + 2 - StepN) <> CoordXY(1) Then
            If acadObj.Closed = False Then GoTo NextFor
         End If
         Set acadObjs(0) = acadObj
       Case "AcDbSolid", "AcDbRegion", "AcDbCircle", "AcDbEllipse"
         Set acadObjs(0) = acadObj
       Case Else: GoTo NextFor
      End Select
      SelPoligons.AddItems acadObjs
NextFor:
   Next acadObj
   If SelPoligons.Count < 2 Then _
      MsgBox "В рисунке менее 2-х полигонов!", vbExclamation: Exit Sub
' Отключаем Undo
   ActiveDocument.SendCommand "_undo _Control _None" & vbCr
' Открываем счётчик (Просто форма с именем UserForm1 и
' текстом с именем Label1)
   UserForm1.Show vbModeless
   With UserForm1.Label1
      NReg = " - " & SelPoligons.Count - 1
     ReDim RegionObj(0) As Variant
' Запускаем цикл на выполнение
      For I = 0 To SelPoligons.Count - 2
         .Caption = I & NReg: DoEvents
         NewReg = True
         Set RegionObj(0) = Nothing
         For J = I + 1 To SelPoligons.Count - 1
            Result = PoligonToPoligon(NewReg, SelPoligons(I), SelPoligons(J), RegionObj)
            Select Case Result
             Case 4: ' Код если один или оба полигона были не корректными
             Case 3: ' Код если полигоны пересекаются
             Case 2: ' Код если полигон 2 внутри полигона 1
             Case 1: ' Код если полигон 1 внутри полигона 2
             Case 0: ' Код если полигоны не зависимы друг от друга
            End Select
         Next J
         If Not (RegionObj(0) Is Nothing) Then RegionObj(0).Delete
      Next I
      SelPoligons.Delete
      .Caption = I & NReg
   End With
' Восстанавливаем режим Undo
   ActiveDocument.SendCommand "_undo _Control _All" & vbCr
End Sub
' Функция контроля вложенности контуров
Function PoligonToPoligon(NewReg As Boolean, PoligonObj1 As AcadEntity, _
                          PoligonObj2 As AcadEntity, RegionObj1 As Variant) As Byte
Static RegAreaOld As Double
Dim RegionSumm As AcadEntity
Dim ArrayPoligon(0) As AcadEntity
Dim RegionObj2 As Variant
Dim IntPoints As Variant
Dim XYmin1 As Variant, XYmax1 As Variant, XYmin2 As Variant, XYmax2 As Variant
' Делаем простейшую проверку на явный разброс контуров
   PoligonObj1.GetBoundingBox XYmin1, XYmax1
   PoligonObj2.GetBoundingBox XYmin2, XYmax2
   If XYmax2(0) < XYmin1(0) Or XYmin2(0) > XYmax1(0) Or _
     XYmax2(1) < XYmin1(1) Or XYmin2(1) > XYmax1(1) Then _
      PoligonToPoligon = 0: Exit Function
' Делаем проверку на пересечение контуров
   IntPoints = PoligonObj1.IntersectWith(PoligonObj2, acExtendNone)
   If UBound(IntPoints) > 1 Then PoligonToPoligon = 3: Exit Function
' Создаём необходимые регионы
   On Error Resume Next
   With ActiveDocument.ModelSpace
      If NewReg = True Then
         If PoligonObj1.ObjectName = "AcDbRegion" Then
           ReDim RegionObj1(0) As Variant
            Set RegionObj1(0) = PoligonObj1.Copy
          Else
            Set ArrayPoligon(0) = PoligonObj1
            RegionObj1 = .AddRegion(ArrayPoligon)
            If Err <> 0 Then
               PoligonToPoligon = 4
               On Error GoTo 0: Exit Function
            End If
            RegAreaOld = RegionObj1(0).Area
         End If
         NewReg = False
      End If
      If PoligonObj2.ObjectName = "AcDbRegion" Then
        ReDim RegionObj2(0) As Variant
         Set RegionObj2(0) = PoligonObj2.Copy
       Else
         Set ArrayPoligon(0) = PoligonObj2
         RegionObj2 = .AddRegion(ArrayPoligon)
      End If
   End With
   If Err <> 0 Then PoligonToPoligon = 4: Exit Function
   On Error GoTo 0
' Выполняем проверку на вхождение регионов друг в друга
   Set RegionSumm = RegionObj1(0).Copy
   RegionSumm.Boolean acIntersection, RegionObj2(0)
   If RegionSumm.Area = 0 Then
      PoligonToPoligon = 0
    ElseIf RegionSumm.Area = RegAreaOld Then
      PoligonToPoligon = 1
    ElseIf RegionSumm.Area < RegAreaOld Then
      PoligonToPoligon = 2
   End If
   RegionSumm.Delete
End Function