Alex_AMF 发表于 2022-7-6 22:05:13

如何利用内置旋转

你好
 
我们的用户必须能够旋转一系列的线、圆、块等(这导致看起来像一个输送机)。我试图使用AutoCAD的内置旋转命令传递选择集。
 
我在AutoDesk论坛上获得了很多帮助:
http://forums.autodesk.com/t5/net/how-to-pass-objectidcollection-into-built-in-rotate-command/m-p/5429159#M42620
 
我现在似乎陷入了僵局。我没有AutoCAD 2015,所以我使用RunCommand包装器来使用编辑器。命令()。
 
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Linq.Expressions
Imports System.Reflection
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput

Module EditorInputExtensionMethods
   <System.Runtime.CompilerServices.Extension()> _
   Public Function Command(editor As Editor, ParamArray args As Object()) As PromptStatus
       If editor Is Nothing Then
         Throw New ArgumentNullException("editor")
       End If
       Return runCommand(editor, args)
   End Function
   Dim runCommand As Func(Of Editor, Object(), PromptStatus) = GenerateRunCommand()
   Private Function GenerateRunCommand() As Func(Of Editor, Object(), PromptStatus)
       Dim method As MethodInfo = GetType(Editor).GetMethod("RunCommand", BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.)
       Dim instance As ParameterExpression = Expression.Parameter(GetType(Editor), "editor")
       Dim args As ParameterExpression = Expression.Parameter(GetType(Object()), "args")
       Return Expression.Lambda(Of Func(Of Editor, Object(), PromptStatus))(Expression.Call(instance, method, args), instance, args).Compile()
   End Function
End Module
 
然后,我使用构建的对象ID集合填充我的SelectionSet。以下是我用来尝试使用AutoCAD提供的内置旋转命令的代码:
 
<CommandMethod("My-Rotate")> _
Public Sub MyRotate()
   'Get the current document and database
   Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
   Dim acCurDb As Database = acDoc.Database
   Dim acObj As Object
   Dim entRes As PromptEntityResult
   Dim entOpts As PromptEntityOptions
   Dim rb As ResultBuffer
   Dim FoundHunter As Boolean
   Dim acBlkTbl As BlockTable
   Dim acBlkTblRec As BlockTableRecord
   Dim pickedPolyline As Polyline = Nothing
   Dim SelSet As SelectionSet
   Dim Lst_ObjId As New List(Of ObjectId)

   'Prompt user to select the conveyor he wants to rotate
   Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView()
   entOpts = New PromptEntityOptions(vbLf & "Choose the object you wish to rotate")
   entRes = acDoc.Editor.GetEntity(entOpts)

   If (entRes.Status = PromptStatus.OK) Then

       'Start a transaction
       Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
         acObj = entRes.ObjectId.GetObject(OpenMode.ForRead)

         'Make sure the selected object was a polyline
         If Not TypeOf acObj Is Polyline Then MsgBox("You must choose a line or polyline") : Exit Sub

         rb = New ResultBuffer
         rb = entRes.ObjectId.GetObject(OpenMode.ForRead).XData()

         'Sets the correct Project Conveyor
         ProjectConveyor.SetByDataTable(GetPKFromResultBuffer(rb), Project.PK_Project)
         
         'Open the Block table for read
         acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)            
         
         'Open the Block table record Model space for write
         acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

         'Go through the Block Table Record and build the collection ID
         For Each acObjId As ObjectId In acBlkTblRec
               rb = New ResultBuffer
               rb = acObjId.GetObject(OpenMode.ForRead).XData()
               FoundHunter = False

               If Not rb Is Nothing Then
                   For Each tv As TypedValue In rb
                     If tv.TypeCode = DxfCode.ExtendedDataRegAppName Then
                           If tv.Value = "MY_PROGRAM_NAME" Then FoundHunter = True
                     End If
                     If FoundHunter And tv.TypeCode = DxfCode.ExtendedDataInteger32 Then
                           If tv.Value = ProjectConveyor.PK_ProjectConveyor Then
                               Lst_ObjId.Add(acObjId) 'Sets up all object IDs correctly here
                               Exit For
                           End If
                     End If
                   Next

                   rb.Dispose()
               End If
         Next

         'Create a selection set from object IDs
         SelSet = SelectionSet.FromObjectIds(Lst_ObjId.ToArray)

         'Use AUTOCAD's Rotate function knowing we have all selections in selection set
         acDoc.Editor.Command("_.rotate", SelSet, "")

         'Save the new objects to the database
         ProjectConveyor.Update()
         acTrans.Commit()
       End Using
   End If
