.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Turning on view is causing sporadic errors

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
carl3ZPF6
429 Views, 7 Replies

Turning on view is causing sporadic errors

I have written the following C# code that takes user input of an integer, then plots views in sheets corresponding to polyines in the model space on different layers. For example in the attached file when 3 is input, then 3 views are inserted on sheet 1, sheet 2, and sheet 3. I have the viewports inserting correctly per the code, but when I un-comment the vp.on line I get the error: Autodesk.AutoCAD.Runtime.Exception: 'eNotInPaperspace'. But in the drawing I can easily turn these views on no problem, any ideas here?

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;

namespace AutoCADExtents
{
    public class Commands
    {
        [CommandMethod("POLYEXTENTS")]
        public void GetPolylineExtents()
        {
            // Get the current document and database
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            // Start a transaction
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // Open the Block table for read
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

                // Get the active document and editor
                Editor ed = doc.Editor;

                // Prompt user for the number of layers/views
                PromptIntegerOptions numLayersPromptOptions = new PromptIntegerOptions("\nEnter number of layers/views to create: ");
                numLayersPromptOptions.AllowNegative = false;
                numLayersPromptOptions.AllowZero = false;
                PromptIntegerResult numLayersPromptResult = ed.GetInteger(numLayersPromptOptions);

                if (numLayersPromptResult.Status != PromptStatus.OK)
                {
                    ed.WriteMessage("\nInvalid input or user cancelled.");
                    return;
                }

                int numLayers = numLayersPromptResult.Value;

                // Open the LayoutManager
                LayoutManager layoutManager = LayoutManager.Current;

                for (int i = 1; i <= numLayers; i++)
                {
                    string sheetName = "Sheet " + i;

                    // Get or create the layout
                    Layout layout = tr.GetObject(layoutManager.GetLayoutId(sheetName), OpenMode.ForWrite) as Layout;

                    // Create or get the first viewport in the layout
                    Viewport vp = GetOrCreateViewport(tr, layout);

                    // Set the viewport properties based on overall extents and layout size
                    SetViewportProperties(tr, layout, vp, bt, ed, i);
                 

                    // Inform user
                    ed.WriteMessage($"\nViewport created and adjusted successfully in '{sheetName}'.");
                }

                tr.Commit(); // Commit the transaction
            }
        }

        private Viewport GetOrCreateViewport(Transaction tr, Layout layout)
        {
            Viewport vp = null;

            // Open the BlockTableRecord for layout
            BlockTableRecord layoutRecord = tr.GetObject(layout.BlockTableRecordId, OpenMode.ForWrite) as BlockTableRecord;

            // Remove existing viewport if any
            foreach (ObjectId objId in layoutRecord)
            {
                if (objId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Viewport))))
                {
                    vp = tr.GetObject(objId, OpenMode.ForWrite) as Viewport;
                    if (vp != null)
                    {
                        vp.Erase();
                        break;
                    }
                }
            }

            // Create a new viewport
            vp = new Viewport();
            layoutRecord.AppendEntity(vp);
            tr.AddNewlyCreatedDBObject(vp, true);

            return vp;
        }

        private void SetViewportProperties(Transaction tr, Layout layout, Viewport vp, BlockTable bt, Editor ed, int layerNumber)
        {
            // Get the overall extents of the entities in model space for the specified layer number
            Extents3d overallExtents = GetOverallExtents(tr, bt, layerNumber);

            // Check if valid extents were found
            if (overallExtents.MinPoint != Point3d.Origin && overallExtents.MaxPoint != Point3d.Origin)
            {
                // Calculate the center of the extents in model space
                Point3d centerPointModelSpace = overallExtents.MinPoint + ((overallExtents.MaxPoint - overallExtents.MinPoint) / 2.0);

                // Calculate the layout dimensions in inches (convert mm to inches)
                double layoutWidth = 20.3867;
                double layoutLength = 25.2982;

                // Determine scale factors based on layout dimensions
                double scaleHeight = layoutWidth / (overallExtents.MaxPoint.Y - overallExtents.MinPoint.Y);
                double scaleWidth = layoutLength / (overallExtents.MaxPoint.X - overallExtents.MinPoint.X);

                // Choose the smaller scale factor to fit either width or height
                double scaleFactor = Math.Min(scaleHeight, scaleWidth);

                // Set the viewport center in paper space
                vp.CenterPoint = new Point3d(13.3056, 13.3432, 0.0);

                // Set the viewport size based on scale factor
                vp.Height = (overallExtents.MaxPoint.Y - overallExtents.MinPoint.Y) * scaleFactor;
                vp.Width = (overallExtents.MaxPoint.X - overallExtents.MinPoint.X) * scaleFactor;

                // Set the view center in model space
                vp.ViewCenter = new Point2d(centerPointModelSpace.X, centerPointModelSpace.Y);

                // Set the view scale (optional)
                vp.CustomScale = scaleFactor;

                //vp.On = true;



            }
            else
            {
                // No valid extents found
                ed.WriteMessage($"\nNo valid extents found for Layer {layerNumber}. Viewport not adjusted.");
            }
        }

        private Extents3d GetOverallExtents(Transaction tr, BlockTable bt, int layerNumber)
        {
            // Initialize extents
            Extents3d overallExtents = new Extents3d();

            // Open the Block table record Model space for read
            BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

            // Iterate through the entities in Model space
            foreach (ObjectId objId in btr)
            {
                Entity ent = tr.GetObject(objId, OpenMode.ForRead) as Entity;

                // Check if the entity is a Polyline and on the specified layer
                if (ent != null && ent is Polyline && ent.Layer == $"{layerNumber}")
                {
                    Polyline pline = (Polyline)ent;

                    // Get the extents of the polyline
                    Extents3d extents = pline.GeometricExtents;

                    // Extend overall extents
                    overallExtents.AddExtents(extents);
                }
            }

            return overallExtents;
        }
    }
}

 

 Also tried to write a second code that turns on all vp's but this also returned the same error.

Tags (2)
7 REPLIES 7
Message 2 of 8
_gile
in reply to: carl3ZPF6

Hi,

Each layout has its own viewport which is not a floating viewport and must not be erased. The Number property of this viewport is always 1, so, you should replace:

if (vp != null)
{
    vp.Erase();
    break;
}

with:

if (vp != null && vp.Number != 1)
{
    vp.Erase();
    break;
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 8
carl3ZPF6
in reply to: carl3ZPF6

@_gileI have done as you said and I still get the same error at line 131, Autodesk.AutoCAD.Runtime.Exception: 'eNotInPaperspace' do I need to move this somewhere else in the routine?

Message 4 of 8
_gile
in reply to: carl3ZPF6

Seeing the error message (eNotInPaperSpace), I'd try to make the newly created Layout current before calling vp.On = true;

 

 

LayoutManager.CurrentLayout = sheetName;

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 8
carl3ZPF6
in reply to: carl3ZPF6

@_gileThis is my best attempt:

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;

namespace AutoCADExtents
{
    public class Commands
    {
        [CommandMethod("POLYEXTENTS")]
        public void GetPolylineExtents()
        {
            // Get the current document and database
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            // Start a transaction
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // Open the Block table for read
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

                // Get the active document and editor
                Editor ed = doc.Editor;

                // Prompt user for the number of layers/views
                PromptIntegerOptions numLayersPromptOptions = new PromptIntegerOptions("\nEnter number of layers/views to create: ");
                numLayersPromptOptions.AllowNegative = false;
                numLayersPromptOptions.AllowZero = false;
                PromptIntegerResult numLayersPromptResult = ed.GetInteger(numLayersPromptOptions);

                if (numLayersPromptResult.Status != PromptStatus.OK)
                {
                    ed.WriteMessage("\nInvalid input or user cancelled.");
                    return;
                }

                int numLayers = numLayersPromptResult.Value;

                // Open the LayoutManager
                LayoutManager layoutManager = LayoutManager.Current;

                for (int i = 1; i <= numLayers; i++)
                {
                    string sheetName = "Sheet " + i;

                    // Get or create the layout
                    Layout layout = tr.GetObject(layoutManager.GetLayoutId(sheetName), OpenMode.ForWrite) as Layout;

                    // Create or get the first viewport in the layout
                    Viewport vp = GetOrCreateViewport(tr, layout);

                    // Set the viewport properties based on overall extents and layout size
                    SetViewportProperties(tr, layout, vp, bt, ed, i, sheetName);

                    // Inform user
                    ed.WriteMessage($"\nViewport created and adjusted successfully in '{sheetName}'.");
                }

                tr.Commit(); // Commit the transaction
            }
        }

        private Viewport GetOrCreateViewport(Transaction tr, Layout layout)
        {
            Viewport vp = null;

            // Open the BlockTableRecord for layout
            BlockTableRecord layoutRecord = tr.GetObject(layout.BlockTableRecordId, OpenMode.ForWrite) as BlockTableRecord;

            // Check if a viewport already exists
            foreach (ObjectId objId in layoutRecord)
            {
                if (objId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Viewport))))
                {
                    vp = tr.GetObject(objId, OpenMode.ForWrite) as Viewport;
                    if (vp != null)
                    {
                        // If viewport exists and is not the first viewport (optional condition), erase it
                        if (vp.Number != 1)
                        {
                            vp.Erase();
                            vp = null; // Set vp to null to create a new one
                            break;
                        }
                    }
                }
            }

            // If no valid viewport found, create a new one
            if (vp == null)
            {
                vp = new Viewport();
                layoutRecord.AppendEntity(vp);
                tr.AddNewlyCreatedDBObject(vp, true);
            }

            return vp;
        }

        private void SetViewportProperties(Transaction tr, Layout layout, Viewport vp, BlockTable bt, Editor ed, int layerNumber, string sheetName)
        {
            // Get the overall extents of the entities in model space for the specified layer number
            Extents3d overallExtents = GetOverallExtents(tr, bt, layerNumber);

            // Check if valid extents were found
            if (overallExtents.MinPoint != Point3d.Origin && overallExtents.MaxPoint != Point3d.Origin)
            {
                // Calculate the center of the extents in model space
                Point3d centerPointModelSpace = overallExtents.MinPoint + ((overallExtents.MaxPoint - overallExtents.MinPoint) / 2.0);

                // Calculate the layout dimensions in inches (convert mm to inches)
                double layoutWidth = 20.3867;
                double layoutLength = 25.2982;

                // Determine scale factors based on layout dimensions
                double scaleHeight = layoutWidth / (overallExtents.MaxPoint.Y - overallExtents.MinPoint.Y);
                double scaleWidth = layoutLength / (overallExtents.MaxPoint.X - overallExtents.MinPoint.X);

                // Choose the smaller scale factor to fit either width or height
                double scaleFactor = Math.Min(scaleHeight, scaleWidth);

                // Set the viewport center in paper space
                vp.CenterPoint = new Point3d(13.3056, 13.3432, 0.0);

                // Set the viewport size based on scale factor
                vp.Height = (overallExtents.MaxPoint.Y - overallExtents.MinPoint.Y) * scaleFactor;
                vp.Width = (overallExtents.MaxPoint.X - overallExtents.MinPoint.X) * scaleFactor;

                // Set the view center in model space
                vp.ViewCenter = new Point2d(centerPointModelSpace.X, centerPointModelSpace.Y);

                // Set the view scale (optional)
                vp.CustomScale = scaleFactor;

                // Inform user
                ed.WriteMessage($"\nViewport properties set for '{sheetName}'.");

                // Ensure that the layout switch happens after viewport properties are set
                SetCurrentLayoutTab(sheetName);
            }
            else
            {
                // No valid extents found
                ed.WriteMessage($"\nNo valid extents found for Layer {layerNumber}. Viewport not adjusted.");
            }
        }

        private Extents3d GetOverallExtents(Transaction tr, BlockTable bt, int layerNumber)
        {
            // Initialize extents
            Extents3d overallExtents = new Extents3d();

            // Open the Block table record Model space for read
            BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

            // Iterate through the entities in Model space
            foreach (ObjectId objId in btr)
            {
                Entity ent = tr.GetObject(objId, OpenMode.ForRead) as Entity;

                // Check if the entity is a Polyline and on the specified layer
                if (ent != null && ent is Polyline && ent.Layer == $"{layerNumber}")
                {
                    Polyline pline = (Polyline)ent;

                    // Get the extents of the polyline
                    Extents3d extents = pline.GeometricExtents;

                    // Extend overall extents
                    overallExtents.AddExtents(extents);
                }
            }

            return overallExtents;
        }

        public static void SetCurrentLayoutTab(string tab)
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;

            using (DocumentLock lk = acDoc.LockDocument())
            {
                // Start a separate transaction for setting the current layout
                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    try
                    {
                        LayoutManager.Current.CurrentLayout = tab;
                        acTrans.Commit();
                    }
                    catch
                    {
                        acTrans.Abort();
                    }
                }
            }
        }
    }
}

 This runs fine with user input 1 and 2, but crashes with user input 3, which is even weirder than the original behavior

