четверг, 5 июня 2014 г.

Стили мультивыносок в AutoCAD

В заметке показан пример программного создания и детальной настройки стиля мультивыносок в AutoCAD. В коде каждая изменяемая нами опция настроек помечена комментарием, содержащим наименование этой опции в англоязычной версии AutoCAD.
В результате работы кода будет создан и настроен новый стиль мультивыноски:



В коде определена команда CreateMultileaderStyle, выполняющая всю необходимую процедуру.

/* MLeaderStyleSample.cs
 * © Андрей Бушман, 2014 
 * Пример создания и настройки стиля мультивыно-
 * сок.
 */
using System;
using cad = Autodesk.AutoCAD.ApplicationServices
.Application;
using Ap = Autodesk.AutoCAD.ApplicationServices;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
using Gm = Autodesk.AutoCAD.Geometry;
using Rt = Autodesk.AutoCAD.Runtime;
using Clr = Autodesk.AutoCAD.Colors;
 
[assembly: Rt.CommandClass(typeof(Bushman.CAD
  .Samples.Styles.MLeaderStyleSample))]
 
namespace Bushman.CAD.Samples.Styles {
  public class MLeaderStyleSample {
    [Rt.CommandMethod("CreateMultileaderStyle",
      Rt.CommandFlags.Modal)]
    public void CreatingMleaderStyle() {
      Ap.Document doc = cad.DocumentManager
        .MdiActiveDocument;
      if(doc == null)
        return;
      Ed.Editor ed = doc.Editor;
      Db.Database db = doc.Database;
 
      using(Db.Transaction tr =
        db.TransactionManager.StartTransaction()) {
        Db.DBDictionary mleaderStylesDict =
          tr.GetObject(
          db.MLeaderStyleDictionaryId,
            Db.OpenMode.ForRead) as
            Db.DBDictionary;
 
        const String mleaderStyleName = "Точка";
 
        Db.MLeaderStyle mleaderStyle;
        if(mleaderStylesDict.Contains(
          mleaderStyleName))
          mleaderStyle = (Db.MLeaderStyle)tr
            .GetObject(
            (Db.ObjectId)mleaderStylesDict[
            mleaderStyleName],
            Db.OpenMode.ForWrite);
        else {
          mleaderStyle = new Db.MLeaderStyle();
          Db.ObjectId mleaderStyleId =
            mleaderStyle.PostMLeaderStyleToDb(db,
            mleaderStyleName);
          tr.AddNewlyCreatedDBObject(
            mleaderStyle, true);
        }
 
        // Ниже рассмотрены все настройки 
        // диалогового окна "Modify Multileader 
        // Style". Все наименования соответствуют
        // английской версии AutoCAD.
 
        // "Вкладка Leader Format" ***
 
        // Группа "General":
 
        mleaderStyle.LeaderLineType =
          Db.LeaderType.StraightLeader; // Type
        mleaderStyle.LeaderLineColor =
          Clr.Color.FromColorIndex(
          Clr.ColorMethod.ByLayer, 256); // Color
        mleaderStyle.LeaderLineTypeId =
          db.ByBlockLinetype; // Linetype
 
        // Lineweight
        mleaderStyle.LeaderLineWeight =
          Db.LineWeight.LineWeight025;
 
        // Группа "Arrowhead":
 
        Db.BlockTable blockTable = tr.GetObject(
          db.BlockTableId, Db.OpenMode.ForRead)
          as Db.BlockTable;
        if(!blockTable.Has("_DOT")) {
          // Загружаем определение блока "_DOT"
          cad.SetSystemVariable("DIMBLK""_DOT")
            ;
        }
        mleaderStyle.ArrowSymbolId = blockTable[
          "_DOT"]; // Symbol
        mleaderStyle.ArrowSize = 1; // Size
 
        // Группа "Leader break":
 
        // Break size
        mleaderStyle.BreakSize = 2;
 
        // Вкладка "Leader Structure" ***
 
        // Группа "Constrains":
 
        // Maximum leader points
        mleaderStyle.MaxLeaderSegmentsPoints = 2;
 
        // First segment angle
        mleaderStyle
          .FirstSegmentAngleConstraint =
          Db.AngleConstraint.DegreesAny;
 
        // Примечание для First segment angle:
 
        // Опция выбрана и значение равно 0:
        // mleaderStyle        
        //  .FirstSegmentAngleConstraint = 
        //  Db.AngleConstraint.DegreesHorz; 
 
        // Опция не выбрана и значение равно 0:
        // mleaderStyle        
        //  .FirstSegmentAngleConstraint = 
        //  Db.AngleConstraint.DegreesAny; 
 
        // Second segment angle
        mleaderStyle
          .SecondSegmentAngleConstraint =
          Db.AngleConstraint.DegreesAny;
 
        // Примечание для Second segment angle:
 
        // Опция выбрана и значение равно 0:
        // mleaderStyle
        //  .SecondSegmentAngleConstraint = 
        //  Db.AngleConstraint.DegreesHorz;
 
        // Опция не выбрана и значение равно 0:
        // mleaderStyle
        //  .SecondSegmentAngleConstraint = 
        //  Db.AngleConstraint.DegreesAny; 
 
        // Группа "Landing settings":
 
        // Автору кода не удалось добраться до 
        // опций "Automatically include landing" 
        // и "Set landing distance", а так же до
        // его значения ни через .NET, ни через 
        // COM.             
 
        // Группа "Scale":
 
        // Annotative
        mleaderStyle.Annotative =
          Db.AnnotativeStates.True;
 
        // Scale multileaders to layout
        // mleaderStyle.Scale = 0; 
 
        // Specify scale
        mleaderStyle.Scale = 1;
 
 
        // Вкладка "Content" ***               
 
        // *** Если для "Multileader type" выбран
        // вариант "MText": ***
 
        // Multileader type
        mleaderStyle.ContentType =
          Db.ContentType.MTextContent;
 
        // Создадим новый текстовый стиль для
        // использования его в нашем стиле
        // мультивыноски
        Db.TextStyleTable tst =
          (Db.TextStyleTable)tr.GetObject(
          db.TextStyleTableId,
          Db.OpenMode.ForWrite);
        Db.TextStyleTableRecord textStyle =
          new Db.TextStyleTableRecord();
        textStyle.Name = "Тип А прямой";
        textStyle.FileName = "Arial.ttf";
        textStyle.XScale = 0.75;
        tst.Add(textStyle);
        tr.AddNewlyCreatedDBObject(textStyle,
          true);
 
        // Группа "Text options":
        Db.MText defaultMText = new Db.MText();
        defaultMText.SetDatabaseDefaults();
 
#if AUTOCAD_2009
        defaultMText.TextStyle = 
          textStyle.ObjectId;
#else
        defaultMText.TextStyleId =
          textStyle.ObjectId;
#endif
 
        defaultMText.Contents = String.Empty;
        // Default text
        mleaderStyle.DefaultMText = defaultMText;
 
        // Text style
        mleaderStyle.TextStyleId =
          textStyle.ObjectId;
        // Text angle
        mleaderStyle.TextAngleType =
          Db.TextAngleType.HorizontalAngle;
        // Text color
        mleaderStyle.TextColor =
          Clr.Color.FromColorIndex(
          Clr.ColorMethod.ByBlock, 256);
        // Text height
        mleaderStyle.TextHeight = 3.5;
        // Alwais left justify
        mleaderStyle.TextAlignAlwaysLeft = false;
        // Frame text
        mleaderStyle.EnableFrameText = false;
 
        // Группа "Leader connection":
        mleaderStyle.TextAttachmentType =
          Db.TextAttachmentType.AttachmentMiddle;
 
        // Left attachment
        mleaderStyle.SetTextAttachmentType(
          Db.TextAttachmentType
          .AttachmentBottomOfTopLine,
          Db.LeaderDirectionType.LeftLeader);
 
        // Right attachment
        mleaderStyle.SetTextAttachmentType(
          Db.TextAttachmentType
          .AttachmentBottomOfTopLine,
            Db.LeaderDirectionType.RightLeader);
 
        // Landing gap 
        mleaderStyle.LandingGap = 1;
 
#if !AUTOCAD_2009
        // AutoCAD 2009 не имеет следующих 
        // свойств:
 
        // Horisontal attachment:
        mleaderStyle.TextAttachmentDirection =
         Db.TextAttachmentDirection
         .AttachmentHorizontal;
 
        // Внимание! если в настройках мы 
        // устанавливаем вариант "Horisontal 
        // attachment", то для установки опций
        // "Left attachment" и "Right attachment"
        // нужно методу SetTextAttachmentType
        // вторым аргументом передавать значения
        // LeftLeader и RightLeader 
        // сооветственно:
 
        // Left attachment
        mleaderStyle.SetTextAttachmentType(
          Db.TextAttachmentType
          .AttachmentBottomOfTopLine,
          Db.LeaderDirectionType.LeftLeader);
        // Right attachment
        mleaderStyle.SetTextAttachmentType(
          Db.TextAttachmentType
          .AttachmentBottomOfTopLine,
          Db.LeaderDirectionType.RightLeader);
 
        // или:
        // Vertical attachment:
        // mleaderStyle.TextAttachmentDirection =
        // Db.TextAttachmentDirection
        // .AttachmentVertical;
 
        // Внимание! если в настройках мы 
        // устанавливаем вариант "Vertical 
        // attachment", то для установки опций
        // "Top attachment" и "Bottom attachment"
        // нужно методу SetTextAttachmentType
        // вторым аргументом передавать значения
        // TopLeader и BottomLeader 
        // сооветственно:
 
        // Top attachment
        // mleaderStyle.SetTextAttachmentType(
        //  Db.TextAttachmentType
        //  .AttachmentCenter,
        //  Db.LeaderDirectionType.TopLeader);
 
        // Bottom attachment
        // mleaderStyle.SetTextAttachmentType(
        //  Db.TextAttachmentType
        //  .AttachmentCenter,
        //  Db.LeaderDirectionType.BottomLeader);
 
        // Extend leader to text
        mleaderStyle.ExtendLeaderToText = false;
#endif
 
        // В этом блоке показаны варианты "Block"
        // и "None": 
#if OTHER_VARIANTS_OF_MULTILEADER_TYPE
        // *** Если для "Multileader type" выбран
        // вариант "Block" ***
 
        // Multileader type
        mleaderStyle.ContentType =
          Db.ContentType.BlockContent;
 
        // Группа "Block options":     
 
        // Создаём нужное нам определение блока
        String blockName = "Блок выноски";
        try {
          Db.SymbolUtilityServices
            .ValidateSymbolName(blockName, false)
            ;
          Db.BlockTable bt = tr.GetObject(
            db.BlockTableId,
            Db.OpenMode.ForWrite) as
            Db.BlockTable;
 
          Db.ObjectId blockId = Db.ObjectId.Null;
 
          if(bt.Has(blockName))
            blockId = bt[blockName];
          else {
            Db.BlockTableRecord block =
              new Db.BlockTableRecord();
            block.Name = blockName;
            block.Annotative =
              Db.AnnotativeStates.True;
            bt.Add(block);
            tr.AddNewlyCreatedDBObject(block,
              true);
            // Пусть наш блок выноски будет пред-
            // ставлен окружностью с текстовым
            // атрибутом
 
            // Окружность
            Db.Circle circle = new Db.Circle();
            circle.Center = new Gm.Point3d(0, 0,
              0);
            circle.Radius = 10.0;
            circle.SetDatabaseDefaults();
            block.AppendEntity(circle);
            tr.AddNewlyCreatedDBObject(circle,
              true);
 
            // Определение атрибута
            Db.AttributeDefinition attDef =
              new Db.AttributeDefinition();
            attDef.Position = new Gm.Point3d(0,
              0, 0);
            attDef.Tag = "Текст выноски";
#if AUTOCAD_2009
            attDef.TextStyle = db.Textstyle;
#else
            attDef.TextStyleId = db.Textstyle;
#endif
            attDef.Prompt = "Значение атрибута";
            attDef.Preset = true;
            attDef.TextString = String.Empty;
            attDef.Justify = Db.AttachmentPoint
              .MiddleCenter;
            attDef.Height = 5;
            attDef.Annotative =
              Db.AnnotativeStates.True;
            block.AppendEntity(attDef);
            tr.AddNewlyCreatedDBObject(attDef,
              true);
            blockId = block.ObjectId;
          }
          // Source block
          mleaderStyle.BlockId = blockId;
          Gm.Scale3d scale3d = new Gm.Scale3d(
            3.35, 3.35, 3.35);
          // Scale
          mleaderStyle.BlockScale = scale3d;
          // Attachment       
          mleaderStyle.BlockConnectionType =
            Db.BlockConnectionType.ConnectBase;
          // Block color
          mleaderStyle.BlockColor = Clr.Color
            .FromColorIndex(Clr.ColorMethod
            .ByBlock, 256);
 
          // ***
        }
        catch(Exception ex) {
          ed.WriteMessage("Exception: {0}\n",
            ex.Message);
        }
 
        // *** Если для "Multileader type" выбран
        // вариант "None" ***
 
        // Multileader type
        mleaderStyle.ContentType =
          Db.ContentType.NoneContent;
 
        // Вариант "None" не содержит никаких 
        // дополнительных настроек.
#endif
        tr.Commit();
      }
    }
  }
}

Комментариев нет: