为什么使用 ObjectARX 中的命令创建的视口没有保存到数据库中?

问题描述

总结

我正在尝试编写一个 C# ObjectARX 脚本来使用 -VPORTS Fit 命令创建一个适合布局范围的视口,但由于某种原因,新视口显示在 AutoCAD 中,但从未保存到输出中绘图。

我尝试过的一些事情

  • 使用 acDoc.SendStringToExecute() 而不是 acDoc.Editor.Command()
  • 使用 -VPORTS 而不是 ._VIEWPORTS
  • 在提交事务之前运行命令
    • 导致 AutoCAD 冻结和崩溃。我想我必须先提交新布局,然后才能制作视口

代码片段

[CommandMethod("CreateViewport")]
public static void CreateViewport()
{
    // Get the current document and database,and start a transaction
    Document acDoc = Application.DocumentManager.MdiActiveDocument;
    Database acCurDb = acDoc.Database;

    try
    {
        Entity acObj = null;

        using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
        {
            // Omitted code for opening block record ...

            // Switch to the previous Paper space layout
            Application.SetSystemVariable("TILEMODE",0);
            acDoc.Editor.SwitchToPaperSpace();

            // Omitted code for creating a polyline in model space to focus on (acObj) ...
            // Omitted code for creating a new layout ...

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

        // This is the part that shows in AutoCAD but doesn't save
        acDoc.Editor.Command("._VIEWPORTS","Fit");
        acDoc.Editor.Command("._MSPACE");
        acDoc.Editor.Command("._ZOOM","_O",SelectionSet.FromObjectIds(new ObjectId[] { acObj.ObjectId }),"");
        acDoc.Editor.Command("._PSPACE");
        acDoc.Editor.Command("._ZOOM","E");

        acCurDb.SaveAs("OutputDrawing.dwg",DwgVersion.AC1027);
    }
    catch (Exception ex)
    {
        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
    }
}

解决方法

我已经直接与 Autodesk 就此进行了交谈,看起来我的问题是我删除旧视口并创建新视口的方式。他们按预期对我的代码进行了以下更改

[CommandMethod("CreateViewport")]
public static void CreateViewport()
{
    // Get the current document and database,and start a transaction
    Document acDoc = Application.DocumentManager.MdiActiveDocument;
    Database acCurDb = acDoc.Database;
    try
    {
        Entity acObj = null;
        using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
        {
            // Open the Block table for read
            BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,OpenMode.ForRead) as BlockTable;
            // Open the Block table record Model space for write
            BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],OpenMode.ForWrite) as BlockTableRecord;
            // Draw the desired viewport on the default layer
            // Create a circle that is at 2,3 with a radius of 4.25
            Circle acCirc = new Circle();
            acCirc.SetDatabaseDefaults();
            acCirc.Center = new Point3d(2,3,0);
            acCirc.Radius = 4.25;
            acObj = acCirc;
            acBlkTblRec.AppendEntity(acObj);
            acTrans.AddNewlyCreatedDBObject(acObj,true);
            // Set current layer to 0
            acCurDb.Clayer = acObj.LayerId;
            // Switch to the previous Paper space layout
            Application.SetSystemVariable("TILEMODE",0);
            acDoc.Editor.SwitchToPaperSpace();
            // List Layouts
            DBDictionary layoutDic = acTrans.GetObject(acCurDb.LayoutDictionaryId,OpenMode.ForRead,false) as DBDictionary;
            LayoutManager acLayoutMgr = LayoutManager.Current;
            Layout acLayout = null;
            foreach (DBDictionaryEntry entry in layoutDic)
            {
                ObjectId layoutId = entry.Value;
                Layout currentLayout = acTrans.GetObject(layoutId,OpenMode.ForRead) as Layout;
                if (currentLayout.LayoutName == "Layout1")
                {
                    acLayout = acTrans.GetObject(layoutId,OpenMode.ForWrite) as Layout;
                    // Delete any existing view ports
                    ObjectIdCollection acViewports = acLayout.GetViewports();
                    foreach (ObjectId acViewportID in acViewports)
                    {
                        Viewport acVport = acTrans.GetObject(acViewportID,OpenMode.ForWrite) as Viewport;
                        acVport.Erase();
                    }
                    //create a blank viewport,we need at least one viewport
                    var btr = (BlockTableRecord)acTrans.GetObject(acLayout.BlockTableRecordId,OpenMode.ForWrite);
                    var vp = new Viewport();
                    btr.AppendEntity(vp);
                    acTrans.AddNewlyCreatedDBObject(vp,true);
                    break;
                }
            }
            // If layout wasn't found,make it
            if (acLayout == null)
            {
                ObjectId objID = acLayoutMgr.CreateLayout("Layout1");
                acLayout = acTrans.GetObject(objID,OpenMode.ForWrite) as Layout;
            }

            // Set the layout current if it is not already
            if (acLayout.TabSelected == false)
            {
                acLayoutMgr.CurrentLayout = acLayout.LayoutName;
            }
            PlotSettings acPlSet = new PlotSettings(acLayout.ModelType);
            acPlSet.CopyFrom(acLayout);
            // Update the PlotConfigurationName property of the PlotSettings object
            PlotSettingsValidator acPlSetVdr = PlotSettingsValidator.Current;
            acPlSetVdr.SetPlotConfigurationName(acPlSet,"DWG To PDF.pc3","ANSI_B_(11.00_x_17.00_Inches)");
            // Zoom to show the whole paper
            acPlSetVdr.SetZoomToPaperOnUpdate(acPlSet,true);
            // Update the layout
            if (!acLayout.IsWriteEnabled)
            {
                acLayout.UpgradeOpen();
            }                    

            acLayout.CopyFrom(acPlSet);
            // Save the new objects to the database
            acTrans.Commit();
        }
        acDoc.Editor.Command("._VIEWPORTS","Fit");
        acDoc.Editor.Command("._MSPACE");
        acDoc.Editor.Command("._ZOOM","_O",SelectionSet.FromObjectIds(new ObjectId[] { acObj.ObjectId }),"");
        acDoc.Editor.Command("._PSPACE");
        acDoc.Editor.Command("._ZOOM","E");
        string dwgPath = @"D:\Work\Cases\8360\OutputDrawing_.dwg";
        dwgPath = dwgPath.Insert(dwgPath.IndexOf(".dwg"),DateTime.Now.ToString("yyyyMMddHHmmssffff"));
        acCurDb.SaveAs(dwgPath,DwgVersion.AC1032);
    }
    catch (System.Exception ex)
    {
        Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
    }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...