Message 6 of 8
norman.yuan
in reply to: carl3ZPF6

I would try to set the layout current before doing anything:

 

                // Open the LayoutManager
                LayoutManager layoutManager = LayoutManager.Current;

                for (int i = 1; i <= numLayers; i++)
                {
                    string sheetName = "Sheet " + i;
                    layoutManager.CurrentLayout = sheetName
                    // Get or create the layout
                    Layout layout = tr.GetObject(layoutManager.GetLayoutId(sheetName), OpenMode.ForWrite) as Layout;

                    // Create or get the first viewport in the layout
                    Viewport vp = GetOrCreateViewport(tr, layout);

                    // Set the viewport properties based on overall extents and layout size
                    SetViewportProperties(tr, layout, vp, bt, ed, i, sheetName);

                    // Inform user
                    ed.WriteMessage($"\nViewport created and adjusted successfully in '{sheetName}'.");
                }

 

In your SetCurrentLayoutTab() method, there is no need to lock the document, nor start a Transaction.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 7 of 8
carl3ZPF6
in reply to: norman.yuan

@norman.yuansee my code below, this results in no output, messages in the editor say views were added and adjusted but there is nothing:

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;

namespace AutoCADExtents
{
    public class Commands
    {
        [CommandMethod("POLYEXTENTS")]
        public void GetPolylineExtents()
        {
            // Get the current document and database
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            // Start a transaction
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // Open the Block table for read
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

                // Get the active document and editor
                Editor ed = doc.Editor;

                // Prompt user for the number of layers/views
                PromptIntegerOptions numLayersPromptOptions = new PromptIntegerOptions("\nEnter number of layers/views to create: ");
                numLayersPromptOptions.AllowNegative = false;
                numLayersPromptOptions.AllowZero = false;
                PromptIntegerResult numLayersPromptResult = ed.GetInteger(numLayersPromptOptions);

                if (numLayersPromptResult.Status != PromptStatus.OK)
                {
                    ed.WriteMessage("\nInvalid input or user cancelled.");
                    return;
                }

                int numLayers = numLayersPromptResult.Value;

                // Open the LayoutManager
                LayoutManager layoutManager = LayoutManager.Current;

                for (int i = 1; i <= numLayers; i++)
                {
                    string sheetName = "Sheet " + i;
                    layoutManager.CurrentLayout = sheetName;
                    // Get or create the layout
                    Layout layout = tr.GetObject(layoutManager.GetLayoutId(sheetName), OpenMode.ForWrite) as Layout;

                    // Create or get the first viewport in the layout
                    Viewport vp = GetOrCreateViewport(tr, layout);

                    // Set the viewport properties based on overall extents and layout size
                    SetViewportProperties(tr, layout, vp, bt, ed, i, sheetName);
                    vp.On = true;
                    // Inform user
                    ed.WriteMessage($"\nViewport created and adjusted successfully in '{sheetName}'.");
                }

                tr.Commit(); // Commit the transaction
            }
        }

