How to fit Entities to Layout's paper size?

Anonymous

How to fit Entities to Layout's paper size?

Anonymous
Not applicable

I've managed to copy Entities from Model Space to Paper Space programmatically (without viewport). New copied objects appears far away from my paper list. So, I need to fit the whole set of copied Entities to paper boundaries and change the scale of Entities according to its extents and paper size. I couldnt find a correct way to do this in C#, hope for your help.

 

Here is my code:

 [CommandMethod("test")]
 public static void copytolist()
 {
 	Document doc = Application.DocumentManager.MdiActiveDocument;
 	Editor ed = doc.Editor;
 	Database db = doc.Database;
	//start transaction
	Transaction tr = doc.TransactionManager.StartTransaction();
 	using (tr)
 	{
	//get the crossing windows coordinates:
        PromptPointOptions ppo = new PromptPointOptions("\nFirst corner: ");
        PromptPointResult ppr = ed.GetPoint(ppo);
        if (ppr.Status != PromptStatus.OK) return;
        PromptCornerOptions pco = new PromptCornerOptions("\nOther corner: ", ppr.Value);
        PromptPointResult pcr = ed.GetCorner(pco);
        if (pcr.Status != PromptStatus.OK) return;
        Point3d p1 = ppr.Value;
        Point3d p2 = pcr.Value;
        if (p1.X == p2.X || p1.Y == p2.Y)
            {
                ed.WriteMessage("\nInvalid coordinate specification");
                return;
            }

        //crossing windows from coordinates:
        PromptSelectionResult res = ed.SelectCrossingWindow(p1, p2);
        if (res.Status != PromptStatus.OK)
            return;
        SelectionSet sset = res.Value;
        if (sset.Count == 0)
             return;

                // take all the entities from the cross selection:
                ObjectIdCollection ids = new ObjectIdCollection();
                foreach (SelectedObject obj in sset)
                    ids.Add(obj.ObjectId);

		//gettin and settin desired layout and clone objects
		LayoutManager acLayoutMgr = LayoutManager.Current;
		DBDictionary layoutDic = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForWrite, false) as DBDictionary;
		foreach (DBDictionaryEntry entry in layoutDic)
 		{
 			ObjectId layoutId = entry.Value;
 			Layout layout = tr.GetObject(layoutId, OpenMode.ForWrite) as Layout;

 			if (layout.LayoutName == "test")
 			{
 				acLayoutMgr.CurrentLayout=layout.LayoutName;
 				BlockTableRecord btr = (BlockTableRecord)tr.GetObject(layout.BlockTableRecordId, OpenMode.ForWrite);
				IdMapping acIdMap = new IdMapping();
				//verify if there are entities to be copied:
                if (ids.Count > 0)
                        {
                            ed.WriteMessage("\nYES, there are entities to be copied: {0} entities!", ids.Count);
                            db.DeepCloneObjects(ids, btr.ObjectId, acIdMap, false);
                        }
                else
                        ed.WriteMessage("\nNO, there are no entities to be copied!");
				//loop through the newly created (clone) objects
				foreach (ObjectId clone in ids)
                	{
                		IdPair pair1 = acIdMap[clone];
                		Entity ent = tr.GetObject(pair1.Value, OpenMode.ForWrite) as Entity;
						//now i need to move new objects to fit my list and change scale of objects, depending from its size and list size
						////////////////////////////////////////////////////////////////
                	}
 			}
 		}
		tr.Commit();
	}
 }

Also, DWG file with drawing and list examples is attached.

Thanks in advance!

0 Likes
Reply
Accepted solutions (1)
1,246 Views
5 Replies
Replies (5)

Alexander.Rivilis
Mentor
Mentor

@Anonymous

As I see you post this question also in http://adn-cis.org/forum/index.php?topic=8508

Solution was provided in that topic.

    using Autodesk.AutoCAD.Runtime;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.Geometry;
    using Autodesk.AutoCAD.EditorInput;
     
    // This line is not mandatory, but improves loading performances
    [assembly: CommandClass(typeof(ZoomViewport.Utils))]
     
    namespace ZoomViewport
    {
     
      public class Utils
      {
        [CommandMethod("TestZoom")]
        public void TestZoom()
        {
          Document doc = Application.DocumentManager.MdiActiveDocument;
          if (doc == null) return;
          Editor ed = doc.Editor;
          Database db = doc.Database;
          PromptSelectionResult rs = ed.GetSelection();
          if (rs.Status != PromptStatus.OK) return;
          ObjectIdCollection ids = new ObjectIdCollection(rs.Value.GetObjectIds());
          test(ref ids);
        }
     
        public static void test(ref ObjectIdCollection ids)
        {
          Document doc = Application.DocumentManager.MdiActiveDocument;
          Editor ed = doc.Editor;
          Database db = doc.Database;
     
          using (Transaction tr = doc.TransactionManager.StartTransaction())
          {
            Extents3d ext = new Extents3d();
            foreach (ObjectId id in ids)
            {
              var ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
              if (ent != null)
              {
                ext.AddExtents(ent.GeometricExtents);
              }
            }
     
            LayoutManager layman = LayoutManager.Current;
     
            DBDictionary layoutDic = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
     
            double mScrRatio;
            // Проходимся по всем листам (модель пропускаем)
            foreach (DBDictionaryEntry entry in layoutDic)
            {
              Layout layout = tr.GetObject(entry.Value, OpenMode.ForRead) as Layout;
     
              if (!layout.ModelType) // Это не модель
              {
                layman.CurrentLayout = layout.LayoutName;
                ObjectIdCollection idsVports = layout.GetViewports();
                // Проходимся по всем видовым экранам (кроме основного видового экрана листа)
                for (int i = 1; i < idsVports.Count; i++)
                {
                  Viewport vp = (Viewport)tr.GetObject(idsVports[i], OpenMode.ForRead);
                  mScrRatio = (vp.Width / vp.Height);
                  // prepare Matrix for DCS to WCS transformation
                  Matrix3d matWCS2DCS;
                  matWCS2DCS = Matrix3d.PlaneToWorld(vp.ViewDirection);
                  matWCS2DCS = Matrix3d.Displacement(vp.ViewTarget - Point3d.Origin) * matWCS2DCS;
                  matWCS2DCS = Matrix3d.Rotation(-vp.TwistAngle, vp.ViewDirection, vp.ViewTarget) * matWCS2DCS;
                  matWCS2DCS = matWCS2DCS.Inverse();
                  ext.TransformBy(matWCS2DCS);
                  // width of the extents in current view
                  double mWidth;
                  mWidth = (ext.MaxPoint.X - ext.MinPoint.X);
                  // height of the extents in current view
                  double mHeight;
                  mHeight = (ext.MaxPoint.Y - ext.MinPoint.Y);
                  // get the view center point
                  Point2d mCentPt = new Point2d(
                    ((ext.MaxPoint.X + ext.MinPoint.X) * 0.5),
                    ((ext.MaxPoint.Y + ext.MinPoint.Y) * 0.5));
                  vp.UpgradeOpen();
                  if (mWidth > (mHeight * mScrRatio))  mHeight = mWidth / mScrRatio;
                  vp.ViewHeight = mHeight * 1.01; 
                  // set the view center
                  vp.ViewCenter = mCentPt;
                  vp.Visible = true;
                  vp.On = true;
                  vp.UpdateDisplay();
                  doc.Editor.SwitchToModelSpace();
                  Application.SetSystemVariable("CVPORT", vp.Number);
                }
              }
            }
            tr.Commit();
          }
        }
      }
    }

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes

Anonymous
Not applicable

No, its absolutely different question there. From your link entities are in viewport. My question here is:

how to do the same without viewport. Just copy to paper and make it fit.

0 Likes

Alexander.Rivilis
Mentor
Mentor
Accepted solution

From this topic: http://adn-cis.org/forum/index.php?topic=8510.msg32169#msg32169

 

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

// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(CloneToLayout.Utils))]

namespace CloneToLayout
{

  public class Utils
  {
    [CommandMethod("CloneToLayout")]
    public void CloneToLayout()
    {
      Document doc = Application.DocumentManager.MdiActiveDocument;
      if (doc == null) return;
      Editor ed = doc.Editor;
      Database db = doc.Database;
      PromptSelectionResult rs = ed.GetSelection();
      if (rs.Status != PromptStatus.OK) return;
      ObjectIdCollection ids = new ObjectIdCollection(rs.Value.GetObjectIds());
      testClone(ref ids);
    }

    public static void testClone(ref ObjectIdCollection ids)
    {
      Document doc = Application.DocumentManager.MdiActiveDocument;
      Editor ed = doc.Editor;
      Database db = doc.Database;
      Extents3d ext = new Extents3d();
      using (Transaction tr = doc.TransactionManager.StartTransaction())
      {
        foreach (ObjectId id in ids)
        {
          Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
          if (ent != null) {
            ext.AddExtents(ent.GeometricExtents);
          }
        }

        // Центральная точка габаритов выбранных примитивов.
        Point3d modelCenter = ext.MinPoint + (ext.MaxPoint - ext.MinPoint) * 0.5;
        double modelHeight = ext.MaxPoint.Y - ext.MinPoint.Y;
        double modelWidth  = ext.MaxPoint.X - ext.MinPoint.X;

        LayoutManager layman = LayoutManager.Current;

        DBDictionary layoutDic = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;

        double mScale = 1;

        // Проходимся по всем листам (модель пропускаем)
        foreach (DBDictionaryEntry entry in layoutDic)
        {
          Layout layout = tr.GetObject(entry.Value, OpenMode.ForRead) as Layout;

          if (!layout.ModelType) // Это не модель
          {
            Extents3d extLayout = new Extents3d();
            BlockTableRecord btrLayout = tr.GetObject(layout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
            // Находим габариты примитивов в листе - будем считать их рамкой листа.
            foreach (ObjectId id in btrLayout)
            {
              Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
              if (ent != null && !(ent is Viewport))
              {
                extLayout.AddExtents(ent.GeometricExtents);
              }
            }
            // Центральная точка габаритов выбранных примитивов в листе
            Point3d layoutCenter = extLayout.MinPoint + (extLayout.MaxPoint - extLayout.MinPoint) * 0.5;
            double layoutHeight = extLayout.MaxPoint.Y - extLayout.MinPoint.Y;
            double layoutWidth = extLayout.MaxPoint.X - extLayout.MinPoint.X;

            // Находим масштабный коэффициент.
            mScale = layoutWidth / modelWidth;
            // Если масштабированная высота модели превышает высоту листа,
            // то в качестве масштаба используем коэффициент на основе высоты
            if (mScale * modelHeight > layoutHeight)
              mScale = layoutHeight / modelHeight;

            // Матрица масштабирования относительно цента в модели 
            Matrix3d matScale = Matrix3d.Scaling(mScale, modelCenter);
            // Масштабируем старый центр в модели по этой матрице
            Point3d  modelCenterScaling = modelCenter.TransformBy(matScale);
            // Находим матрицу переноса точки масштабированного центра в модели в точку
            // центра листа
            Matrix3d matDisp = Matrix3d.Displacement(layoutCenter - modelCenterScaling);
            // Комбинированная матрица
            Matrix3d matCompose = matScale.PreMultiplyBy(matDisp);

            IdMapping idmap = new IdMapping();

            btrLayout.UpgradeOpen();
            db.DeepCloneObjects(ids, layout.BlockTableRecordId, idmap, false);
            btrLayout.DowngradeOpen();
            foreach (IdPair idpair in idmap)
            {
              if (idpair.IsPrimary)
              {
                Entity ent = tr.GetObject(idpair.Value, OpenMode.ForWrite) as Entity;
                if (ent != null)
                {
                  // Трансформируем по комбинированной матрице
                  ent.TransformBy(matCompose);
                }
              }
            }
          }

        }
        tr.Commit();
      }
    }
  }
}

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes

Alexander.Rivilis
Mentor
Mentor

 

 

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes

Anonymous
Not applicable

Great solution! Thanks a lot!

0 Likes