End Sub
 
我的问题是,每当我到达acDoc。编辑命令()部分,它不会提示用户旋转任何内容。它返回错误(-5001)。。。有什么想法吗?

BlackBox 发表于 2022-7-6 22:21:15

 
尝试移动编辑器。Command()从事务的using语句中调用,在它后面加上类似(如图所示)的内容:
 

                   // ...

                   //Create a selection set from object IDs
                   SelSet = SelectionSet.FromObjectIds(Lst_ObjId.ToArray());

                   //Use AUTOCAD's Rotate function knowing we have all selections in selection set
                   //acDoc.Editor.Command("_.rotate", SelSet, "");

                   //Save the new objects to the database
                   ProjectConveyor.Update();
                   acTrans.Commit();
               }

               if (SelSet.Count > 0)
                   acDoc.Editor.Command("_.rotate", SelSet, "");
         }
       }

 
^^2015年测试,FWIW

Alex_AMF 发表于 2022-7-6 22:29:19

感谢黑盒回复。
 
我找到了问题的根源,但还没有解决。
 
我在AutoCad标准版中测试了这一切,这是所有用户通常使用的版本。
http://i.imgur.com/0EcIYw5.png
 
最后,我在AutoCad Mechanical edition中进行了测试。
http://i.imgur.com/pLnU9Xy.png
 
它只在机械方面起作用。在Mechanical中,它甚至可以与事务中的编辑器命令一起工作。为了慎重起见,我将按照你的建议把它排除在交易之外。
 
你知道为什么它在标准版中如此浮夸吗?
 

BlackBox 发表于 2022-7-6 22:36:47

 
没有更多信息或完整的代码继续。。。不
 
我也在使用AutoCAD垂直工具,如Map 3D和Civil 3D(我们的主要生产工具)。。。Map 3D、Civil 3D、Mechanical、MEP等垂直视图构建在我们称之为vanilla AutoCAD(您称之为标准)的基础上,因此在AutoCAD中工作的内容将在垂直视图(OOTB)中工作。。。然而,在垂直方向上起作用的可能在香草中不一定起作用。
 
如果您发现需要两个独立的交互,那么您可以考虑在代码中使用and If或SWITCH case语句有条件地测试它,或者只编译两个独立的程序集,并使用自动加载机制将正确的程序集自动加载到正确的应用程序中。如果还不熟悉,请参阅我签名中的链接以了解更多信息。
 
另外,如果你还不是ADN会员,你将继续为你的雇主开发内部定制。。。您可以考虑成为AUGI Professional会员,该会员具有免费的Autodesk Developer Network(ADN)标准会员资格(为您节省1400美元)。
 
干杯

Alex_AMF 发表于 2022-7-6 22:40:48

你说得对,我在“标准”AutoCAD上使用了Vanilla配置文件,而机械配置文件从ACADMPP开始。
 
我会在你的签名中查看你的自动加载器链接。此外,我将登记成为AUGI专业会员。看起来很有趣。
 
谢谢

BlackBox 发表于 2022-7-6 22:55:22

 
不客气,Alex_AMF;我很乐意帮忙。
 
干杯

Alex_AMF 发表于 2022-7-6 22:59:23

最后一个问题。。。
 
我对使用内置rotate命令的代码有一个问题。旋转项目后,我想在数据库中保存新的Point3d,然后保存图形。尽管如此,我的问题是编译器要通过编辑器。Command(),一直持续到结束子对象,然后提示用户旋转对象。
 
为什么不等到用户完成命令后再继续?它只是直接通过。
 
有办法解决这个问题吗?

BlackBox 发表于 2022-7-6 23:11:09

 
您应该仔细阅读同步执行和异步执行之间的区别。
 
您可能需要考虑使用SendStringToExecute()。
 
干杯
页: [1]
查看完整版本: 如何利用内置旋转