Viewport.CustomScale returns extra scale value of 1 in all layouts

Viewport.CustomScale returns extra scale value of 1 in all layouts

Gauzdx
Contributor Contributor
450 Views
3 Replies
Message 1 of 4

Viewport.CustomScale returns extra scale value of 1 in all layouts

Gauzdx
Contributor
Contributor

Hello,

I am trying to loop through all layouts in the drawing and get viewports' custom scale that are under them. I am able to get the value but confused with the output I am getting. There are two rows in my extract that tells me two scales of the viewport. I created 3 viewports in Layout1 and 1 viewport in Layout2. But I am not sure why there is an extra viewport showing up with scale as 1 in both layout 1 & 2 (see line 3 and 11 in the picture). I am filtering the model space viewport in my code. 

 

Gauzdx_0-1707978278383.png

 

 

 

public static void GetLayouts(Transaction tr, Database db, BlockTable bt, string dataOutputPath, string dwgName)
{
	StringBuilder csvLayoutList = new StringBuilder();
	csvLayoutList.AppendLine("HeaderToBeEditedLater");

	//Open the Layout dictionary
	DBDictionary layoutDict = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;

	//Iterate through each layout
	foreach (DBDictionaryEntry layoutentry in layoutDict)
	{
		ObjectId layoutId = layoutentry.Value;
		Layout layout = tr.GetObject(layoutId, OpenMode.ForRead) as Layout;

		if (layout.LayoutName.Equals("Model", StringComparison.OrdinalIgnoreCase))
		{
			continue;
		}
		//csvLayoutList.AppendLine(layout.LayoutName);

		BlockTableRecord layoutbtr = tr.GetObject(layout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
		foreach (ObjectId layoutentId in layoutbtr)
		{
			AcadEntity layent = tr.GetObject(layoutentId, OpenMode.ForRead) as AcadEntity;
			if (layent != null && layent is Viewport)
			{
				Viewport viewport = layent as Viewport;
				csvLayoutList.AppendLine(layout.LayoutName);
				csvLayoutList.AppendLine($"Viewport Scale: {viewport.CustomScale}");
			}
		}
	}
	File.WriteAllText(dataOutputPath + "\\LayoutList.csv", csvLayoutList.ToString());
}

 

 

 

 

0 Likes
Accepted solutions (1)
451 Views
3 Replies
Replies (3)
Message 2 of 4

_gile
Consultant
Consultant

Hi,

In addition to floating viewports, each layout has its own viewport (which Number property is always equal to 1).

Try replacing:

if (layent != null && layent is Viewport)
{
    Viewport viewport = layent as Viewport;
    csvLayoutList.AppendLine(layout.LayoutName);
    csvLayoutList.AppendLine($"Viewport Scale: {viewport.CustomScale}");
}

with:

if (layent != null && layent is Viewport viewport && viewport.Number != 1)
{
    csvLayoutList.AppendLine(layout.LayoutName);
    csvLayoutList.AppendLine($"Viewport Scale: {viewport.CustomScale}");
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 4

Gauzdx
Contributor
Contributor

@_gile I retrieved the viewport number but it is still confusing in Layout2. Both viewport numbers are -1 (inactive). I want to filter out the one that has scale 1. 

Gauzdx_0-1707980298984.png

 

0 Likes
Message 4 of 4

_gile
Consultant
Consultant
Accepted solution

This is because the layout have never been active before.

You can use the LayoutManager to activate each layout before processing it. To be able to use the Layoutmanager, the processed Database have to be the working database. So, if you call this method on a 'side database' you have to set it as working database. This can be done using the @ActivistInvestor's WorkingDatabase class.

        public static string GetLayouts(Transaction tr, Database db)
        {
            var layoutManager = LayoutManager.Current;
            string currentLayout = layoutManager.CurrentLayout;
            var stringBuilder = new StringBuilder();
            var layoutDictionary = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
            foreach (DBDictionaryEntry entry in layoutDictionary)
            {
                if (entry.Value == SymbolUtilityServices.GetBlockModelSpaceId(db))
                    continue;
                var layout = (Layout)tr.GetObject(entry.Value, OpenMode.ForRead);
                layoutManager.CurrentLayout = layout.LayoutName;
                var layoutBtr = (BlockTableRecord)tr.GetObject(layout.BlockTableRecordId, OpenMode.ForRead);
                foreach (ObjectId id in layoutBtr)
                {
                    if (id.ObjectClass.Name == "AcDbViewport")
                    {
                        var viewport = (Viewport)tr.GetObject(id, OpenMode.ForRead);
                        if (viewport.Number != 1)
                        {
                            stringBuilder.AppendLine(layout.LayoutName);
                            stringBuilder.AppendLine($"Viewport Scale: {viewport.CustomScale}");
                        }
                    }
                }
            }
            layoutManager.CurrentLayout = currentLayout;
            return stringBuilder.ToString();
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes