├── .gitignore
├── LICENSE.md
├── LayoutsFromModel.build
├── LayoutsFromModel.sln
├── LayoutsFromModel.smproj
├── LayoutsFromModel
├── BlocksBordersBuilder.cs
├── BorderDrawer.cs
├── BorderPromptResult.cs
├── CommandClass.cs
├── Configuration
│ ├── AppConfig.cs
│ ├── ConfigurationDialog.xaml
│ ├── ConfigurationDialog.xaml.cs
│ └── PrecisionValidationRule.cs
├── DrawingBorders.cs
├── Helpers
│ └── AcadPreferencesHelper.cs
├── IBorderVisitor.cs
├── IBordersCollectionBuilder.cs
├── InitialUserInteraction.cs
├── LayoutCreator.cs
├── LayoutsFromModel.csproj
├── PlotSettingsInfo.cs
├── PlotSettingsInfoBuilder.cs
├── PlotSettingsManager.cs
├── PromptResultStatus.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── CmdOptions.Designer.cs
│ ├── CmdOptions.resx
│ ├── CmdPrompts.Designer.cs
│ ├── CmdPrompts.resx
│ └── ErrorMessages.resx
└── UserInputBordersBuilder.cs
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | #OS junk files
2 | [Tt]humbs.db
3 | *.DS_Store
4 |
5 | #Visual Studio files
6 | *.[Oo]bj
7 | *.user
8 | *.aps
9 | *.pch
10 | *.vspscc
11 | *.vssscc
12 | *_i.c
13 | *_p.c
14 | *.ncb
15 | *.suo
16 | *.tlb
17 | *.tlh
18 | *.bak
19 | *.[Cc]ache
20 | *.ilk
21 | *.log
22 | *.lib
23 | *.sbr
24 | *.sdf
25 | *.opensdf
26 | ipch/
27 | obj/
28 | [Bb]in
29 | [Dd]ebug*/
30 | [Rr]elease*/
31 | Ankh.NoLoad
32 |
33 | #Tooling
34 | _ReSharper*/
35 | *.resharper
36 | [Tt]est[Rr]esult*
37 |
38 | #Project files
39 | [Bb]uild/
40 |
41 | #Subversion files
42 | .svn
43 |
44 | # Office Temp Files
45 | ~$*
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Aleksey Nakoryakov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LayoutsFromModel.build:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
28 |
29 |
30 |
31 |
33 |
34 |
35 |
36 |
37 |
42 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
58 |
59 |
60 |
61 |
62 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/LayoutsFromModel.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | # SharpDevelop 4.2.1.8805
5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2655139F-B74F-43F7-AF81-979D81EE583A}"
6 | ProjectSection(SolutionItems) = postProject
7 | LayoutsFromModel.build = LayoutsFromModel.build
8 | EndProjectSection
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LayoutsFromModel", "LayoutsFromModel\LayoutsFromModel.csproj", "{A1C752F5-8EF6-44A6-BFAD-C3948D05C452}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|x86 = Debug|x86
15 | Release|x86 = Release|x86
16 | Debug|Any CPU = Debug|Any CPU
17 | Release|Any CPU = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {A1C752F5-8EF6-44A6-BFAD-C3948D05C452}.Debug|x86.Build.0 = Debug|x86
21 | {A1C752F5-8EF6-44A6-BFAD-C3948D05C452}.Debug|x86.ActiveCfg = Debug|x86
22 | {A1C752F5-8EF6-44A6-BFAD-C3948D05C452}.Release|x86.Build.0 = Release|x86
23 | {A1C752F5-8EF6-44A6-BFAD-C3948D05C452}.Release|x86.ActiveCfg = Release|x86
24 | {A1C752F5-8EF6-44A6-BFAD-C3948D05C452}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {A1C752F5-8EF6-44A6-BFAD-C3948D05C452}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {A1C752F5-8EF6-44A6-BFAD-C3948D05C452}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {A1C752F5-8EF6-44A6-BFAD-C3948D05C452}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | EndGlobalSection
29 | EndGlobal
30 |
--------------------------------------------------------------------------------
/LayoutsFromModel.smproj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bargool/LayoutsFromModel/28119de39c943a127b670c60efab2a6d3f10f3ab/LayoutsFromModel.smproj
--------------------------------------------------------------------------------
/LayoutsFromModel/BlocksBordersBuilder.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 13.05.13
4 | * Time: 14:39
5 | */
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using Autodesk.AutoCAD.DatabaseServices;
10 | using Autodesk.AutoCAD.EditorInput;
11 |
12 | namespace LayoutsFromModel
13 | {
14 | ///
15 | /// Класс, создающий коллекцию границ чертежей из вхождений блоков
16 | ///
17 | public class BlocksBordersBuilder : IBordersCollectionBuilder
18 | {
19 | private Database _wdb = HostApplicationServices.WorkingDatabase;
20 |
21 | public int InitialBorderIndex { get; set; }
22 |
23 | ///
24 | /// Получение границ из вхождений блоков
25 | ///
26 | /// Массив границ чертежей
27 | public DrawingBorders[] GetDrawingBorders()
28 | {
29 | List borders = new List();
30 |
31 | string blockname = GetBordersBlockName();
32 |
33 | using (Transaction tr = _wdb.TransactionManager.StartTransaction())
34 | {
35 | // Получаем коллекцию ObjectId вхождений блока blockname, затем сортируем
36 | // "построчно"
37 | IEnumerable blockRefIds = null;
38 | BlockTable bt = (BlockTable)tr.GetObject(_wdb.BlockTableId, OpenMode.ForRead);
39 | if (!bt.Has(blockname))
40 | throw new ArgumentException("blockname");
41 | ObjectId btrId = bt[blockname];
42 |
43 | Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
44 | PromptSelectionResult res = ed.SelectImplied();
45 | if (res.Status == PromptStatus.OK)
46 | {
47 | blockRefIds = res.Value
48 | .GetObjectIds()
49 | .Where(id => id.ObjectClass.Name == "AcDbBlockReference")
50 | .Where(id => ((BlockReference)tr.GetObject(id, OpenMode.ForRead)).DynamicBlockTableRecord == btrId);
51 | }
52 | else
53 | {
54 | blockRefIds = GetBlockReferences(btrId);
55 | }
56 |
57 | blockRefIds = blockRefIds
58 | .Select(n => (BlockReference)tr.GetObject(n, OpenMode.ForRead))
59 | .OrderByDescending(n => n.Position.Y)
60 | .ThenBy(n => n.Position.X)
61 | .Select(n => n.ObjectId);
62 |
63 | int borderIndex = InitialBorderIndex;
64 |
65 | foreach (var brefId in blockRefIds)
66 | {
67 | string borderName = string.Format("{0}{1}{2}",
68 | Configuration.AppConfig.Instance.Prefix,
69 | borderIndex++,
70 | Configuration.AppConfig.Instance.Suffix);
71 | borders.Add(CreateBorder(brefId, borderName));
72 | }
73 | tr.Commit();
74 | }
75 |
76 | return borders.ToArray();
77 | }
78 |
79 | private string GetBordersBlockName()
80 | {
81 | string blockname = Configuration.AppConfig.Instance.BlockName;
82 | if (string.IsNullOrEmpty(blockname))
83 | throw new System.Exception("Не задано имя блока рамки!");
84 | return blockname;
85 | }
86 |
87 | private List GetBlockReferences(ObjectId blockId)
88 | {
89 | List result = null;
90 | using (Transaction tr = _wdb.TransactionManager.StartTransaction())
91 | {
92 | BlockTableRecord btr = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
93 |
94 | BlockTable bt = (BlockTable)tr.GetObject(_wdb.BlockTableId, OpenMode.ForRead);
95 | ObjectId modelId = ((BlockTableRecord)tr
96 | .GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead)).ObjectId;
97 |
98 | result = btr.GetAllBlockReferenceIds(true)
99 | .Select(n => (BlockReference)tr.GetObject(n, OpenMode.ForRead))
100 | .Where(n => n.OwnerId == modelId)
101 | .Select(n => n.ObjectId)
102 | .ToList();
103 | tr.Commit();
104 | }
105 | return result;
106 | }
107 |
108 | ///
109 | /// Создание объекта границы чертежа
110 | /// Масштаб берётся из масштаба вхождения блока по оси X
111 | ///
112 | /// ObjectId вхождения блока рамки
113 | /// Имя будущего листа
114 | /// Объект границ чертежа
115 | private DrawingBorders CreateBorder(ObjectId brefId, string name)
116 | {
117 | DrawingBorders border = null;
118 |
119 | using (Transaction tr = _wdb.TransactionManager.StartTransaction())
120 | {
121 | BlockReference bref = (BlockReference)tr.GetObject(brefId, OpenMode.ForRead);
122 | double scale = bref.ScaleFactors.X;
123 | border = DrawingBorders.CreateDrawingBorders(bref.GeometricExtents.MinPoint,
124 | bref.GeometricExtents.MaxPoint,
125 | name,
126 | scale);
127 | tr.Commit();
128 | }
129 | return border;
130 | }
131 | }
132 |
133 | public static class BlockTableRecordExtensions
134 | {
135 | public static IEnumerable GetAllBlockReferenceIds(this BlockTableRecord btr, bool directOnly)
136 | {
137 | IEnumerable brefIds = btr
138 | .GetBlockReferenceIds(directOnly, false)
139 | .Cast()
140 | .Concat(
141 | btr.GetAnonymousBlockIds()
142 | .Cast()
143 | .SelectMany(
144 | n => ((BlockTableRecord)n.GetObject(OpenMode.ForRead))
145 | .GetBlockReferenceIds(directOnly, false)
146 | .Cast()));
147 | return brefIds;
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/LayoutsFromModel/BorderDrawer.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey
3 | * Date: 01.05.2013
4 | * Time: 15:09
5 | */
6 | using System;
7 | using System.Collections.Generic;
8 |
9 | using Autodesk.AutoCAD.Colors;
10 | using Autodesk.AutoCAD.Geometry;
11 | using Autodesk.AutoCAD.GraphicsInterface;
12 | using ADS = Autodesk.AutoCAD.DatabaseServices;
13 |
14 | namespace LayoutsFromModel
15 | {
16 | ///
17 | /// Посетитель, отрисовывающий временной графикой выбранные пользователем рамки.
18 | ///
19 | public class BorderDrawer : IBorderVisitor
20 | {
21 | List objects = new List();
22 | Color graphicsColor = Color.FromColorIndex(ColorMethod.ByLayer, 20);
23 |
24 | public void DrawBorder(DrawingBorders border)
25 | {
26 | // Обводим рамку прямоугольником
27 | Drawable rec = CreateRectangle(border.First, border.Second);
28 | this.objects.Add(rec);
29 | TransientManager tm = TransientManager.CurrentTransientManager;
30 | tm.AddTransient(rec, TransientDrawingMode.Highlight, 128, new IntegerCollection());
31 |
32 | // Вписываем в рамку название будущего листа и его формат
33 | Drawable txt = CreateLayoutNameMText(border.Center, border.Name, border.PSInfo.Name, border.ScaleFactor);
34 | this.objects.Add(txt);
35 | tm.AddTransient(txt, TransientDrawingMode.DirectShortTerm, 256, new IntegerCollection());
36 | }
37 |
38 | private ADS.DBObject CreateRectangle(Point3d first, Point3d second)
39 | {
40 | ADS.Polyline pl = new ADS.Polyline(4);
41 | pl.Color = this.graphicsColor;
42 | double firstX = first.X;
43 | double secondX = second.X;
44 | double firstY = first.Y;
45 | double secondY = second.Y;
46 | pl.AddVertexAt(0, new Point2d(firstX, firstY), 0, 0, 0);
47 | pl.AddVertexAt(1, new Point2d(firstX, secondY), 0, 0, 0);
48 | pl.AddVertexAt(2, new Point2d(secondX, secondY), 0, 0, 0);
49 | pl.AddVertexAt(3, new Point2d(secondX, firstY), 0, 0, 0);
50 | pl.Closed = true;
51 | return pl;
52 | }
53 |
54 | private ADS.DBObject CreateLayoutNameMText(Point3d center, string name, string format, double scaleFactor)
55 | {
56 | ADS.MText mt = new ADS.MText();
57 | mt.SetDatabaseDefaults(ADS.HostApplicationServices.WorkingDatabase);
58 | mt.BackgroundFillColor = this.graphicsColor;
59 | mt.BackgroundFill = true;
60 | mt.Contents = name + "\\P" + format;
61 | mt.TextHeight = 12 * scaleFactor;
62 | mt.Location = center;
63 | mt.Attachment = ADS.AttachmentPoint.MiddleCenter;
64 | return mt;
65 | }
66 |
67 | public void ClearData()
68 | {
69 | TransientManager tm = TransientManager.CurrentTransientManager;
70 | if (this.objects != null || this.objects.Count != 0)
71 | {
72 | tm.EraseTransients(TransientDrawingMode.Highlight, 128, new IntegerCollection());
73 | tm.EraseTransients(TransientDrawingMode.DirectShortTerm, 256, new IntegerCollection());
74 | foreach (Drawable obj in this.objects)
75 | obj.Dispose();
76 | this.objects.Clear();
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/LayoutsFromModel/BorderPromptResult.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 07.05.13
4 | * Time: 17:04
5 | */
6 | using System;
7 | using Autodesk.AutoCAD.Geometry;
8 |
9 | namespace LayoutsFromModel
10 | {
11 | ///
12 | /// Результат ввода пользователем рамки чертежа
13 | ///
14 | public struct BorderPromptResult
15 | {
16 | Point3d firstPoint;
17 | public Point3d FirstPoint {
18 | get { return firstPoint; }
19 | }
20 |
21 | Point3d secondPoint;
22 | public Point3d SecondPoint {
23 | get { return secondPoint; }
24 | }
25 |
26 | string stringResult;
27 | public string StringResult {
28 | get { return stringResult; }
29 | set { stringResult = value; }
30 | }
31 |
32 | PromptResultStatus queryStatus;
33 | public PromptResultStatus QueryStatus {
34 | get { return queryStatus; }
35 | set { queryStatus = value; }
36 | }
37 |
38 | public BorderPromptResult(Point3d firstPoint, Point3d secondPoint)
39 | {
40 | this.queryStatus = PromptResultStatus.OK;
41 | this.firstPoint = firstPoint;
42 | this.secondPoint = secondPoint;
43 | this.stringResult = "";
44 | }
45 |
46 | public BorderPromptResult(string stringResult)
47 | {
48 | this.queryStatus = PromptResultStatus.Keyword;
49 | this.stringResult = stringResult;
50 | this.firstPoint = Point3d.Origin;
51 | this.secondPoint = Point3d.Origin;
52 | }
53 |
54 | public BorderPromptResult(PromptResultStatus queryStatus)
55 | {
56 | this.queryStatus = queryStatus;
57 | this.firstPoint = Point3d.Origin;
58 | this.secondPoint = Point3d.Origin;
59 | this.stringResult = "";
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/LayoutsFromModel/CommandClass.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 06.03.12
4 | * Time: 18:05
5 | */
6 | //Microsoft
7 | using System;
8 |
9 | //Autodesk
10 | using Autodesk.AutoCAD.Runtime;
11 | using acad = Autodesk.AutoCAD.ApplicationServices.Application;
12 |
13 | [assembly:CommandClass(typeof(LayoutsFromModel.CommandClass))]
14 |
15 | namespace LayoutsFromModel
16 | {
17 | ///
18 | /// Данный класс содержит методы для непосредственной работы с AutoCAD
19 | ///
20 | public class CommandClass
21 | {
22 | [CommandMethodAttribute("bargLFM", CommandFlags.Modal|CommandFlags.NoPaperSpace)]
23 | [CommandMethodAttribute("LFM", CommandFlags.Modal|CommandFlags.NoPaperSpace)]
24 | public void LayoutFromUserInput()
25 | {
26 | CreateLayouts(new UserInputBordersBuilder());
27 | }
28 |
29 | [CommandMethod("bargLFBL", CommandFlags.Modal|CommandFlags.NoPaperSpace|CommandFlags.UsePickSet)]
30 | public void LayoutFromBlocks()
31 | {
32 | CreateLayouts(new BlocksBordersBuilder());
33 | }
34 |
35 | private void CreateLayouts(IBordersCollectionBuilder bordersBuilder)
36 | {
37 | InitialUserInteraction initial = new InitialUserInteraction();
38 | initial.GetInitialData();
39 | if (initial.InitialDataStatus == PromptResultStatus.Cancelled)
40 | return;
41 | initial.FillPlotInfoManager();
42 | bordersBuilder.InitialBorderIndex = initial.Index;
43 | DrawingBorders[] borders = bordersBuilder.GetDrawingBorders();
44 | if (borders.Length == 0)
45 | {
46 | acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nНе выбран ни один чертёж");
47 | return;
48 | }
49 | LayoutCreator layoutCreator = new LayoutCreator();
50 | foreach (DrawingBorders border in borders)
51 | {
52 | layoutCreator.CreateLayout(border);
53 | }
54 |
55 | Configuration.AppConfig cfg = Configuration.AppConfig.Instance;
56 | // Если в конфигурации отмечено "возвращаться в модель" - то переходим в модель
57 | if (cfg.TilemodeOn)
58 | acad.SetSystemVariable("TILEMODE", 1);
59 |
60 | // Если в конфигурации отмечено "удалять неинициализированные листы" - удаляем их
61 | if (cfg.DeleteNonInitializedLayouts)
62 | {
63 | layoutCreator.DeleteNoninitializedLayouts();
64 | acad.DocumentManager.MdiActiveDocument.Editor.Regen();
65 | }
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/LayoutsFromModel/Configuration/AppConfig.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 08/01/2012
4 | * Time: 13:58
5 | */
6 | using System;
7 | using System.ComponentModel;
8 | using System.IO;
9 | using System.Reflection;
10 | using System.Runtime.Serialization;
11 | using System.Windows;
12 | using System.Xml.Serialization;
13 |
14 | namespace LayoutsFromModel.Configuration
15 | {
16 | ///
17 | /// Класс, представляющий конфигурацию приложения
18 | ///
19 | [Serializable]
20 | public sealed class AppConfig
21 | {
22 | string prefix = "Lay";
23 | ///
24 | /// Префикс имени Layout
25 | ///
26 | public string Prefix {
27 | get { return prefix; }
28 | set { prefix = value; }
29 | }
30 |
31 | string suffix = "";
32 | ///
33 | /// Суффикс имени Layout
34 | ///
35 | public string Suffix {
36 | get { return suffix; }
37 | set { suffix = value; }
38 | }
39 |
40 | int precision = 10;
41 | ///
42 | /// Точность определения формата бумаги
43 | ///
44 | public int Precision {
45 | get { return precision; }
46 | set { precision = value; }
47 | }
48 |
49 | bool deleteNonInitializedLayouts = false;
50 | ///
51 | /// Удалять ли неинициализированные листы
52 | ///
53 | public bool DeleteNonInitializedLayouts {
54 | get { return deleteNonInitializedLayouts; }
55 | set { deleteNonInitializedLayouts = value; }
56 | }
57 |
58 | double referenceDimension = 185.0;
59 | ///
60 | /// Эталонный размер. Используется для определения масштаба чертежа при
61 | /// выборе пользователем. По-умолчанию - длина основной надписи
62 | ///
63 | public double ReferenceDimension {
64 | get { return referenceDimension; }
65 | set { referenceDimension = value; }
66 | }
67 |
68 | bool tilemodeOn = true;
69 | ///
70 | /// Возвращаться ли в модель по окончанию созданию листов
71 | ///
72 | public bool TilemodeOn {
73 | get { return tilemodeOn; }
74 | set { tilemodeOn = value; }
75 | }
76 |
77 | string templatePath = "";
78 | ///
79 | /// Путь к шаблону с именованными настройками печати
80 | ///
81 | public string TemplatePath {
82 | get { return templatePath; }
83 | set { templatePath = value; }
84 | }
85 |
86 | string blockName = "";
87 | ///
88 | /// Имя блока рамки
89 | ///
90 | public string BlockName {
91 | get { return blockName; }
92 | set { blockName = value; }
93 | }
94 |
95 | bool lockViewPorts = false;
96 | ///
97 | /// Блокирование видовых экранов
98 | ///
99 | public bool LockViewPorts {
100 | get { return lockViewPorts; }
101 | set { lockViewPorts = value; }
102 | }
103 |
104 | const string FILENAME = "lfmsettings.xml"; // Имя файла конфигурации
105 | // Полный путь к файлу конфигурации
106 | private static string SettingsFile
107 | {
108 | get
109 | {
110 | return Path.Combine(Path.GetDirectoryName(
111 | Assembly.GetAssembly(typeof(AppConfig))
112 | .Location), FILENAME);
113 | }
114 | }
115 |
116 |
117 | private static AppConfig instance = Load();
118 |
119 | public static AppConfig Instance {
120 | get { return instance; }
121 | }
122 |
123 | private AppConfig()
124 | {}
125 |
126 | ///
127 | /// Сохранение конфигурации в файл
128 | ///
129 | public void Save()
130 | {
131 | using (Stream stream = File.Create(SettingsFile))
132 | {
133 | XmlSerializer ser = new XmlSerializer(this.GetType());
134 | ser.Serialize(stream, this);
135 | }
136 | }
137 |
138 | ///
139 | /// Загрузка конфигурации из файла
140 | ///
141 | ///
142 | private static AppConfig Load()
143 | {
144 | if (!File.Exists(SettingsFile))
145 | return new AppConfig();
146 | using (Stream stream = File.OpenRead(SettingsFile))
147 | {
148 | try
149 | {
150 | XmlSerializer ser = new XmlSerializer(typeof(AppConfig));
151 | return (AppConfig)ser.Deserialize(stream);
152 | }
153 | catch (InvalidOperationException)
154 | {
155 | stream.Close();
156 | File.Delete(SettingsFile);
157 | return new AppConfig();
158 | }
159 | }
160 | }
161 |
162 | ///
163 | /// Метод вызывает диалог конфигурации и изменяет настройки в зависимости от результата вызова
164 | ///
165 | public void ShowDialog()
166 | {
167 | ConfigurationDialog win = new ConfigurationDialog(Prefix, Suffix,
168 | Precision,DeleteNonInitializedLayouts,
169 | ReferenceDimension,
170 | TilemodeOn,
171 | BlockName,
172 | LockViewPorts);
173 | win.ShowDialog();
174 | if (true == win.DialogResult)
175 | {
176 | this.Prefix = win.Prefix;
177 | this.Suffix = win.Suffix;
178 | this.Precision = win.Precision??new AppConfig().Precision;
179 | this.DeleteNonInitializedLayouts = win.DelNonInitializedLayouts;
180 | this.TilemodeOn = win.TilemodeOn;
181 | this.BlockName = win.BlockName;
182 | this.LockViewPorts = win.LockViewPorts;
183 | Save();
184 | }
185 | }
186 |
187 | public bool TemplateExists()
188 | {
189 | return !string.IsNullOrEmpty(this.TemplatePath)&&File.Exists(this.TemplatePath);
190 | }
191 |
192 | public override string ToString()
193 | {
194 | return string.Format(
195 | "[Configuration Prefix={0}, Suffix={1}, Precision={2}, DeleteNonInitializedLayouts={3}, ReferenceDimension={4}, TilemodeOn={5}]",
196 | Prefix, Suffix, Precision, DeleteNonInitializedLayouts, ReferenceDimension, TilemodeOn);
197 | }
198 | }
199 | }
--------------------------------------------------------------------------------
/LayoutsFromModel/Configuration/ConfigurationDialog.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
21 |
25 |
28 |
29 |
30 |
31 |
32 |
35 |
36 |
39 |
40 |
43 |
50 |
51 |
55 |
59 |
63 |
64 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/LayoutsFromModel/Configuration/ConfigurationDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 01.08.12
4 | * Time: 13:37
5 | */
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Text;
9 | using System.Windows;
10 | using System.Windows.Controls;
11 | using System.Windows.Data;
12 | using System.Windows.Documents;
13 | using System.Windows.Input;
14 | using System.Windows.Media;
15 |
16 | namespace LayoutsFromModel.Configuration
17 | {
18 | ///
19 | /// Interaction logic for ConfigurationDialog.xaml
20 | ///
21 | public partial class ConfigurationDialog : Window
22 | {
23 | //TODO: Напрямую связать конфигурацию и поля ввода окна
24 | public string Prefix { get; private set; }
25 | public string Suffix { get; private set; }
26 | public int? Precision { get; set; }
27 | public bool DelNonInitializedLayouts { get; set; }
28 |
29 | public double? ReferenceDimension { get; set; }
30 | public bool TilemodeOn { get; set; }
31 |
32 | public string BlockName { get; set; }
33 | public bool LockViewPorts { get; set; }
34 |
35 | public ConfigurationDialog()
36 | {
37 | InitializeComponent();
38 | }
39 |
40 | public ConfigurationDialog
41 | (string prefix, string suffix, Nullable precision,
42 | bool delNonInitializedLayouts, double referenceDimension,
43 | bool tilemodeOn, string blockname, bool lockViewPorts)
44 | :this()
45 | {
46 | this.Prefix = prefix;
47 | this.Suffix = suffix;
48 | this.Precision = precision;
49 | this.DelNonInitializedLayouts = delNonInitializedLayouts;
50 | this.ReferenceDimension = referenceDimension;
51 | this.TilemodeOn = tilemodeOn;
52 | this.BlockName = blockname;
53 | this.LockViewPorts = lockViewPorts;
54 | }
55 |
56 | void Window_Loaded(object sender, RoutedEventArgs e)
57 | {
58 | txtPrefix.Text = this.Prefix;
59 | txtSuffix.Text = this.Suffix;
60 | txtPrecision.Text = this.Precision.ToString();
61 | chkDeleteNonInitialized.IsChecked = this.DelNonInitializedLayouts;
62 | chkTileModeOn.IsChecked = this.TilemodeOn;
63 | txtBlockName.Text = this.BlockName;
64 | chkLockVP.IsChecked = this.LockViewPorts;
65 | }
66 |
67 | void BtnOK_Click(object sender, RoutedEventArgs e)
68 | {
69 | this.DialogResult = true;
70 | }
71 |
72 | void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
73 | {
74 | Prefix = txtPrefix.Text;
75 | Suffix = txtSuffix.Text;
76 | int precision;
77 | Precision = int.TryParse(txtPrecision.Text, out precision) ? (int?)Math.Abs(precision) : null;
78 | DelNonInitializedLayouts = chkDeleteNonInitialized.IsChecked??false;
79 | this.TilemodeOn = chkTileModeOn.IsChecked??false;
80 | this.BlockName = txtBlockName.Text;
81 | this.LockViewPorts = chkLockVP.IsChecked ?? false;
82 | }
83 | }
84 | }
--------------------------------------------------------------------------------
/LayoutsFromModel/Configuration/PrecisionValidationRule.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 27.08.12
4 | * Time: 15:19
5 | */
6 | using System;
7 | using System.Windows.Controls;
8 |
9 | namespace LayoutsFromModel.Configuration
10 | {
11 | ///
12 | /// Заготовка для PrecisionValidationRule.
13 | ///
14 | public class PrecisionValidationRule : ValidationRule
15 | {
16 | int minValue = 0;
17 |
18 | public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
19 | {
20 | int precision;
21 | if (!int.TryParse((string)value, out precision))
22 | return new ValidationResult(false, "Должно быть число");
23 | if (precision
12 | /// Класс, описывающий поведение границ выделенной
13 | /// области для отображения в пространстве листа
14 | ///
15 | public sealed class DrawingBorders
16 | {
17 | Point3d first;
18 | ///
19 | /// Первая точка рамки
20 | ///
21 | public Point3d First {
22 | get { return first; }
23 | }
24 |
25 | Point3d second;
26 | ///
27 | /// Вторая точка рамки, противоположная первой
28 | ///
29 | public Point3d Second {
30 | get { return second; }
31 | }
32 |
33 | ///
34 | /// Высота выделенной области
35 | ///
36 | public double Height {
37 | get { return Math.Abs(first.Y-second.Y); }
38 | }
39 |
40 | ///
41 | /// Ширина выделенной области
42 | ///
43 | public double Width {
44 | get { return Math.Abs(first.X-second.X); }
45 | }
46 |
47 | ///
48 | /// Центр выделенной области
49 | ///
50 | public Point3d Center {
51 | get { return (new LineSegment3d(first, second)).MidPoint; }
52 | }
53 |
54 | string name;
55 | ///
56 | /// Имя области, в дальнейшем имя листа
57 | ///
58 | public string Name {
59 | get { return name; }
60 | set { name = value; }
61 | }
62 |
63 | ///
64 | /// Масштаб
65 | ///
66 | public double ScaleFactor { get; private set; }
67 |
68 | ///
69 | /// Информация о формате бумаги, в который вписываются данные границы
70 | ///
71 | public PlotSettingsInfo PSInfo { get; set; }
72 |
73 | private DrawingBorders() {}
74 |
75 | private DrawingBorders(Point3d first, Point3d second, string name, double scale)
76 | {
77 | this.first = first;
78 | this.second = second;
79 | this.name = name;
80 | this.ScaleFactor = scale;
81 | }
82 |
83 | public static DrawingBorders CreateDrawingBorders(Point3d first, Point3d second, string name, double scale)
84 | {
85 | DrawingBorders borders = new DrawingBorders(first, second, name, scale);
86 | PlotSettingsManager psm = PlotSettingsManager.Current;
87 | borders.PSInfo = psm.GetPlotSettings(borders, Configuration.AppConfig.Instance.Precision);
88 | return borders;
89 | }
90 |
91 | public override string ToString()
92 | {
93 | return string.Format("[LayoutBorders First={0}, Second={1}, Name={2}, Scale={3}]", first, second, name, ScaleFactor);
94 | }
95 |
96 | public void Accept(IBorderVisitor visitor)
97 | {
98 | visitor.DrawBorder(this);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/LayoutsFromModel/Helpers/AcadPreferencesHelper.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 03.08.12
4 | * Time: 12:32
5 | */
6 | using System;
7 | using System.Reflection;
8 | using Autodesk.AutoCAD.ApplicationServices;
9 |
10 | namespace LayoutsFromModel
11 | {
12 | ///
13 | /// Класс для работы с настройками AutoCAD
14 | ///
15 | public static class AcadPreferencesHelper
16 | {
17 | ///
18 | /// Метод задаёт значение для настройки LayoutCreateViewport
19 | ///
20 | /// Новое значение настройки
21 | /// Старое значение настройки
22 | public static bool SetLayoutCreateViewportProperty(bool newValue)
23 | {
24 | object acadObject = Application.AcadApplication;
25 | object preferences = acadObject.GetType().InvokeMember("Preferences",
26 | BindingFlags.GetProperty,
27 | null, acadObject, null);
28 | object display =
29 | preferences.GetType().InvokeMember("Display",
30 | BindingFlags.GetProperty,
31 | null, preferences, null);
32 | object layoutProperty = display
33 | .GetType().InvokeMember("LayoutCreateViewport",
34 | BindingFlags.GetProperty,
35 | null, display, null);
36 | bool layoutCreateViewportProperty = Convert.ToBoolean(layoutProperty);
37 | object[] dataArray = new object[]{newValue};
38 | display.GetType()
39 | .InvokeMember("LayoutCreateViewport",
40 | BindingFlags.SetProperty,
41 | null, display, dataArray);
42 | return layoutCreateViewportProperty;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/LayoutsFromModel/IBorderVisitor.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey
3 | * Date: 01.05.2013
4 | * Time: 15:07
5 | */
6 | using System;
7 |
8 | namespace LayoutsFromModel
9 | {
10 | ///
11 | /// Интерфейс посетителя, отрисовывающего границы чертежей
12 | ///
13 | public interface IBorderVisitor
14 | {
15 | void DrawBorder(DrawingBorders border);
16 | void ClearData();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/LayoutsFromModel/IBordersCollectionBuilder.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 07.05.13
4 | * Time: 14:22
5 | */
6 | using System;
7 |
8 | namespace LayoutsFromModel
9 | {
10 | ///
11 | /// Интерфейс строителя коллекции границ чертежей
12 | ///
13 | public interface IBordersCollectionBuilder
14 | {
15 | ///
16 | /// Номер первого чертежа
17 | ///
18 | int InitialBorderIndex { get; set; }
19 |
20 | DrawingBorders[] GetDrawingBorders();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/LayoutsFromModel/InitialUserInteraction.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 06.05.13
4 | * Time: 14:14
5 | */
6 | using System;
7 | using System.Collections.Generic;
8 | using Autodesk.AutoCAD.EditorInput;
9 | using CO = LayoutsFromModel.Properties.CmdOptions;
10 | using CP = LayoutsFromModel.Properties.CmdPrompts;
11 |
12 | namespace LayoutsFromModel
13 | {
14 | ///
15 | /// Обработка первоначального взаимодействия с пользователем.
16 | /// Получение номера первого листа. Работа с конфигурацией.
17 | /// Заполнение коллекции настроек печати
18 | ///
19 | public class InitialUserInteraction
20 | {
21 | bool useTemplate;
22 |
23 | Editor ed;
24 |
25 | public int Index { get; set; }
26 |
27 | public PromptResultStatus InitialDataStatus { get; private set; }
28 |
29 | public InitialUserInteraction()
30 | {
31 | this.Index = 1;
32 | this.useTemplate = false;
33 | this.ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
34 | }
35 |
36 | ///
37 | /// Метод служит для первоначального опроса пользователя
38 | ///
39 | public void GetInitialData()
40 | {
41 | PromptIntegerResult piRes = null; // Номер первого Layout
42 | bool exitLoop = false; // Условие продолжения команды
43 | do
44 | {
45 | // Получаем начальный номер для Layout
46 | PromptIntegerOptions pio = new PromptIntegerOptions("\n"+CP.FirstLayoutNumber);
47 | pio.Keywords.Add(CO.Configuration);
48 | if (!this.useTemplate)
49 | {
50 | pio.Keywords.Add(CO.UseTemplate);
51 | pio.Keywords.Add(CO.TemplateSelect);
52 | }
53 | pio.AllowNegative = false;
54 | pio.AllowNone = false;
55 | pio.DefaultValue = this.Index;
56 | piRes = ed.GetInteger(pio);
57 | // TODO Обрабатывать выход по escape
58 | switch (piRes.Status)
59 | {
60 | // Введён номер - продолжаем
61 | case PromptStatus.OK:
62 | this.Index = piRes.Value;
63 | exitLoop = true;
64 | break;
65 | // Отрабатываем ключевые слова
66 | case PromptStatus.Keyword:
67 | if (piRes.StringResult.Equals(CO.Configuration, StringComparison.InvariantCulture))
68 | Configuration.AppConfig.Instance.ShowDialog();
69 | else
70 | TemplateProcessing(piRes.StringResult);
71 | break;
72 | default:
73 | this.InitialDataStatus = PromptResultStatus.Cancelled;
74 | return;
75 | }
76 | } while (!exitLoop);
77 | this.InitialDataStatus = PromptResultStatus.OK;
78 | }
79 |
80 | ///
81 | /// Заполнение коллекции настроек печати
82 | ///
83 | public void FillPlotInfoManager()
84 | {
85 | Configuration.AppConfig cfg = Configuration.AppConfig.Instance;
86 | IEnumerable psinfos = null;
87 | if (this.useTemplate)
88 | {
89 | psinfos = PlotSettingsInfoBuilder.CreatePlotSettingsInfos(cfg.TemplatePath);
90 | ed.WriteMessage("\n" + CP.UsingTemplate + cfg.TemplatePath);
91 | }
92 | else
93 | psinfos = PlotSettingsInfoBuilder.CreatePlotSettingsInfos();
94 |
95 | PlotSettingsManager psm = PlotSettingsManager.Current;
96 | psm.Clear();
97 |
98 | foreach (PlotSettingsInfo psi in psinfos)
99 | psm.Add(psi);
100 | }
101 |
102 | ///
103 | /// Обработка параметров ком. строки, связанный с использованием шаблона
104 | ///
105 | /// Выбранный параметр ком. строки
106 | private void TemplateProcessing(string keyword)
107 | {
108 | if (keyword.Equals(CO.UseTemplate, StringComparison.InvariantCulture))
109 | {
110 | // Если файл шаблона задан и существует, присваиваем true, иначе выкидываем ошибку
111 | if (Configuration.AppConfig.Instance.TemplateExists())
112 | this.useTemplate = true;
113 | else
114 | throw new System.Exception("Не задан, или неверно задан файл шаблона");
115 | }
116 |
117 | if (keyword.Equals(CO.TemplateSelect, StringComparison.InvariantCulture))
118 | {
119 | this.useTemplate = SelectTemplate();
120 | }
121 | }
122 |
123 | ///
124 | /// Запрос пользователя для выбора файла шаблона
125 | ///
126 | /// True, если был выбран корректный файл шаблона, иначе false
127 | private bool SelectTemplate()
128 | {
129 | Configuration.AppConfig cfg = Configuration.AppConfig.Instance;
130 | PromptOpenFileOptions pofo = new PromptOpenFileOptions(CP.TemplateFileQuery);
131 | pofo.Filter = CP.TemplateFileQueryFilter;
132 | pofo.InitialFileName = cfg.TemplatePath;
133 |
134 | PromptFileNameResult templateName = ed.GetFileNameForOpen(pofo);
135 |
136 | if (templateName.Status == PromptStatus.OK)
137 | {
138 | if (!System.IO.File.Exists(templateName.StringResult))
139 | throw new System.IO.FileNotFoundException(templateName.StringResult);
140 | cfg.TemplatePath = templateName.StringResult;
141 | cfg.Save();
142 | return true;
143 | }
144 |
145 | return false;
146 | }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/LayoutsFromModel/LayoutCreator.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey
3 | * Date: 02.05.2013
4 | * Time: 15:35
5 | */
6 | using System;
7 | using Autodesk.AutoCAD.DatabaseServices;
8 | using Autodesk.AutoCAD.Geometry;
9 | using Bargool.Acad.Library;
10 |
11 | namespace LayoutsFromModel
12 | {
13 | ///
14 | /// Класс для создания листов
15 | ///
16 | public class LayoutCreator
17 | {
18 | Database wdb;
19 |
20 | public LayoutCreator()
21 | {
22 | this.wdb = HostApplicationServices.WorkingDatabase;
23 | }
24 |
25 | ///
26 | /// Метод создаёт Layout по заданным параметрам
27 | ///
28 | /// Границы выделенной области в пространстве модели
29 | public void CreateLayout(DrawingBorders borders)
30 | {
31 | using (Transaction tr = this.wdb.TransactionManager.StartTransaction())
32 | {
33 | string layoutName = CheckLayoutName(borders.Name);
34 |
35 | PlotSettings ps = ImportPlotSettings(borders, tr);
36 | LayoutManager lm = LayoutManager.Current;
37 | Layout layout;
38 | try
39 | {
40 | layout = (Layout)tr.GetObject(lm.CreateLayout(layoutName), OpenMode.ForWrite);
41 | }
42 | catch (System.Exception ex)
43 | {
44 | throw new System.Exception(String.Format("Ошибка создания Layout {0}\n{1}", layoutName, ex.Message));
45 | }
46 |
47 | layout.CopyFrom(ps);
48 | lm.CurrentLayout = layout.LayoutName;
49 | View.Zoom(new Point3d(0,0,0), new Point3d(layout.PlotPaperSize.X, layout.PlotPaperSize.Y, 0), new Point3d(), 1);
50 | CreateViewport(layout, borders, tr);
51 | tr.Commit();
52 | }
53 | }
54 |
55 | ///
56 | /// Метод удаляет неинициализированные листы
57 | ///
58 | public void DeleteNoninitializedLayouts()
59 | {
60 | using (Transaction tr = wdb.TransactionManager.StartTransaction())
61 | {
62 | DBDictionary dic = (DBDictionary)tr.GetObject(wdb.LayoutDictionaryId, OpenMode.ForRead);
63 | foreach (DBDictionaryEntry entry in dic)
64 | {
65 | Layout layout = (Layout)tr.GetObject(entry.Value, OpenMode.ForRead);
66 | if (!layout.ModelType && layout.GetViewports().Count == 0)
67 | {
68 | if (dic.Count>1)
69 | {
70 | if (!dic.IsWriteEnabled)
71 | dic.UpgradeOpen();
72 | dic.Remove(entry.Value);
73 | layout.UpgradeOpen();
74 | layout.Erase(true);
75 | Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
76 | .MdiActiveDocument.Editor.WriteMessage("\nУдаляю лист "+layout.LayoutName+Environment.NewLine);
77 | }
78 | }
79 | }
80 | tr.Commit();
81 | }
82 | }
83 |
84 | ///
85 | /// Проверка корректности желаемого имени листа
86 | /// Если лист с желаемым именем уже существует, к данному имени добавится "(1)"
87 | /// Если и это имя уже есть - цифра в скобках будет увеличиваться, пока не будет найден
88 | /// уникальный вариант
89 | ///
90 | /// Желаемое имя листа
91 | /// Корректное имя листа
92 | string CheckLayoutName(string expectedName)
93 | {
94 | string layoutName = expectedName;
95 | using (Transaction tr = this.wdb.TransactionManager.StartTransaction())
96 | {
97 | // Проверяем на наличие листа с указанным именем
98 | DBDictionary layoutsDic = (DBDictionary)tr.GetObject(wdb.LayoutDictionaryId, OpenMode.ForRead);
99 | if (layoutsDic.Contains(layoutName))
100 | {
101 | // Если есть - добавляем номер в скобках, итерируем номер, пока имя не станет уникальным
102 | int dublicateLayoutIndex = 1;
103 | while (layoutsDic.Contains(string.Format("{0}({1})", layoutName, dublicateLayoutIndex)))
104 | {
105 | dublicateLayoutIndex++;
106 | }
107 | layoutName = string.Format("{0}({1})", layoutName, dublicateLayoutIndex);
108 | }
109 | tr.Commit();
110 | }
111 | return layoutName;
112 | }
113 |
114 | ///
115 | /// Метод добавляет из объекта границ чертежа новые
116 | /// именованые настройки печати в файл, если таковых там нет
117 | ///
118 | /// Объект границ чертежа
119 | /// Текущая транзакция
120 | /// Настройки печати, соответствующие границам чертежа
121 | PlotSettings ImportPlotSettings(DrawingBorders borders, Transaction tr)
122 | {
123 | PlotSettings ps = new PlotSettings(false);
124 | ps.CopyFrom(borders.PSInfo.PSettings);
125 |
126 | DBDictionary psDict = (DBDictionary)tr.GetObject(this.wdb.PlotSettingsDictionaryId,
127 | OpenMode.ForRead);
128 | if (!psDict.Contains(ps.PlotSettingsName))
129 | {
130 | psDict.UpgradeOpen();
131 | ps.AddToPlotSettingsDictionary(this.wdb);
132 | tr.AddNewlyCreatedDBObject(ps, true);
133 | psDict.DowngradeOpen();
134 | }
135 | return ps;
136 | }
137 |
138 | ///
139 | /// Метод создаёт Viewport на заданном Layout, в размер листа
140 | ///
141 | /// Layout, на котором создаётся viewport
142 | /// Границы выделенной области в модели
143 | void CreateViewport(Layout layout, DrawingBorders borders, Transaction tr)
144 | {
145 | int vpCount = layout.GetViewports().Count;
146 | if (vpCount == 0)
147 | {
148 | throw new System.Exception(String.Format("Layout {0} не инициализирован", layout.LayoutName));
149 | }
150 | Viewport vp;
151 | if (vpCount == 1)
152 | {
153 | BlockTableRecord lbtr =
154 | (BlockTableRecord)tr.GetObject(layout.BlockTableRecordId, OpenMode.ForWrite);
155 | vp = new Viewport();
156 | vp.SetDatabaseDefaults();
157 | lbtr.AppendEntity(vp);
158 | tr.AddNewlyCreatedDBObject(vp, true);
159 | vp.On = true;
160 | }
161 | else
162 | {
163 | ObjectId vpId = layout.GetViewports()[vpCount-1];
164 | if (vpId.IsNull)
165 | throw new System.Exception("Не удалось получить вьюпорт!");
166 |
167 | vp = (Viewport)tr.GetObject(vpId, OpenMode.ForWrite);
168 | if (vp == null)
169 | throw new System.Exception("Не удалось получить вьюпорт!");
170 | }
171 | // Высоту и ширину вьюпорта выставляем в размер выделенной области
172 | vp.Height = borders.Height / borders.ScaleFactor;
173 | vp.Width = borders.Width / borders.ScaleFactor;
174 | vp.CenterPoint = new Point3d(vp.Width/2 + layout.PlotOrigin.X,
175 | vp.Height/2 + layout.PlotOrigin.Y,
176 | 0);
177 | vp.ViewTarget = new Point3d(0,0,0);
178 | vp.ViewHeight = borders.Height;
179 | vp.ViewCenter = new Point2d(borders.Center.X, borders.Center.Y);
180 | vp.Locked = LayoutsFromModel.Configuration.AppConfig.Instance.LockViewPorts;
181 | }
182 | }
183 | }
--------------------------------------------------------------------------------
/LayoutsFromModel/LayoutsFromModel.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {A1C752F5-8EF6-44A6-BFAD-C3948D05C452}
5 | Debug
6 | x86
7 | Library
8 | LayoutsFromModel
9 | LayoutsFromModel
10 | v3.5
11 | Properties
12 | False
13 | False
14 | 4
15 | false
16 | OnBuildSuccess
17 | AnyCPU
18 | False
19 | False
20 |
21 |
22 | False
23 | Auto
24 | 4194304
25 |
26 | 4096
27 |
28 |
29 | bin\Debug\
30 | true
31 | Full
32 | True
33 | True
34 | DEBUG;TRACE
35 | Project
36 |
37 |
38 | bin\Release\
39 | False
40 | None
41 | True
42 | False
43 | TRACE
44 |
45 |
46 | False
47 | Auto
48 | 4194304
49 |
50 | 4096
51 |
52 |
53 |
54 | C:\ObjectARX 2010\inc-x64\AcDbMgd.dll
55 | False
56 |
57 |
58 | C:\ObjectARX 2010\inc-x64\AcMgd.dll
59 | False
60 |
61 |
62 | 3.0
63 |
64 |
65 | 3.0
66 |
67 |
68 |
69 | 3.5
70 |
71 |
72 |
73 | 3.5
74 |
75 |
76 | 3.0
77 |
78 |
79 |
80 |
81 | Extensions\AcadSystemVariableSwitcher.cs
82 |
83 |
84 | Extensions\View.cs
85 |
86 |
87 | IBordersCollectionBuilder.cs
88 |
89 |
90 | IBorderVisitor.cs
91 |
92 |
93 |
94 |
95 |
96 |
97 | ConfigurationDialog.xaml
98 | Code
99 |
100 |
101 | ConfigurationDialog.xaml
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | PlotSettingsInfo.cs
112 |
113 |
114 |
115 |
116 | CmdOptions.resx
117 | True
118 |
119 |
120 | CmdPrompts.resx
121 | True
122 |
123 |
124 | IBordersCollectionBuilder.cs
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | PublicResXFileCodeGenerator
138 | CmdOptions.Designer.cs
139 |
140 |
141 | PublicResXFileCodeGenerator
142 | CmdPrompts.Designer.cs
143 |
144 |
145 | PublicResXFileCodeGenerator
146 | LayoutsFromModel.Resources
147 | ErrorMessages.Designer.cs
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/LayoutsFromModel/PlotSettingsInfo.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 27.02.13
4 | * Time: 17:10
5 | */
6 | using System;
7 | using System.Collections.Generic;
8 | using Autodesk.AutoCAD.DatabaseServices;
9 |
10 | namespace LayoutsFromModel
11 | {
12 | ///
13 | /// Класс, содержащий информацию о настройках печати
14 | ///
15 | public class PlotSettingsInfo : IEqualityComparer
16 | {
17 | ///
18 | /// Имя формата бумаги
19 | ///
20 | public string Name {
21 | get { return PSettings.PlotSettingsName; }
22 | }
23 | ///
24 | /// Ширина листа
25 | ///
26 | public double Width {
27 | get { return PSettings.PlotRotation == PlotRotation.Degrees000 ? PSettings.PlotPaperSize.X : PSettings.PlotPaperSize.Y; }
28 | }
29 | ///
30 | /// Высота листа
31 | ///
32 | public double Height {
33 | get { return PSettings.PlotRotation == PlotRotation.Degrees000 ? PSettings.PlotPaperSize.Y : PSettings.PlotPaperSize.X; }
34 | }
35 | ///
36 | /// PlotSettings
37 | ///
38 | public PlotSettings PSettings { get; private set; }
39 |
40 | public PlotSettingsInfo(PlotSettings pSettings)
41 | {
42 | if (pSettings == null)
43 | throw new ArgumentNullException("PlotSettings");
44 | this.PSettings = pSettings;
45 | }
46 |
47 | public bool Equals(PlotSettingsInfo x, PlotSettingsInfo y)
48 | {
49 | return Math.Abs(x.Height - y.Height) < 1E-9 && Math.Abs(x.Width - y.Width) < 1E-9;
50 | }
51 |
52 | public int GetHashCode(PlotSettingsInfo obj)
53 | {
54 | return (obj.Height*obj.Width).GetHashCode();
55 | }
56 |
57 | public override string ToString()
58 | {
59 | return Name;
60 | }
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/LayoutsFromModel/PlotSettingsInfoBuilder.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 28.02.13
4 | * Time: 13:27
5 | */
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Collections.Specialized;
9 | using System.Linq;
10 | using Autodesk.AutoCAD.DatabaseServices;
11 | using Autodesk.AutoCAD.ApplicationServices;
12 |
13 | namespace LayoutsFromModel
14 | {
15 | ///
16 | /// Класс служит для создания коллекции PlotSettingsInfo
17 | ///
18 | public static class PlotSettingsInfoBuilder
19 | {
20 | ///
21 | /// Чтение именованных настроек печати из указанного файла
22 | ///
23 | /// Путь к файлу с именованными настройками печати
24 | /// Коллекция PlotSettingsInfo
25 | public static IEnumerable CreatePlotSettingsInfos(string templatePath)
26 | {
27 | Database db = null;
28 | bool isTemplateOpened = false;
29 |
30 | DocumentCollection docMan = Application.DocumentManager;
31 | Document doc = docMan.Cast().FirstOrDefault(d => d.Name.Equals(templatePath, StringComparison.InvariantCulture));
32 | if (doc != null)
33 | {
34 | db = doc.Database;
35 | isTemplateOpened = true;
36 | }
37 | else
38 | {
39 | db = new Database(false, true);
40 | db.ReadDwgFile(templatePath, System.IO.FileShare.Read, true, null);
41 | }
42 |
43 | using (Transaction tr = db.TransactionManager.StartTransaction())
44 | {
45 | DBDictionary psDict = tr.GetObject(db.PlotSettingsDictionaryId, OpenMode.ForRead) as DBDictionary;
46 | if (psDict != null)
47 | {
48 | foreach (DBDictionaryEntry entry in psDict)
49 | {
50 | ObjectId psId = entry.Value;
51 | PlotSettings ps = tr.GetObject(psId, OpenMode.ForRead) as PlotSettings;
52 | // Настройки печати для модели и настройки листов самих по себе
53 | // нам не нужны
54 | // только именованные настройки печати для листов
55 | if (!ps.ModelType && !ps.PlotSettingsName.Contains("*"))
56 | {
57 | PlotSettings newPS = new PlotSettings(false);
58 | newPS.CopyFrom(ps);
59 | yield return new PlotSettingsInfo(newPS);
60 | }
61 | }
62 | }
63 | tr.Commit();
64 | }
65 | if (!isTemplateOpened)
66 | db.Dispose();
67 | }
68 |
69 | ///
70 | /// Создание коллекции PlotSettingsInfo из пользовательских форматов
71 | /// в файле DWG to PDF.pc3
72 | /// Также в коллекцию будут включены форматы, начинающиеся с "ISO_A" - это поведение
73 | /// подлежит изменению
74 | ///
75 | /// Коллекция PlotSettingsInfo
76 | public static IEnumerable CreatePlotSettingsInfos()
77 | {
78 | string PLOTTER_NAME = "DWG To PDF.pc3";
79 | Database db = HostApplicationServices.WorkingDatabase;
80 | using (Transaction tr = db.TransactionManager.StartTransaction())
81 | {
82 | PlotSettingsValidator psv = PlotSettingsValidator.Current;
83 | PlotSettings ps = new PlotSettings(false);
84 | psv.RefreshLists(ps);
85 | psv.SetPlotConfigurationName(ps, PLOTTER_NAME, null);
86 | // Получаем список CanonicalMediaNames плоттера
87 | StringCollection canonicalMediaNames = psv.GetCanonicalMediaNameList(ps);
88 |
89 | string plotStyle = "acad.ctb";
90 | System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex(@"[\<>/?"":;*|,=`]");
91 |
92 | for (int nameIndex = 0; nameIndex < canonicalMediaNames.Count; nameIndex++)
93 | {
94 | // Работаем только с пользовательскими форматами
95 | if (canonicalMediaNames[nameIndex].Contains("UserDefinedMetric") ||
96 | canonicalMediaNames[nameIndex].StartsWith("ISO_A"))
97 | {
98 | psv.SetPlotConfigurationName(ps, PLOTTER_NAME, canonicalMediaNames[nameIndex]);
99 |
100 | psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Layout);
101 | psv.SetPlotPaperUnits(ps, PlotPaperUnit.Millimeters);
102 |
103 | psv.SetStdScaleType(ps, StdScaleType.StdScale1To1);
104 | psv.SetUseStandardScale(ps, true);
105 |
106 | psv.SetCurrentStyleSheet(ps, plotStyle);
107 |
108 | if (canonicalMediaNames[nameIndex].StartsWith("ISO_A0"))
109 | psv.SetPlotRotation(ps, PlotRotation.Degrees090);
110 | else
111 | psv.SetPlotRotation(ps, PlotRotation.Degrees000);
112 |
113 | string plotSettingsName = re.Replace(psv.GetLocaleMediaName(ps, nameIndex), "");
114 | if (string.IsNullOrEmpty(plotSettingsName))
115 | {
116 | plotSettingsName = canonicalMediaNames[nameIndex];
117 | }
118 | ps.PlotSettingsName = plotSettingsName;
119 |
120 | PlotSettings newPS = new PlotSettings(false);
121 | newPS.CopyFrom(ps);
122 | yield return new PlotSettingsInfo(newPS);
123 | }
124 | }
125 | }
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/LayoutsFromModel/PlotSettingsManager.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 27.02.13
4 | * Time: 17:47
5 | */
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 |
10 | namespace LayoutsFromModel
11 | {
12 | ///
13 | /// Класс, инкапсулирующий логику работы с коллекцией PlotSettingsInfo.
14 | /// В коллекции не допускаются PlotSettings с одинаковым размером листа
15 | ///
16 | public class PlotSettingsManager : ICollection
17 | {
18 | private List plotSettingsInfos = new List();
19 |
20 | private static PlotSettingsManager current = new PlotSettingsManager();
21 |
22 | public static PlotSettingsManager Current {
23 | get { return current; }
24 | }
25 |
26 | private PlotSettingsManager()
27 | {}
28 |
29 | // Формат бумаги с максимальной высотой
30 | private PlotSettingsInfo maximumHeighted{
31 | get
32 | {
33 | return plotSettingsInfos
34 | .OrderBy(n => n.Height)
35 | .ThenBy(n => n.Width)
36 | .Last();
37 | }
38 | }
39 |
40 | ///
41 | /// Метод ищет наименьший формат бумаги, в который помещается указанная область
42 | ///
43 | /// Границы области, для которой надо делать Layout
44 | /// Точность определения формата
45 | /// Формат бумаги
46 | public PlotSettingsInfo GetPlotSettings(DrawingBorders borders, int precision)
47 | {
48 | double scale = 1 / borders.ScaleFactor;
49 | return plotSettingsInfos
50 | .Where(n => n.Height >= borders.Height*scale - precision)
51 | .Where(n => n.Width >= borders.Width*scale - precision)
52 | .Aggregate(maximumHeighted, (work, next) => {
53 | double DiffHeightNext = Math.Round(next.Height) - borders.Height*scale;
54 | double DiffHeightWork = Math.Round(work.Height) - borders.Height*scale;
55 | double DiffWidthNext = Math.Round(next.Width) - borders.Width*scale;
56 | double DiffWidthWork = Math.Round(work.Width) - borders.Width*scale;
57 | if (DiffHeightNext GetEnumerator()
116 | {
117 | return plotSettingsInfos.GetEnumerator();
118 | }
119 |
120 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
121 | {
122 | return plotSettingsInfos.GetEnumerator();
123 | }
124 | #endregion
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/LayoutsFromModel/PromptResultStatus.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 08.05.13
4 | * Time: 13:21
5 | */
6 | using System;
7 |
8 | namespace LayoutsFromModel
9 | {
10 | ///
11 | /// Перечисление, отражающее статус запроса пользователя
12 | ///
13 | public enum PromptResultStatus
14 | {
15 | Cancelled,
16 | Keyword,
17 | OK
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/LayoutsFromModel/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #region Using directives
2 |
3 | using System;
4 | using System.Reflection;
5 | using System.Runtime.InteropServices;
6 |
7 | #endregion
8 |
9 | // General Information about an assembly is controlled through the following
10 | // set of attributes. Change these attribute values to modify the information
11 | // associated with an assembly.
12 | [assembly: AssemblyTitle("LayoutsFromModel")]
13 | [assembly: AssemblyDescription("AutoCAD plugin. Создание листов из чертежей, оформленных в модели. http://forum.dwg.ru/showthread.php?t=83750")]
14 | [assembly: AssemblyConfiguration("")]
15 | [assembly: AssemblyCompany("")]
16 | [assembly: AssemblyProduct("LayoutsFromModel")]
17 | [assembly: AssemblyCopyright("Copyright 2013")]
18 | [assembly: AssemblyTrademark("")]
19 | [assembly: AssemblyCulture("")]
20 |
21 | // This sets the default COM visibility of types in the assembly to invisible.
22 | // If you need to expose a type to COM, use [ComVisible(true)] on that type.
23 | [assembly: ComVisible(false)]
24 |
25 | // The assembly version has following format :
26 | //
27 | // Major.Minor.Build.Revision
28 | //
29 | // You can specify all the values or you can use the default the Revision and
30 | // Build Numbers by using the '*' as shown below:
31 | [assembly: AssemblyVersion("1.4.0.0")]
32 |
--------------------------------------------------------------------------------
/LayoutsFromModel/Properties/CmdOptions.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.296
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace LayoutsFromModel.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | public class CmdOptions {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal CmdOptions() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | public static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LayoutsFromModel.Properties.CmdOptions", typeof(CmdOptions).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | public static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Cancel.
65 | ///
66 | public static string Cancel {
67 | get {
68 | return ResourceManager.GetString("Cancel", resourceCulture);
69 | }
70 | }
71 |
72 | ///
73 | /// Looks up a localized string similar to Configuration.
74 | ///
75 | public static string Configuration {
76 | get {
77 | return ResourceManager.GetString("Configuration", resourceCulture);
78 | }
79 | }
80 |
81 | ///
82 | /// Looks up a localized string similar to Newscale.
83 | ///
84 | public static string NewScale {
85 | get {
86 | return ResourceManager.GetString("NewScale", resourceCulture);
87 | }
88 | }
89 |
90 | ///
91 | /// Looks up a localized string similar to Process.
92 | ///
93 | public static string Process {
94 | get {
95 | return ResourceManager.GetString("Process", resourceCulture);
96 | }
97 | }
98 |
99 | ///
100 | /// Looks up a localized string similar to templateSelect.
101 | ///
102 | public static string TemplateSelect {
103 | get {
104 | return ResourceManager.GetString("TemplateSelect", resourceCulture);
105 | }
106 | }
107 |
108 | ///
109 | /// Looks up a localized string similar to Undo.
110 | ///
111 | public static string Undo {
112 | get {
113 | return ResourceManager.GetString("Undo", resourceCulture);
114 | }
115 | }
116 |
117 | ///
118 | /// Looks up a localized string similar to useTemplate.
119 | ///
120 | public static string UseTemplate {
121 | get {
122 | return ResourceManager.GetString("UseTemplate", resourceCulture);
123 | }
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/LayoutsFromModel/Properties/CmdOptions.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Cancel
122 |
123 |
124 | useTemplate
125 |
126 |
127 | Undo
128 |
129 |
130 | Process
131 |
132 |
133 | Configuration
134 |
135 |
136 | templateSelect
137 |
138 |
139 | Newscale
140 |
141 |
--------------------------------------------------------------------------------
/LayoutsFromModel/Properties/CmdPrompts.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.296
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace LayoutsFromModel.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | public class CmdPrompts {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal CmdPrompts() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | public static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LayoutsFromModel.Properties.CmdPrompts", typeof(CmdPrompts).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | public static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Задайте номер первого Layout: .
65 | ///
66 | public static string FirstLayoutNumber {
67 | get {
68 | return ResourceManager.GetString("FirstLayoutNumber", resourceCulture);
69 | }
70 | }
71 |
72 | ///
73 | /// Looks up a localized string similar to Дайте первую точку рамки: .
74 | ///
75 | public static string FrameFirstPointQuery {
76 | get {
77 | return ResourceManager.GetString("FrameFirstPointQuery", resourceCulture);
78 | }
79 | }
80 |
81 | ///
82 | /// Looks up a localized string similar to Дайте противоположную точку рамки: .
83 | ///
84 | public static string FrameOppositePointQuery {
85 | get {
86 | return ResourceManager.GetString("FrameOppositePointQuery", resourceCulture);
87 | }
88 | }
89 |
90 | ///
91 | /// Looks up a localized string similar to Укажите файл шаблона.
92 | ///
93 | public static string TemplateFileQuery {
94 | get {
95 | return ResourceManager.GetString("TemplateFileQuery", resourceCulture);
96 | }
97 | }
98 |
99 | ///
100 | /// Looks up a localized string similar to Шаблон (*.dwg, *.dwt)|*.dwg;*.dwt.
101 | ///
102 | public static string TemplateFileQueryFilter {
103 | get {
104 | return ResourceManager.GetString("TemplateFileQueryFilter", resourceCulture);
105 | }
106 | }
107 |
108 | ///
109 | /// Looks up a localized string similar to Используем шаблон .
110 | ///
111 | public static string UsingTemplate {
112 | get {
113 | return ResourceManager.GetString("UsingTemplate", resourceCulture);
114 | }
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/LayoutsFromModel/Properties/CmdPrompts.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Задайте номер первого Layout:
122 |
123 |
124 | Укажите файл шаблона
125 |
126 |
127 | Шаблон (*.dwg, *.dwt)|*.dwg;*.dwt
128 |
129 |
130 | Используем шаблон
131 |
132 |
133 | Дайте первую точку рамки:
134 |
135 |
136 | Дайте противоположную точку рамки:
137 |
138 |
--------------------------------------------------------------------------------
/LayoutsFromModel/Properties/ErrorMessages.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/LayoutsFromModel/UserInputBordersBuilder.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * User: aleksey.nakoryakov
3 | * Date: 07.05.13
4 | * Time: 14:26
5 | */
6 | using System;
7 | using System.Collections.Generic;
8 | using Autodesk.AutoCAD.EditorInput;
9 | using Autodesk.AutoCAD.Geometry;
10 | using Bargool.Acad.Library;
11 |
12 | using CO = LayoutsFromModel.Properties.CmdOptions;
13 | using CP = LayoutsFromModel.Properties.CmdPrompts;
14 |
15 | namespace LayoutsFromModel
16 | {
17 | ///
18 | /// Класс, создающий коллекцию границ чертежей с помощью
19 | /// ввода этих самых границ пользователем
20 | ///
21 | public class UserInputBordersBuilder : IBordersCollectionBuilder
22 | {
23 | Editor ed;
24 | public int InitialBorderIndex { get; set; }
25 |
26 | public UserInputBordersBuilder()
27 | {
28 | ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
29 | }
30 |
31 | public UserInputBordersBuilder(int firstPageIndex)
32 | : this()
33 | {
34 | this.InitialBorderIndex = firstPageIndex;
35 | }
36 |
37 | public DrawingBorders[] GetDrawingBorders()
38 | {
39 | List borders = new List();
40 |
41 | // Выставляем osmode в 1 - ENDpoint
42 | using (AcadSystemVariableSwitcher varSW = new AcadSystemVariableSwitcher("OSMODE", 1))
43 | {
44 | Configuration.AppConfig cfg = Configuration.AppConfig.Instance;
45 | // Крутимся, пока нужны новые масштабы (а один раз он точно нужен)
46 | bool needNewScale = true;
47 |
48 | BorderDrawer drawer = new BorderDrawer();
49 |
50 | while (needNewScale)
51 | {
52 | // Получаем масштаб
53 | double scale = GetScale(cfg.ReferenceDimension);
54 | if (scale == 0)
55 | return borders.ToArray();
56 |
57 | needNewScale = false;
58 |
59 | // Крутимся, пока нужны новые рамки
60 | bool needNewBorder = true;
61 | while (needNewBorder)
62 | {
63 | BorderPromptResult borderRes = GetBorderPoints();
64 | switch (borderRes.QueryStatus)
65 | {
66 | case PromptResultStatus.Cancelled:
67 | // Пользователь нажал escape, запускаем процесс создания листов
68 | needNewBorder = false;
69 | break;
70 |
71 | case PromptResultStatus.Keyword:
72 | // Использованы параметры ком. строки
73 |
74 | // Нужен новый масштаб
75 | if (borderRes.StringResult.Equals(CO.NewScale, StringComparison.InvariantCulture))
76 | {
77 | needNewBorder = false;
78 | needNewScale = true;
79 | }
80 |
81 | // Запускаем процесс создания листов
82 | if (borderRes.StringResult.Equals(CO.Process, StringComparison.InvariantCulture))
83 | {
84 | needNewBorder = false;
85 | }
86 |
87 | // Отменяем последний введённый чертёж
88 | if (borderRes.StringResult.Equals(CO.Undo, StringComparison.InvariantCulture))
89 | {
90 | if (borders.Count>0)
91 | {
92 | borders.RemoveAt(borders.Count-1);
93 | InitialBorderIndex--;
94 |
95 | drawer.ClearData();
96 | foreach (DrawingBorders b in borders)
97 | {
98 | b.Accept(drawer);
99 | }
100 | }
101 | else
102 | {
103 | ed.WriteMessage("\nНечего возвращать");
104 | }
105 | }
106 |
107 | // Выходим из команды
108 | if (borderRes.StringResult.Equals(CO.Cancel, StringComparison.InvariantCulture))
109 | {
110 | ed.WriteMessage("\nОтмена!");
111 | drawer.ClearData();
112 | borders.Clear();
113 | return borders.ToArray();
114 | }
115 |
116 | break;
117 |
118 | case PromptResultStatus.OK:
119 | // Введены точки
120 | string bordername = string.Format("{0}{1}{2}", cfg.Prefix, InitialBorderIndex++, cfg.Suffix);
121 | DrawingBorders border =
122 | DrawingBorders.CreateDrawingBorders(borderRes.FirstPoint,
123 | borderRes.SecondPoint,
124 | bordername,
125 | scale);
126 | ed.WriteMessage("\nДобавляем лист {0}. Формат листа: {1}", bordername, border.PSInfo.Name);
127 | borders.Add(border);
128 | border.Accept(drawer);
129 |
130 | break;
131 | default:
132 | throw new Exception("Invalid value for BorderQueryResultStatus");
133 | }
134 | }
135 | }
136 | drawer.ClearData();
137 | // Возвращаем osmode в исходное состояние
138 | }
139 | return borders.ToArray();
140 | }
141 |
142 | double GetScale(double baseReferenceDimension)
143 | {
144 | string prompt = string.Format("\nЗадайте или укажите длину основной надписи (то, что должно быть {0} мм):", baseReferenceDimension);
145 | PromptDistanceOptions pdo =
146 | new PromptDistanceOptions(prompt);
147 | pdo.AllowZero = false;
148 | pdo.AllowNegative = false;
149 | pdo.Only2d = true;
150 | pdo.UseDashedLine = true;
151 | pdo.DefaultValue = baseReferenceDimension;
152 | PromptDoubleResult res = ed.GetDistance(pdo);
153 | if (res.Status!= PromptStatus.OK)
154 | return 0.0;
155 | double scale = res.Value / baseReferenceDimension;
156 | ed.WriteMessage("\nМасштабный коэффициент: {0}", scale);
157 | return scale;
158 | }
159 |
160 | BorderPromptResult GetBorderPoints()
161 | {
162 | PromptPointOptions ppo = new PromptPointOptions("\n" + CP.FrameFirstPointQuery);
163 | ppo.Keywords.Add(CO.Process);
164 | ppo.Keywords.Add(CO.NewScale);
165 | ppo.Keywords.Add(CO.Undo);
166 | ppo.Keywords.Add(CO.Cancel);
167 | // Запрашиваем первую точку
168 | PromptPointResult res1 = ed.GetPoint(ppo);
169 | if (res1.Status== PromptStatus.OK)
170 | {
171 | Point3d p1 = res1.Value;
172 | // Запрашиваем вторую точку
173 | PromptCornerOptions pco = new PromptCornerOptions(CP.FrameOppositePointQuery, p1);
174 | pco.UseDashedLine = true;
175 | PromptPointResult res2 = ed.GetCorner(pco);
176 | if (res2.Status != PromptStatus.OK)
177 | return new BorderPromptResult(PromptResultStatus.Cancelled);
178 |
179 | p1 = p1.TransformBy(ed.CurrentUserCoordinateSystem);
180 | Point3d p2 = res2.Value.TransformBy(ed.CurrentUserCoordinateSystem);
181 | return new BorderPromptResult(p1, p2);
182 | }
183 | else if (res1.Status == PromptStatus.Keyword)
184 | {
185 | return new BorderPromptResult(res1.StringResult);
186 | }
187 |
188 | return new BorderPromptResult();
189 | }
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Назначение программы:
2 | Создание листов по рамкам, указанным пользователем в модели. Автоматический выбор форматов бумаги и настройка листов.
3 |
4 | Принцип работы:
5 | - Программа формирует предварительный список настроек листа, с форматами бумаги
6 | Список формируется двумя способами
7 | 1. Из DWG to PDF.pc3
8 | Выбираются все пользовательские форматы
9 | В конец списка добавляются форматы, начинающиеся на "ISO A.."
10 | Область печати выставляется "Лист"
11 | Единицы измерения - миллиметры
12 | Масштаб 1:1
13 | Стиль печати - acad.ctb. Позже буду брать из файла конфигурации
14 | Имя настройки берётся из имени формата бумаги. Если встречаются символы из ряда "\<>/?"":;*|,=`" - убираются
15 | 2. Из файла шаблона
16 | Копируются пользовательские именованные настройки печати, доступные из диалога "Page setup"
17 | Повторяю. Пользовательски настройки. Не листы, а именно настройки
18 | Ещё раз. В листы не заглядываем ВООБЩЕ
19 | Соответственно, имя настройки печати не должно начинаться с символа звёздочки "*"
20 | - Запрашивает у пользователя "референтный размер".
21 | Используется для определения масштаба рамки. По-умолчанию это 185 мм. - длина основной надписи
22 | - Запрашивает у пользователя противоположные углы рамок
23 | Слева-направо, сверху-вниз, или наоборот - не важно
24 | Привязка принудительно выставляется "конточка"
25 | - На основе масштаба и списка форматов определяет наиболее подходящий
26 | При этом используется строго ориентация из "списка". Ориентацию с книжной на альбомную и обратно программа произвольно не меняет. Строго по "списку настроек"
27 | - По выбранным форматам бумаги создаёт листы
28 | В чертёж добавляет подходящие именованные настройки из "списка", настроенные на нужный формат бумаги
29 | Присваивает созданным листам соответствующие именованные настройки
30 | - Создаёт видовой экран, "смотрящий" на рамку, указанную пользователем
31 |
32 | Процесс работы:
33 | 1. Для вызова программы введите в ком. строку lfm
34 | 2. Либо задайте номер первого создаваемого листа, либо используйте опции ком. строки
35 | 3. Укажите "референтный" размер
36 | 4. Указывайте рамки, кликая по противоположным углам рамок.
37 | Опции ком. строки см. соответствующий раздел
38 | 5. По окончании жмите escape или используйте опцию P
39 |
40 | Конфигурация:
41 | - Файл конфигурации. Имя файла - lfmsettings.xml. Хранится рядом программой
42 | Содержимое, не используемое диалогом конфигурации:
43 | - ReferenceDimension (По-умолчанию - 185). Референтный размер. Масштаб рамки будет определяться как отношение указанного пользователем размера к размеру в конфигурации. Если у вас референтный размер другой - можете изменить вручную
44 | - TemplatePath. Путь к шаблону для формирования списка настроек листов. Устанавливается программой при выборе опции templateSelect
45 | Диалог конфигурации:
46 | - Префикс - Префикс имени создаваемого листа
47 | - Суффикс - Суффикс имени создаваемого листа
48 | - Точность определения форматов - Отвечает за точность определения форматов. Суть в том, что форматки иногда бывают примерно по госту. Таким образом, если указываемая форматка больше гостовского размера (уже после скалирования) на указанный размер - будет выбран соответствующий формат бумаги. Значение - целое число. По умолчанию = 10 мм
49 | - Удалять неинициализированые листы - Удалять ли листы, на которые ни разу не заходил пользователь
50 | - Оставаться в модели по окончании работы - Возвращать ли пользователя в модель по окончании работы программы
51 |
52 | Опции ком. строки:
53 | - Undo - Отменить выбор последней рамки
54 | - Newscale - Задать новый масштаб рамки
55 | - Process - Выполнить создание листов
56 | - Configuration - Вызвать диалог конфигурации
57 | - useTemplate - Для создания листов использовать ранее выбранный шаблонный файл
58 | - templateSelect - Выбрать шаблонный файл. Переменная FILEDIA влияет на вид запроса (можно использовать в макросах)
59 |
60 | Известные проблемы:
61 | - Если настройки листа подразумевают область печати Extents, и стоит галка Fit to paper - возможно неправильное отображение области бумаги в пространстве листа. На печать не влияет
62 | - Пока больше ничего не вспомнить
63 |
64 |
65 | http://mind42.com/mindmap/941c4e75-f2c4-4743-864a-59fb15820f95?rel=url
--------------------------------------------------------------------------------