Не работает BooleanOperation для Region (AutoCAD 2013)

Автор Тема: Не работает BooleanOperation для Region (AutoCAD 2013)  (Прочитано 7070 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн trirАвтор темы

  • ADN Club
  • ****
  • Сообщений: 475
  • Карма: 63
Код:
Код - vb.net [Выбрать]
  1.     <CommandMethod("test3")> _
  2.     Public Sub test3()
  3.         Dim acDoc As MyAcAs.Document = MyAcAs.Application.DocumentManager.MdiActiveDocument
  4.         Dim acCurDb As Database = acDoc.Database
  5.         Dim docloc As MyAcAs.DocumentLock = acDoc.LockDocument()
  6.         Using docloc
  7.             Dim wCol As ObjectIdCollection = CrEnt()
  8.             Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
  9.                 Dim reg1, reg2 As Region
  10.                 reg1 = acTrans.GetObject(wCol(0), OpenMode.ForWrite).Clone
  11.                 reg2 = acTrans.GetObject(wCol(1), OpenMode.ForWrite).Clone
  12.                 reg1.BooleanOperation(BooleanOperationType.BoolSubtract, reg2)
  13.                 Dim acBlkTbl As BlockTable
  14.                 acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
  15.                 Dim acBlkTblRec As BlockTableRecord
  16.                 acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
  17.                 acBlkTblRec.AppendEntity(reg1)
  18.                 acTrans.AddNewlyCreatedDBObject(reg1, True)
  19.                 acTrans.Commit()        
  20.             End Using
  21.         End Using
  22.         acCurDb = Nothing
  23.         acDoc = Nothing
  24.     End Sub
  25.  
  26.     Public Function CrEnt() As ObjectIdCollection
  27.         Dim acDoc As MyAcAs.Document = MyAcAs.Application.DocumentManager.MdiActiveDocument
  28.         Dim acCurDb As Database = acDoc.Database
  29.         Dim res As New ObjectIdCollection
  30.         'Dim docloc As MyAcAs.DocumentLock = acDoc.LockDocument()
  31.         'Using docloc
  32.         Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
  33.             Dim acBlkTbl As BlockTable
  34.             acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
  35.             '' Open the Block table record Model space for write
  36.             Dim acBlkTblRec As BlockTableRecord
  37.             acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
  38.             '
  39.             Dim wCol As DBObjectCollection = CrReg(CrPoly())
  40.             For I = 0 To wCol.Count - 1
  41.                 acBlkTblRec.AppendEntity(wCol(I))
  42.                 acTrans.AddNewlyCreatedDBObject(wCol(I), True)
  43.                 res.Add(wCol(I).ObjectId)
  44.             Next I
  45.             acTrans.Commit()
  46.         End Using
  47.         acCurDb = Nothing
  48.         acDoc = Nothing
  49.         Return res
  50.     End Function
  51.  
  52.     Public Function CrPoly() As Polyline
  53.         Dim res As New Polyline()
  54.         '
  55.         res.AddVertexAt(0, New Point2d(0, 0), 0, 0, 0)
  56.         res.AddVertexAt(1, New Point2d(0, 10), 0, 0, 0)
  57.         res.AddVertexAt(2, New Point2d(5, 15), 0, 0, 0)
  58.         res.AddVertexAt(3, New Point2d(45, 15), 0, 0, 0)
  59.         res.AddVertexAt(4, New Point2d(45, 0), 0, 0, 0)
  60.         res.Closed = True
  61.         '
  62.         Return res
  63.     End Function
  64.  
  65.     Public Function CrReg(wPoly As Polyline) As DBObjectCollection
  66.         Dim wCol As New DBObjectCollection
  67.         wCol.Add(wPoly)
  68.         'Dim res As New Region
  69.         wCol.Add(New Circle(New Point3d(35, 7, 0), New Vector3d(0, 0, 1), 2))
  70.         wCol = Region.CreateFromCurves(wCol)
  71.         Return wCol
  72.     End Function
« Последнее редактирование: 06-10-2014, 16:05:11 от Александр Ривилис »

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
Честно говоря из кода я не слишком хорошо понял чего ты добиваешься и зачем проводишь операцию вычитания с клонами, а не с исходными областями.
Тем не менее вот так работает:
Код - vb.net [Выбрать]
  1. Imports System
  2. Imports Autodesk.AutoCAD.Runtime
  3. Imports Autodesk.AutoCAD.ApplicationServices
  4. Imports Autodesk.AutoCAD.DatabaseServices
  5. Imports Autodesk.AutoCAD.Geometry
  6. Imports Autodesk.AutoCAD.EditorInput
  7. <Assembly: CommandClass(GetType(AutoCAD_VB_plug_in1.MyCommands))>
  8. Namespace AutoCAD_VB_plug_in1
  9.     Public Class MyCommands
  10.         <CommandMethod("test3")> _
  11.         Public Sub test3()
  12.             Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
  13.             Dim acCurDb As Database = acDoc.Database
  14.             Dim docloc As DocumentLock = acDoc.LockDocument()
  15.             Using docloc
  16.                 Dim wCol As ObjectIdCollection = CrEnt()
  17.                 Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
  18.                     Dim reg1, reg2, reg3 As Region
  19.                     reg1 = acTrans.GetObject(wCol(0), OpenMode.ForRead).Clone
  20.                     reg2 = acTrans.GetObject(wCol(1), OpenMode.ForRead).Clone
  21.                     ' Так как вычитать имеет смысл только из большей области меньшую
  22.                     ' то проведём небольшое исследование и упорядочим области
  23.                     If (reg2.Area > reg1.Area) Then
  24.                         reg3 = reg2 : reg2 = reg1
  25.                     Else
  26.                         reg3 = reg1
  27.                     End If
  28.                     reg3.BooleanOperation(BooleanOperationType.BoolSubtract, reg2)
  29.                     Dim acBlkTbl As BlockTable
  30.                     acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
  31.                     Dim acBlkTblRec As BlockTableRecord
  32.                     acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
  33.                     acBlkTblRec.AppendEntity(reg3)
  34.                     reg3.Close()
  35.                     acTrans.Commit()
  36.                 End Using
  37.             End Using
  38.             acCurDb = Nothing
  39.             acDoc = Nothing
  40.         End Sub
  41.  
  42.         Public Function CrEnt() As ObjectIdCollection
  43.             Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
  44.             Dim acCurDb As Database = acDoc.Database
  45.             Dim res As New ObjectIdCollection
  46.             'Dim docloc As MyAcAs.DocumentLock = acDoc.LockDocument()
  47.             'Using docloc
  48.             Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
  49.                 Dim acBlkTbl As BlockTable
  50.                 acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
  51.                 '' Open the Block table record Model space for write
  52.                 Dim acBlkTblRec As BlockTableRecord
  53.                 acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
  54.                 '
  55.                 Dim wCol As DBObjectCollection = CrReg(CrPoly())
  56.                 For I = 0 To wCol.Count - 1
  57.                     acBlkTblRec.AppendEntity(wCol(I))
  58.                     acTrans.AddNewlyCreatedDBObject(wCol(I), True)
  59.                     res.Add(wCol(I).ObjectId)
  60.                 Next I
  61.                 acTrans.Commit()
  62.             End Using
  63.             acCurDb = Nothing
  64.             acDoc = Nothing
  65.             Return res
  66.         End Function
  67.  
  68.         Public Function CrPoly() As Polyline
  69.             Dim res As New Polyline()
  70.             '
  71.             res.AddVertexAt(0, New Point2d(0, 0), 0, 0, 0)
  72.             res.AddVertexAt(1, New Point2d(0, 10), 0, 0, 0)
  73.             res.AddVertexAt(2, New Point2d(5, 15), 0, 0, 0)
  74.             res.AddVertexAt(3, New Point2d(45, 15), 0, 0, 0)
  75.             res.AddVertexAt(4, New Point2d(45, 0), 0, 0, 0)
  76.             res.Closed = True
  77.             '
  78.             Return res
  79.         End Function
  80.  
  81.         Public Function CrReg(wPoly As Polyline) As DBObjectCollection
  82.             Dim wCol As New DBObjectCollection
  83.             wCol.Add(wPoly)
  84.             'Dim res As New Region
  85.             wCol.Add(New Circle(New Point3d(35, 7, 0), New Vector3d(0, 0, 1), 2))
  86.             wCol = Region.CreateFromCurves(wCol)
  87.             Return wCol
  88.         End Function
  89.  
  90.     End Class
  91.  
  92. End Namespace

P.S.: Вот это абсолютно лишнее:
Код - vb.net [Выбрать]
  1.            acCurDb = Nothing
  2.             acDoc = Nothing
« Последнее редактирование: 06-10-2014, 16:29:16 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн trirАвтор темы

  • ADN Club
  • ****
  • Сообщений: 475
  • Карма: 63
Кажется всё дело в "If (reg2.Area > reg1.Area) Then"
http://knowledge.autodesk.com/support/autocad/downloads/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-684E602E-3555-4370-BCDC-1CE594676C43-htm.html
Хотя если просто поменять reg1 и reg2 местами - просто будет fatal error...

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
Кажется всё дело в "If (reg2.Area > reg1.Area) Then"
Это одно из...
Хотя если просто поменять reg1 и reg2 местами - просто будет fatal error...
Надеюсь ты имеешь в виду не Fatal Error, а Exception. Во всяком случае у меня в AutoCAD 2013 SP2 x64 Fatal Error не воспроизводится.
Если уж начать перечислять "неточности" в твоём коде, то зачем в этом коде:
Код - C# [Выбрать]
  1. reg1 = acTrans.GetObject(wCol(0), OpenMode.ForWrite).Clone
  2. reg2 = acTrans.GetObject(wCol(1), OpenMode.ForWrite).Clone
ForWrite, если вполне достаточно ForRead?



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн trirАвтор темы

  • ADN Club
  • ****
  • Сообщений: 475
  • Карма: 63
Именно Fatal Error
ForWrite - потому что иначе ругался

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
Именно Fatal Error
ForWrite - потому что иначе ругался
Какой-то AutoCAD у тебя неправильный. ;)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение