Esses dias precisei fazer um diagrama unifilar. Esse tipo diagrama vem de uma longa multiplicação diagramática de muitos anos o que significa que os documentos são formado por linhas básicas, em model space e com cada folha em um arquivo dwg separado.
Pensado assim fiz alguns ajustes na elaboração dos documentos e a primeira coisa que queria era colocar todas as folhas em um único documento dwg, ponto crucial.
Se o documento tem poucas folhas é fácil mas e quando o documento tem muitas folhas seria interessante ter algum mecanismo para criar todos os Layout’s de modo automático.
Outro ponto é que sempre que se cria um Layout no AutoCAD o Layout vem sem nenhuma configuração e com uma viewport bizarra no meio do documento.
Usar o Layout é nitidamente uma atividade geral que muitas pessoas precisam automatizar.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.DatabaseServices; using System.Collections.Specialized; namespace AutoCAD.NET_Blog_Ex_2020_03_17 { public class myCommands { [CommandMethod("CriarLayoutRapido")] public void CriaLayout() { Document doc = Application.DocumentManager.MdiActiveDocument; if (doc == null) return; Database db = doc.Database; Editor ed = doc.Editor; //Abre a Transaction using (Transaction tr = db.TransactionManager.StartTransaction()) { // cria uma nova aba de Layout ObjectId id = LayoutManager.Current.CriarLayout("MeuLayoutNovo"); // Pega o objeto criado pelo Id Layout lay = (Layout)tr.GetObject(id, OpenMode.ForWrite); // Faça algumas configurações no layout e obtenha suas extensões // TODO: personalizar essa parte (você pode colocar as suas configurações personalizadas aqui) lay.SetPlotSettings( "ISO_full_bleed_2A0_(1189.00_x_1682.00_MM)", "monochrome.ctb", "DWF6 ePlot.pc3" ); Extents2d ext = lay.GetMaxExtents(); //Dimensiona a viewport de acordo com as extensões calculadas na linha anterior //Eu não uso margem nenhuma para sempre imprimir como PDF e a "borda" da janela ser o limite da pãgina e tudo ficar na //escala. lay.AplicaViewPort( tr, 2, vp => { vp.ResizeViewport(ext, 1.0); // Aqui voce pode ajustar para dar zoom no objeto ou até selecionar uma parte do model especifica. if (EncontraOsLimitesLimitedoDataBase(db.Extmin, db.Extmax)) { vp.FitContentToViewport(new Extents3d(db.Extmin, db.Extmax), 1.0); } //Dá um lock na Viewport. vp.Locked = true; } ); tr.Commit(); } //Dá uma ajeitada para tu ver o que rolou no código. ed.Document.SendStringToExecute("_.ZOOM _E ", true, false, false); ed.Document.SendStringToExecute("_.ZOOM .7X ", true, false, false); ed.Regen(); } /// <summary> /// Essa função serve para saber qual são os limites mãximos e minimos do desenho. /// Se você fizer algo sempre dentro dos limites não ~e necessária essa função. /// </summary> /// <param name="min">ponto 3d min</param> /// <param name="max">ponto 3d max</param> /// <returns></returns> private bool EncontraOsLimitesLimitedoDataBase(Point3d min, Point3d max) { bool eok = !(min.X > 0 && min.Y > 0 && min.Z > 0 && max.X < 0 && max.Y < 0 && max.Z < 0); return eok; } } public static class myExtensions { /// <summary> /// Inverte a ordem das propriedades X e Y de um Point2d. /// Para encontrar o outro extremo da viewport /// </summary> public static Point2d Swap(this Point2d pt, bool flip = true) { return flip ? new Point2d(pt.Y, pt.X) : pt; } /// <summary> /// Converte ym ponto 2d em um ponto 3d /// </summary> /// <param name="pt">Point2d.</param> /// <returns>Point3d com Z = 0 </returns> public static Point3d ConvPint_2dto3d(this Point2d pt) { return new Point3d(pt.X, pt.Y, 0); } /// <summary> /// Converte um ponto 3d em 2d. /// </summary> /// <param name="pt">The Point3d to strip.</param> /// <returns>The stripped Point2d.</returns> public static Point2d ConvPint_3dto2d(this Point3d pto3d) { return new Point2d(pto3d.X, pto3d.Y); } /// <summary> /// Cria o lauout com a opção de seleciona-lo como principal /// </summary> /// <param name="lm"></param> /// <param name="nome"></param> /// <param name="select"></param> /// <returns></returns> public static ObjectId CriarLayout(this LayoutManager lm, string nome, bool select = true) { // First try to get the layout ObjectId id = lm.GetLayoutId(nome); //Se não existe o Lauoyt ainda então o crie: if (!id.IsValid) id = lm.CreateLayout(nome); //Seleciona o Layout if (select) lm.CurrentLayout = nome; return id; } public static void AplicaViewPort(this Layout ilayout, Transaction aTrans, int vpNum, Action<Viewport> f) { ObjectIdCollection vpIds = ilayout.GetViewports(); Viewport vp = null; //N"ao tem como saber qual ~e a viewport na lista então procura uma a uma. foreach (ObjectId vpId in vpIds) { Viewport vp2 = aTrans.GetObject(vpId, OpenMode.ForWrite) as Viewport; if (vp2 != null && vp2.Number == vpNum) { vp = vp2; break; } } if (vp == null) { //Se não encontrou nenhuma viewport no Lauoyt então crie uma var btr = (BlockTableRecord)aTrans.GetObject(ilayout.BlockTableRecordId, OpenMode.ForWrite); vp = new Viewport(); //adiciona a viewport ao banco de dados do desenho btr.AppendEntity(vp); aTrans.AddNewlyCreatedDBObject(vp, true); vp.On = true; vp.GridOn = true; } f(vp); } public static void SetPlotSettings(this Layout lay, string pageSize, string styleSheet, string device) { using (var ps = new PlotSettings(lay.ModelType)) { ps.CopyFrom(lay); PlotSettingsValidator psv = PlotSettingsValidator.Current; //Seleciona a protagem StringCollection devs = psv.GetPlotDeviceList(); if (devs.Contains(device)) { psv.SetPlotConfigurationName(ps, device, null); psv.RefreshLists(ps); } StringCollection mns = psv.GetCanonicalMediaNameList(ps); if (mns.Contains(pageSize)) { psv.SetCanonicalMediaName(ps, pageSize); } //Seta as penas de poltagem StringCollection ssl = psv.GetPlotStyleSheetList(); if (ssl.Contains(styleSheet)) { psv.SetCurrentStyleSheet(ps, styleSheet); } //Copia a configuração de volta para o layout bool upgraded = false; if (!lay.IsWriteEnabled) { lay.UpgradeOpen(); upgraded = true; } lay.CopyFrom(ps); if (upgraded) { lay.DowngradeOpen(); } } } /// <summary> /// Determina qual seria o mãximo tamanho permitido apara o Layout /// </summary> /// public static Extents2d GetMaxExtents(this Layout lay) { var div = lay.PlotPaperUnits == PlotPaperUnit.Inches ? 25.4 : 1.0; var doIt = lay.PlotRotation == PlotRotation.Degrees090 || lay.PlotRotation == PlotRotation.Degrees270; var min = lay.PlotPaperMargins.MinPoint.Swap(doIt) / div; var max = (lay.PlotPaperSize.Swap(doIt) - lay.PlotPaperMargins.MaxPoint.Swap(doIt).GetAsVector()) / div; return new Extents2d(min, max); } public static void ResizeViewport( this Viewport vp, Extents2d ext, double fac = 1.0 ) { vp.Width = (ext.MaxPoint.X - ext.MinPoint.X) * fac; vp.Height = (ext.MaxPoint.Y - ext.MinPoint.Y) * fac; vp.CenterPoint = (Point2d.Origin + (ext.MaxPoint - ext.MinPoint) * 0.5).ConvPint_2dto3d(); } public static void FitContentToViewport( this Viewport vp, Extents3d ext3d, double fac = 1.0 ) { vp.ViewCenter = (ext3d.MinPoint + ((ext3d.MaxPoint - ext3d.MinPoint) * 0.5)).ConvPint_3dto2d(); var hgt = ext3d.MaxPoint.Y - ext3d.MinPoint.Y; var wid = ext3d.MaxPoint.X - ext3d.MinPoint.X; var aspect = vp.Width / vp.Height; if (wid / hgt > aspect) hgt = wid / aspect; vp.ViewHeight = hgt; vp.CustomScale *= fac; } } }
Observando o código veja que ele cria o layout e defini o tamanho da página. Depois disso o código modifica a viewport existente á criada junto com o Layout. Depois ajusto o zum para deixar o conteúdo mais ou menos preenchido durante esse processo de criação da viewport.
Tem também como deixar a viewport bloqueada. Como as pessoas que trabalham comigo não tem muito conhecimento de como usar o viewport prefiro deixa-las “presas” o que facilita para galera.
Espero que esse código seja útil para mais alguém além de mim.
veja o vídeo da utilização da função:
Código para Download.
Comentários
Postar um comentário