        private Viewport GetOrCreateViewport(Transaction tr, Layout layout)
        {
            Viewport vp = null;

            // Open the BlockTableRecord for layout
            BlockTableRecord layoutRecord = tr.GetObject(layout.BlockTableRecordId, OpenMode.ForWrite) as BlockTableRecord;

            // Check if a viewport already exists
            foreach (ObjectId objId in layoutRecord)
            {
                if (objId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Viewport))))
                {
                    vp = tr.GetObject(objId, OpenMode.ForWrite) as Viewport;
                    if (vp != null)
                    {
                        // If viewport exists and is not the first viewport (optional condition), erase it
                        if (vp.Number != 1)
                        {
                            vp.Erase();
                            vp = null; // Set vp to null to create a new one
                            break;
                        }
                    }
                }
            }

            // If no valid viewport found, create a new one
            if (vp == null)
            {
                vp = new Viewport();
                layoutRecord.AppendEntity(vp);
                tr.AddNewlyCreatedDBObject(vp, true);
            }

            return vp;
        }

        private void SetViewportProperties(Transaction tr, Layout layout, Viewport vp, BlockTable bt, Editor ed, int layerNumber, string sheetName)
        {
            // Get the overall extents of the entities in model space for the specified layer number
            Extents3d overallExtents = GetOverallExtents(tr, bt, layerNumber);

            // Check if valid extents were found
            if (overallExtents.MinPoint != Point3d.Origin && overallExtents.MaxPoint != Point3d.Origin)
            {
                // Calculate the center of the extents in model space
                Point3d centerPointModelSpace = overallExtents.MinPoint + ((overallExtents.MaxPoint - overallExtents.MinPoint) / 2.0);

                // Calculate the layout dimensions in inches (convert mm to inches)
                double layoutWidth = 20.3867;
                double layoutLength = 25.2982;

                // Determine scale factors based on layout dimensions
                double scaleHeight = layoutWidth / (overallExtents.MaxPoint.Y - overallExtents.MinPoint.Y);
                double scaleWidth = layoutLength / (overallExtents.MaxPoint.X - overallExtents.MinPoint.X);

                // Choose the smaller scale factor to fit either width or height
                double scaleFactor = Math.Min(scaleHeight, scaleWidth);

                // Set the viewport center in paper space
                vp.CenterPoint = new Point3d(13.3056, 13.3432, 0.0);

                // Set the viewport size based on scale factor
                vp.Height = (overallExtents.MaxPoint.Y - overallExtents.MinPoint.Y) * scaleFactor;
                vp.Width = (overallExtents.MaxPoint.X - overallExtents.MinPoint.X) * scaleFactor;

                // Set the view center in model space
                vp.ViewCenter = new Point2d(centerPointModelSpace.X, centerPointModelSpace.Y);

                // Set the view scale (optional)
                vp.CustomScale = scaleFactor;

                // Inform user
                ed.WriteMessage($"\nViewport properties set for '{sheetName}'.");

                // Ensure that the layout switch happens after viewport properties are set

               
            }
            else
            {
                // No valid extents found
                ed.WriteMessage($"\nNo valid extents found for Layer {layerNumber}. Viewport not adjusted.");
            }
        }

        private Extents3d GetOverallExtents(Transaction tr, BlockTable bt, int layerNumber)
        {
            // Initialize extents
            Extents3d overallExtents = new Extents3d();

            // Open the Block table record Model space for read
            BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

            // Iterate through the entities in Model space
            foreach (ObjectId objId in btr)
            {
                Entity ent = tr.GetObject(objId, OpenMode.ForRead) as Entity;

                // Check if the entity is a Polyline and on the specified layer
                if (ent != null && ent is Polyline && ent.Layer == $"{layerNumber}")
                {
                    Polyline pline = (Polyline)ent;

                    // Get the extents of the polyline
                    Extents3d extents = pline.GeometricExtents;

                    // Extend overall extents
                    overallExtents.AddExtents(extents);
                }
            }

            return overallExtents;
        }


    }
}
Message 8 of 8
carl3ZPF6
in reply to: carl3ZPF6

@norman.yuan @_gile After some playing around I was able to fix this with a separate function, see below. Not sure why I couldnt do this in the loop.

public void TurnOnAllViewports()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        // Get the layout dictionary
        DBDictionary layoutDict = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);

        foreach (DBDictionaryEntry layoutEntry in layoutDict)
        {
            // Get each layout
            Layout layout = (Layout)tr.GetObject(layoutEntry.Value, OpenMode.ForRead);

            // Skip the Model layout
            if (layout.LayoutName == "Model")
                continue;

            // Switch to the layout
            ed.Command("_.layout", "Set", layout.LayoutName);

            // Get the block table record for the layout
            BlockTableRecord btr = (BlockTableRecord)tr.GetObject(layout.BlockTableRecordId, OpenMode.ForRead);

            foreach (ObjectId objId in btr)
            {
                // Check if the object is a viewport
                if (objId.ObjectClass == RXObject.GetClass(typeof(Viewport)))
                {
                    Viewport vp = (Viewport)tr.GetObject(objId, OpenMode.ForWrite);

                    // Turn on the viewport
                    vp.On = true;
                }
            }
        }

        // Commit the transaction
        tr.Commit();
    }

    // Refresh the display
    Application.UpdateScreen();
}

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report