프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

hytos / ID2.Manager / ID2.Manager.Compare / Controls / Verification.cs @ 2810b131

이력 | 보기 | 이력해설 | 다운로드 (65.2 KB)

1 13a36357 humkyung
using devDept.Eyeshot;
2
using devDept.Eyeshot.Entities;
3
using devDept.Eyeshot.Translators;
4
using devDept.Geometry.Entities;
5
using System;
6
using System.Collections.Generic;
7
using System.ComponentModel;
8
using System.Data;
9
using System.Drawing;
10
using System.IO;
11
using System.Linq;
12
using System.Runtime.InteropServices;
13
using System.Text;
14
using System.Threading.Tasks;
15
using System.Windows.Forms;
16
using Telerik.WinControls;
17
using Telerik.WinControls.UI;
18
using Telerik.Windows.Documents.Fixed.FormatProviders.Pdf;
19
using Telerik.Windows.Documents.Fixed.Model;
20
using Telerik.Windows.Documents.Fixed.Model.Editing;
21
22
namespace ID2.Manager.Controls
23
{
24
    public partial class Verification : UserControl
25
    {
26
        readonly string IniFilePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 
27
            Application.ProductName, $"{Application.ProductName}.ini");
28
29
        #region 기본값
30
        private static string AutoCADLayer { get; } = "AutoCAD";
31
        private static Color AutoCADColor = Color.FromArgb(44, 44, 44);
32
        private static string AVEVALayer { get; } = "AVEVA";
33
        private static Color AVEVAColor = Color.FromArgb(44, 44, 44);
34
        private static Color DiffColor = Color.Yellow;
35
        private static Color RevCloudColor = Color.Magenta;
36
        private static double Tolerance = 0;
37
        #endregion
38
39
        private RadProgressBarElement _progressBar = null;
40
41
        public Verification(RadProgressBarElement progressBar)
42
        {
43
            InitializeComponent();
44
45
            this.Load += Verification_Load;
46
            this.radSpinEditorTolerance.ValueChanged += RadSpinEditorTolerance_ValueChanged;
47
            this.radColorBoxAutoCADColor.ValueChanged += RadColorBoxAutoCADColor_ValueChanged;
48
            this.radColorBoxAVEVAColor.ValueChanged += RadColorBoxAVEVAColor_ValueChanged;
49
            this.radColorBoxDiffColor.ValueChanged += RadColorBoxDiffColor_ValueChanged;
50
            this.radColorBoxRevCloudColor.ValueChanged += RadColorBoxRevCloudColor_ValueChanged;
51
52
            this.designAutoCAD.ActionMode = actionType.SelectVisibleByPickDynamic;
53
            this.designAutoCAD.ActiveViewport.CoordinateSystemIcon.Visible = false;
54
            this.designAutoCAD.Selection.ColorDynamic = Color.FromArgb(80, Color.OrangeRed);
55
            this.designAutoCAD.Selection.HaloInnerColor = Color.FromArgb(255, Color.OrangeRed);
56
            this.designAutoCAD.Selection.HaloOuterColor = Color.FromArgb(64, Color.OrangeRed);
57
            this.designAutoCAD.Selection.HaloWidthPolygons = 4;
58
            this.designAutoCAD.Selection.HaloWidthWires = 2;
59
60
            this.designAVEVA.ActionMode = actionType.SelectVisibleByPickDynamic;
61
            this.designAVEVA.ActiveViewport.CoordinateSystemIcon.Visible = false;
62
            this.designCompare.ActionMode = actionType.SelectVisibleByPickDynamic;
63
            this.designCompare.ActiveViewport.CoordinateSystemIcon.Visible = false;
64
65
            _progressBar = progressBar;
66
67
            #region Camera Sync
68
            this.designAutoCAD.ActiveViewport.Rotate.Enabled = false;
69
            this.designAVEVA.ActiveViewport.Rotate.Enabled = false;
70
            this.designCompare.ActiveViewport.Rotate.Enabled = false;
71
72
            this.designAutoCAD.ActiveViewport.ViewCubeIcon.Visible = false;
73
            this.designAVEVA.ActiveViewport.ViewCubeIcon.Visible = false;
74
            this.designCompare.ActiveViewport.ViewCubeIcon.Visible = false;
75
76
            this.designAutoCAD.AnimateCamera = false;
77
            this.designAVEVA.AnimateCamera = false;
78
            this.designCompare.AnimateCamera = false;
79
80
            this.designAutoCAD.CameraChangedFrequency = 200;
81
            this.designAVEVA.CameraChangedFrequency = 200;
82
            this.designCompare.CameraChangedFrequency = 200;
83
84
            this.designAutoCAD.CameraChanged += CameraChanged;
85
            this.designAVEVA.CameraChanged += CameraChanged;
86
            this.designCompare.CameraChanged += CameraChanged;
87
            #endregion
88
        }
89
90
        /// <summary>
91
        /// Cloud Mark의 색상을 설정한다.
92
        /// </summary>
93
        /// <param name="sender"></param>
94
        /// <param name="e"></param>
95
        private void RadColorBoxRevCloudColor_ValueChanged(object sender, EventArgs e)
96
        {
97
            Verification.RevCloudColor = this.radColorBoxRevCloudColor.Value;
98
            string color = $"{Verification.RevCloudColor.R},{Verification.RevCloudColor.G},{Verification.RevCloudColor.B}";
99
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "RevCloudColor", color);
100
        }
101
102
        /// <summary>
103
        /// 두 도면을 비교하여 결과를 PDF로 출력한다.
104
        /// </summary>
105
        /// <param name="sender"></param>
106
        /// <param name="e"></param>
107
        public void CompareDrawings(IList<Document> docs, bool Save = false)
108
        {
109
            string FileFolder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 
110
                Application.ProductName, "Compare");
111
            if (!System.IO.Directory.Exists(FileFolder)) System.IO.Directory.CreateDirectory(FileFolder);
112
113
            try
114
            {
115
                Size? size = new Size();
116
                RadFixedDocument FixedDoc = null;
117
                if (Save)
118
                {
119
                    size = new Size(1920 * 2, 1080 * 2);
120
                    FixedDoc = new RadFixedDocument();
121
                }
122
123
                _progressBar.Maximum = docs.Count();
124
                _progressBar.Value1 = 0;
125
                foreach (var doc in docs)
126
                {
127
                    _progressBar.Text = doc.DocumentNo;
128
                    CompareDrawing(doc, Save);
129
130
                    if (Save)
131
                    {
132
                        using (var bmp = this.designCompare.RenderToBitmap(size.Value))
133
                        {
134
                            string FilePath = System.IO.Path.Combine(FileFolder, $"{doc.DocumentNo}.jpg");
135
                            bmp.Save(FilePath, System.Drawing.Imaging.ImageFormat.Jpeg);
136
137
                            var page = FixedDoc.Pages.AddPage();
138
                            page.Size = new Telerik.Documents.Primitives.Size(size.Value.Width, size.Value.Height);
139
                            var editor = new FixedContentEditor(page);
140
                            using (FileStream fs = new FileStream(FilePath, FileMode.Open))
141
                            {
142
                                editor.DrawImage(fs);
143
                            }
144
                        }
145
                    }
146
147
                    _progressBar.Value1 += 1;
148
                    Application.DoEvents();
149
                }
150
151
                if (Save)
152
                {
153
                    RadSaveFileDialog saveFileDialog = new RadSaveFileDialog()
154
                    {
155
                        Filter = "PDF files (*.pdf)|*.pdf",
156
                        RestoreDirectory = true
157
                    };
158
                    if (System.Windows.Forms.DialogResult.OK == saveFileDialog.ShowDialog())
159
                    {
160
                        string selectedFileName = saveFileDialog.FileName;
161
162
                        // If you are working in a .NET Core application, you will need to also provide an image resolver. You can use the default implementation provided in Telerik.Documents.ImageUtils: 
163
                        Telerik.Documents.ImageUtils.ImagePropertiesResolver defaultImagePropertiesResolver = new Telerik.Documents.ImageUtils.ImagePropertiesResolver();
164
                        Telerik.Windows.Documents.Extensibility.FixedExtensibilityManager.ImagePropertiesResolver = defaultImagePropertiesResolver;
165
166
                        var provider = new PdfFormatProvider();
167
                        File.WriteAllBytes(selectedFileName, provider.Export(FixedDoc));
168
169
                        RadMessageBox.Show("Comparing document is done");
170
                    }
171
                }
172
            }
173
            catch(Exception ex)
174
            {
175
                RadMessageBox.Show(ex.Message);
176
            }
177
        }
178
179
        /// <summary>
180
        /// 서로 다른 엔터티의 색상을 설정한다.
181
        /// </summary>
182
        /// <param name="sender"></param>
183
        /// <param name="e"></param>
184
        private void RadColorBoxDiffColor_ValueChanged(object sender, EventArgs e)
185
        {
186
            Verification.DiffColor = this.radColorBoxDiffColor.Value;
187
            string color = $"{Verification.DiffColor.R},{Verification.DiffColor.G},{Verification.DiffColor.B}";
188
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "DiffColor", color);
189
        }
190
191
        /// <summary>
192
        /// AutoCAD 엔터티의 색상을 설정한다.
193
        /// </summary>
194
        /// <param name="sender"></param>
195
        /// <param name="e"></param>
196
        private void RadColorBoxAutoCADColor_ValueChanged(object sender, EventArgs e)
197
        {
198
            Verification.AutoCADColor = this.radColorBoxAutoCADColor.Value;
199
            string color = $"{Verification.AutoCADColor.R},{Verification.AutoCADColor.G},{Verification.AutoCADColor.B}";
200
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "AutoCADColor", color);
201
        }
202
203
        /// <summary>
204
        /// AVEVA 엔터티의 색상을 설정한다.
205
        /// </summary>
206
        /// <param name="sender"></param>
207
        /// <param name="e"></param>
208
        private void RadColorBoxAVEVAColor_ValueChanged(object sender, EventArgs e)
209
        {
210
            Verification.AVEVAColor = this.radColorBoxAVEVAColor.Value;
211
            string color = $"{Verification.AVEVAColor.R},{Verification.AVEVAColor.G},{Verification.AVEVAColor.B}";
212
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "AVEVAColor", color);
213
        }
214
215
        /// <summary>
216
        /// 수정한 Tolerance를 시스템에 반영한다.
217
        /// </summary>
218
        /// <param name="sender"></param>
219
        /// <param name="e"></param>
220
        private void RadSpinEditorTolerance_ValueChanged(object sender, EventArgs e)
221
        {
222
            double toler = Convert.ToDouble(this.radSpinEditorTolerance.Value);
223
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "Tolerance", toler.ToString());
224
            Verification.Tolerance = toler;
225
        }
226
227
        private void Verification_Load(object sender, EventArgs e)
228
        {
229
            string Toler = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Tolerance");
230
            if (!string.IsNullOrEmpty(Toler))
231
            {
232
                this.radSpinEditorTolerance.Value = Convert.ToDecimal(Toler);
233
                Verification.Tolerance = Convert.ToDouble(this.radSpinEditorTolerance.Value);
234
            }
235
236
            string _AutoCADColor = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "AutoCADColor");
237
            if (!string.IsNullOrEmpty(_AutoCADColor))
238
            {
239
                var tokens = _AutoCADColor.Split(',');
240
                if (tokens.Length == 3)
241
                {
242
                    this.radColorBoxAutoCADColor.Value =
243
                         Color.FromArgb(Convert.ToInt32(tokens[0]), Convert.ToInt32(tokens[1]), Convert.ToInt32(tokens[2]));
244
                }
245
            }
246
247
            string _AVEVAColor = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "AVEVAColor");
248
            if (!string.IsNullOrEmpty(_AVEVAColor))
249
            {
250
                var tokens = _AVEVAColor.Split(',');
251
                if (tokens.Length == 3)
252
                {
253
                    this.radColorBoxAVEVAColor.Value =
254
                        Color.FromArgb(Convert.ToInt32(tokens[0]), Convert.ToInt32(tokens[1]), Convert.ToInt32(tokens[2]));
255
                }
256
            }
257
258
            string _DiffColor = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "DiffColor");
259
            if (!string.IsNullOrEmpty(_DiffColor))
260
            {
261
                var tokens = _DiffColor.Split(',');
262
                if (tokens.Length == 3)
263
                {
264
                    this.radColorBoxDiffColor.Value =
265
                        Color.FromArgb(Convert.ToInt32(tokens[0]), Convert.ToInt32(tokens[1]), Convert.ToInt32(tokens[2]));
266
                }
267
            }
268
269
            string _RevCloudColor = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "RevCloudColor");
270
            if (!string.IsNullOrEmpty(_RevCloudColor))
271
            {
272
                var tokens = _RevCloudColor.Split(',');
273
                if (tokens.Length == 3)
274
                {
275
                    this.radColorBoxRevCloudColor.Value =
276
                        Color.FromArgb(Convert.ToInt32(tokens[0]), Convert.ToInt32(tokens[1]), Convert.ToInt32(tokens[2]));
277
                }
278
            }
279
280
            designCompare.ActiveViewport.Background.BottomColor = Color.White;
281
            designCompare.ActiveViewport.Background.TopColor = Color.White;
282
283
            #region Except Layer를 로딩한다.
284
            string _ExceptLayers = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers");
285
            if (!string.IsNullOrEmpty(_ExceptLayers))
286
            {
287
                Forms.ExceptLayer.ExceptLayers.AddRange(_ExceptLayers.Split(',').ToList().ConvertAll(x => new Forms.ExceptLayer.Layer(x)));
288
289
                string _ExceptLayersVisible = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers Visible");
290
                if (!string.IsNullOrEmpty(_ExceptLayersVisible))
291
                {
292
                    var tokens = _ExceptLayersVisible.Split(',').ToList().ConvertAll(x => Convert.ToBoolean(x));
293
                    for (int i = 0; i < Forms.ExceptLayer.ExceptLayers.Count; ++i)
294
                    {
295
                        if (i < tokens.Count)
296
                        {
297
                            Forms.ExceptLayer.ExceptLayers[i].Visible = tokens[i];
298
                        }
299
                    }
300
                }
301
            }
302
            #endregion
303
        }
304
305
        /// <summary>
306
        /// 엔터티들의 색상을 바꾼다.
307
        /// </summary>
308
        /// <param name="design"></param>
309
        /// <param name="list"></param>
310
        public void ColorEntities(Design design, IList<Entity> list, Color color, colorMethodType colorMethod=colorMethodType.byEntity, bool ChangeBlkColor=true)
311
        {
312
            foreach (Entity ent in list)
313
            {
314
                ColorEntity(design, ent, color, colorMethod, ChangeBlkColor);
315
            }
316
        }
317
318
        /// <summary>
319
        /// 엔터티의 색상을 변경한다.
320
        /// </summary>
321
        /// <param name="design"></param>
322
        /// <param name="entity"></param>
323
        /// <param name="color"></param>
324
        private void ColorEntity(Design design, Entity entity, Color color, colorMethodType colorMethod = colorMethodType.byEntity, 
325
            bool ChangeBlkColor = true)
326
        {
327
            if (entity is BlockReference blkref)
328
            {
329
                blkref.Color = color;
330
                blkref.ColorMethod = colorMethod;
331
332
                if (ChangeBlkColor)
333
                {
334
                    var blk = design.Blocks.FirstOrDefault(x => x.Name == blkref.BlockName);
335
                    if (blk != null)
336
                    {
337
                        ColorEntities(design, blk.Entities, color, colorMethodType.byParent);
338
                        foreach (var attr in blkref.Attributes.Values)
339
                        {
340
                            attr.Color = color;
341
                            attr.ColorMethod = colorMethodType.byParent;
342
                        }
343
                    }
344
                }
345
            }
346
            else
347
            {
348
                entity.Color = color;
349
                entity.ColorMethod = colorMethod;
350
            }
351
        }
352
353
        /// <summary>
354
        /// 주어진 도면의 원본과 AVEVA를 비교한다.
355
        /// </summary>
356
        private void CompareDrawing(Document doc, bool ResultOnly = false)
357
        {
358
            /// AutoCAD P&ID 파일을 화면에 표시한다.
359
            void ShowAutoCADFile(string FilePath, Design design, bool clear = true)
360
            {
361
                if (clear) design.Clear();
362
                if (System.IO.File.Exists(FilePath))
363
                {
364
                    try
365
                    {
366
                        devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(FilePath);
367
                        ra.DoWork();
368
                        if (!ra.Layers.Contains(Verification.AutoCADLayer)) ra.Layers.Add(Verification.AutoCADLayer, Verification.AutoCADColor);
369
                        foreach (var ent in ra.Entities)
370
                        {
371
                            ent.Color = Verification.AutoCADColor;
372
                            ent.ColorMethod = colorMethodType.byEntity;
373
                            if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
374
                            {
375
                                ent.LayerName = Verification.AutoCADLayer;
376
                            }
377
                        }
378
                        ra.AddToScene(design);
379
                    }
380
                    catch (Exception ex)
381
                    {
382
                        RadMessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, RadMessageIcon.Error);
383
                        return;
384
                    }
385
386
                    var AddEntities = new List<Entity>();
387
                    design.Entities.Where(x => x.LayerName == Verification.AutoCADLayer).ToList().ForEach(x =>
388
                    {
389
                        if (x is LinearPath lp)
390
                        {
391
                            int count = Convert.ToInt32(lp.Vertices.Length);
392
                            for (int i = 0; i < count - 1; ++i)
393
                            {
394
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
395
                                {
396
                                    LayerName = lp.LayerName,
397
                                    LineWeight = lp.LineWeight,
398
                                    LineTypeMethod = colorMethodType.byEntity
399
                                });
400
                            }
401
                        }
402
                        else if (x is BlockReference blkref && blkref.Attributes.Any())
403
                        {
404
                            var attributes = blkref.Attributes;
405
                            var entities = blkref.Explode(design.Blocks);
406
                            foreach (var ent in entities.Where(y => y is devDept.Eyeshot.Entities.Attribute))
407
                            {
408
                                var txt = ent as devDept.Eyeshot.Entities.Attribute;
409
                                txt.LayerName = Verification.AutoCADLayer;
410
                                KeyValuePair<string, AttributeReference>? kp = attributes.FirstOrDefault(z => z.Key == txt.TextString);
411
                                if (kp.HasValue) txt.TextString = (kp.Value.Value) != null ? kp.Value.Value.Value : string.Empty;
412
                            }
413
414
                            AddEntities.AddRange(entities.Where(y => 
415
                            {
416
                                if (y is devDept.Eyeshot.Entities.Attribute attr && !string.IsNullOrEmpty(attr.TextString)) return true;
417
                                if (y is devDept.Eyeshot.Entities.Text text && !string.IsNullOrEmpty(text.TextString)) return true;
418
                                return false;
419
                            }));
420
                            blkref.Attributes.Clear();
421
                            blkref.UpdateBoundingBox(new TraversalParams(design));
422
                        }
423
                    });
424
425
                    #region LinearPath 그리고 Except Layer에 있고 Visible=False 항목 제외
426
                    design.Entities.RemoveAll(x => (x is LinearPath && x.LayerName == Verification.AutoCADLayer) || 
427
                    Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
428
                    #endregion
429
                    design.Entities.AddRange(AddEntities);
430
431
                    #region 브랜치가 생성되는 부분에서 라인을 분할
432
                    var queue = design.Entities.Where(x => x is Line && x.LayerName == Verification.AutoCADLayer).ToList();
433
                    while (queue.Any())
434
                    {
435
                        var line1 = queue.First() as Line;
436
                        var dir1 = line1.Direction;
437
                        dir1.Normalize();
438
                        queue.Remove(line1);
439
                        for (int i = 0; i < queue.Count; ++i)
440
                        {
441
                            var line2 = queue.ElementAt(i) as Line;
442
                            var dir2 = line2.Direction;
443
                            dir2.Normalize();
444
                            if (devDept.Geometry.Vector3D.AreOrthogonal(dir1, dir2))
445
                            {
446
                                var intersects = line1.IntersectWith(line2);
447
                                if (intersects.Count() == 1)
448
                                {
449
                                    if (line1.StartPoint.DistanceTo(intersects[0]) > 0.1 && line1.EndPoint.DistanceTo(intersects[0]) > 0.1)
450
                                    {
451
                                        var split1 = new devDept.Eyeshot.Entities.Line(line1.StartPoint, intersects[0])
452
                                        {
453
                                            LayerName = line1.LayerName,
454
                                            LineWeight = line1.LineWeight,
455
                                            LineTypeMethod = colorMethodType.byEntity
456
                                        };
457
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line1.EndPoint)
458
                                        {
459
                                            LayerName = line1.LayerName,
460
                                            LineWeight = line1.LineWeight,
461
                                            LineTypeMethod = colorMethodType.byEntity
462
                                        };
463
                                        design.Entities.Add(split1);
464
                                        design.Entities.Add(split2);
465
                                        design.Entities.Remove(line1);
466
467
                                        queue.Add(split1);
468
                                        queue.Add(split2);
469
470
                                        break;
471
                                    }
472
473
                                    if (line2.StartPoint.DistanceTo(intersects[0]) > 0.1 && line2.EndPoint.DistanceTo(intersects[0]) > 0.1)
474
                                    {
475
                                        var split1 = new devDept.Eyeshot.Entities.Line(line2.StartPoint, intersects[0])
476
                                        {
477
                                            LayerName = line2.LayerName,
478
                                            LineWeight = line2.LineWeight,
479
                                            LineTypeMethod = colorMethodType.byEntity
480
                                        };
481
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line2.EndPoint)
482
                                        {
483
                                            LayerName = line2.LayerName,
484
                                            LineWeight = line2.LineWeight,
485
                                            LineTypeMethod = colorMethodType.byEntity
486
                                        };
487
                                        design.Entities.Add(split1);
488
                                        design.Entities.Add(split2);
489
                                        design.Entities.Remove(line2);
490
491
                                        queue.Remove(line2);
492
                                        queue.Add(split1);
493
                                        queue.Add(split2);
494
                                    }
495
                                }
496
                            }
497
                        }
498
                    }
499
                    #endregion
500
501
                    ColorEntities(design, design.Entities, Verification.AutoCADColor);
502
503
                    // Sets the view as Top
504
                    design.SetView(viewType.Top);
505
                    design.ZoomFit();
506
                    design.Invalidate();
507
                }
508
            }
509
510
            /// AVEVA P&ID 파일을 화면에 표시한다.
511
            void ShowAVEVAPIDFile(string FilePath, Design design, bool clear = true)
512
            {
513
                if (clear) design.Clear();
514
                if (System.IO.File.Exists(FilePath))
515
                {
516
                    devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(FilePath);
517
                    ra.DoWork();
518
                    if (!ra.Layers.Contains(Verification.AVEVALayer)) ra.Layers.Add(Verification.AVEVALayer, Verification.AVEVAColor);
519
                    foreach (var ent in ra.Entities)
520
                    {
521
                        ent.Color = Verification.AVEVAColor;
522
                        ent.ColorMethod = colorMethodType.byEntity;
523
                        if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
524
                        {
525
                            ent.LayerName = Verification.AVEVALayer;
526
                        }
527
                    }
528
                    ra.AddToScene(design);
529
530
                    #region 멀티 라인들을 분할하여 추가한다.
531
                    var AddEntities = new List<Entity>();
532
                    design.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList().ForEach(x =>
533
                    {
534
                        if (x is Mesh mesh && (mesh.LayerName == "AS_PIPE" || mesh.LayerName == "AS_INST"))
535
                        {
536
                            int count = Convert.ToInt32(mesh.Vertices.Length * 0.5);
537
                            for (int i = 0; i < count - 1; ++i)
538
                            {
539
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(mesh.Vertices[i], mesh.Vertices[i + 1])
540
                                {
541
                                    LayerName = mesh.LayerName,
542
                                    LineWeight = 3.0f,
543
                                    LineTypeMethod = colorMethodType.byEntity,
544
                                    Color = Verification.AVEVAColor,
545
                                    ColorMethod = colorMethodType.byEntity
546
                                });
547
                            }
548
                        }
549
                        else if (x is TabulatedSurface tf && (tf.LayerName == "AS_PIPE" || tf.LayerName == "AS_INST"))
550
                        {
551
                            int count = Convert.ToInt32(tf.ControlPoints.Length * 0.5);
552
                            for (int i = 0; i < count - 1; ++i)
553
                            {
554
                                AddEntities.Add(
555
                                    new devDept.Eyeshot.Entities.Line(
556
                                    new devDept.Geometry.Point3D(tf.ControlPoints[i, 0].X, tf.ControlPoints[i, 0].Y, 0),
557
                                    new devDept.Geometry.Point3D(tf.ControlPoints[i + 1, 0].X, tf.ControlPoints[i + 1, 0].Y, 0))
558
                                    {
559
                                        LayerName = tf.LayerName,
560
                                        LineWeight = 3.0f,
561
                                        LineTypeMethod = colorMethodType.byEntity,
562
                                        Color = Verification.AVEVAColor,
563
                                        ColorMethod = colorMethodType.byEntity
564
                                    }
565
                                );
566
                            }
567
                        }
568
                        else if (x is LinearPath lp)
569
                        {
570
                            int count = Convert.ToInt32(lp.Vertices.Length);
571
                            for (int i = 0; i < count - 1; ++i)
572
                            {
573
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
574
                                {
575
                                    LayerName = lp.LayerName,
576
                                    LineWeight = lp.LineWeight,
577
                                    LineTypeMethod = colorMethodType.byEntity
578
                                });
579
                            }
580
                        }
581
                        else if(x is BlockReference blkref)
582
                        {
583
                            var attributes = blkref.Attributes;
584
                            var entities = blkref.Explode(design.Blocks);
585
                            foreach (var ent in entities.Where(y => y is devDept.Eyeshot.Entities.Attribute))
586
                            {
587
                                var txt = ent as devDept.Eyeshot.Entities.Attribute;
588
                                txt.LayerName = Verification.AVEVALayer;
589
                                KeyValuePair<string, AttributeReference>? kp = attributes.FirstOrDefault(z => z.Key == txt.TextString);
590
                                if (kp.HasValue) txt.TextString = (kp.Value.Value) != null ? kp.Value.Value.Value : string.Empty;
591
                            }
592
593
                            AddEntities.AddRange(entities.Where(y =>
594
                            {
595
                                if (y is devDept.Eyeshot.Entities.Attribute attr && !string.IsNullOrEmpty(attr.TextString)) return true;
596
                                if (y is devDept.Eyeshot.Entities.Text text && !string.IsNullOrEmpty(text.TextString)) return true;
597
                                return false;
598
                            }));
599
                            blkref.Attributes.Clear();
600
                            blkref.UpdateBoundingBox(new TraversalParams(design));
601
                        }
602
                    });
603
                    design.Entities.RemoveAll(x =>
604
                    ((x is Mesh || x is TabulatedSurface) && (x.LayerName == "AS_PIPE" || x.LayerName == "AS_INST")) ||
605
                    (x is LinearPath && x.LayerName == Verification.AVEVALayer) ||
606
                    Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
607
                    design.Entities.AddRange(AddEntities);
608
                    #endregion
609
610
                    ColorEntities(design, design.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList(), Verification.AVEVAColor);
611
612
                    #region 블럭 이름이 PSNODE, PENODE인 블럭은 보이지 않도록 한다.
613
                    design.Entities.ForEach(x =>
614
                    {
615
                        if (x is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE" ||
616
                        blkref.BlockName.StartsWith("ARROW")))
617
                            blkref.Visible = false;
618
                    });
619
                    #endregion
620
621
                    design.SetView(viewType.Top);
622
                    design.ZoomFit();
623
                    design.Invalidate();
624
                }
625
            }
626
627
            string dwgExtension = ".dwg";
628
            string ID2DrawingFolder = Program.AutoCADFolder;
629
            string dwgFilePath = System.IO.Path.Combine(ID2DrawingFolder, $"{doc.DocumentNo}{dwgExtension}");
630
            if (!ResultOnly) ShowAutoCADFile(dwgFilePath, this.designAutoCAD);
631
            ShowAutoCADFile(dwgFilePath, this.designCompare);
632
633
            string AVEVAPIDFolder = Program.AVEVAPIDFolder;
634
            string AVEVAPIDFilePath = string.Empty;
635
            if (AVEVAPIDFolder != null)
636
            {
637
                AVEVAPIDFilePath = System.IO.Path.Combine(AVEVAPIDFolder, $"{doc.DocumentNo}{dwgExtension}");
638
                if (!ResultOnly) ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designAVEVA);
639
                ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designCompare, false);
640
            }
641
642
            if (System.IO.File.Exists(dwgFilePath) && System.IO.File.Exists(AVEVAPIDFilePath))
643
            {
644
                var AutoCADEntities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AutoCADLayer).ToList();
645
                var AVEVAtities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList();
646
                CompareAndMark(this.designCompare, AutoCADEntities, this.designCompare, AVEVAtities);
647
            }
648
        }
649
650
        /// <summary>
651
        /// 주어진 두 엔터티 리스트를 비교하여 틀린 엔터티의 색상을 설정한 색상으로 변경한다.
652
        /// </summary>
653
        /// <param name="entList1"></param>
654
        /// <param name="entList2"></param>
655
        private void CompareAndMark(Design design1, IList<Entity> AutoCADEntities, Design design2, IList<Entity> AVEVAEntities)
656
        {
657
            var DiffRegions = new List<devDept.Eyeshot.OrientedBoundingRect>();
658
659
            int[] equalEntitiesInV1 = new int[AVEVAEntities.Count];
660
            bool[] equalEntitiesInV2 = new bool[AVEVAEntities.Count];
661
662
            /// 서로 검사 가능한 타입인지 확인한다.
663
            bool CheckType(Entity ent1, Entity ent2)
664
            {
665
                return ent1.GetType() == ent2.GetType() ||
666
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Text) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText)) ||
667
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
668
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Line) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.TabulatedSurface)) ||
669
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
670
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText));
671
            }
672
673
            try
674
            {
675
                for (int i = 0; i < AutoCADEntities.Count(); i++)
676
                {
677
                    Entity entVp1 = AutoCADEntities[i];
678
                    bool foundEqual = false;
679
680
                    for (int j = 0; j < AVEVAEntities.Count(); j++)
681
                    {
682
                        Entity entVp2 = AVEVAEntities[j];
683
684
                        if (entVp2 is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE")) continue;
685
                        if (!equalEntitiesInV2[j] && CheckType(entVp1, entVp2) && 
686
                            CompareIfEqual(design1, entVp1, design2, entVp2))
687
                        {
688
                            equalEntitiesInV1[j] = i;
689
                            equalEntitiesInV2[j] = true;
690
                            foundEqual = true;
691
                            break;
692
                        }
693
                    }
694
                    if (!foundEqual)
695
                    {
696
                        ColorEntity(design1, AutoCADEntities[i], Verification.DiffColor, colorMethodType.byEntity, false);
697
698
                        #region 틀린 엔터티의 BoundingBox를 구함
699
                        var origin = new devDept.Geometry.Point2D(entVp1.BoxMin.X - 1, entVp1.BoxMin.Y - 1);
700
                        double width = entVp1.BoxMax.X - entVp1.BoxMin.X;
701
                        double height = entVp1.BoxMax.Y - entVp1.BoxMin.Y;
702
                        var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
703
                        DiffRegions.Add(rect);
704
                        #endregion
705
                    }
706
                }
707
708
                for (int j = 0; j < AVEVAEntities.Count; j++)
709
                {
710
                    if (!equalEntitiesInV2[j])
711
                    {
712
                        ColorEntity(design2, AVEVAEntities[j], Verification.DiffColor, colorMethodType.byEntity, false);
713
714
                        #region 틀린 엔터티의 BoundingBox를 구함 
715
                        var origin = new devDept.Geometry.Point2D(AVEVAEntities[j].BoxMin.X - 1, AVEVAEntities[j].BoxMin.Y - 1);
716
                        double width = AVEVAEntities[j].BoxMax.X - AVEVAEntities[j].BoxMin.X;
717
                        double height = AVEVAEntities[j].BoxMax.Y - AVEVAEntities[j].BoxMin.Y;
718
                        var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
719
                        DiffRegions.Add(rect);
720
                        #endregion
721
                    }
722
                }
723
724
                #region 인접한 영역을 하나로 합친다.
725
                var queue = new List<devDept.Eyeshot.OrientedBoundingRect>(DiffRegions);
726
                DiffRegions.Clear();
727
                while (queue.Any())
728
                {
729
                    var first = queue[0];
730
                    var FirstMin = first.GetOrigin();
731
                    var FirstMax = FirstMin + first.GetAxis()[0] * first.Size.X + first.GetAxis()[1] * first.Size.Y;
732
733
                    queue.Remove(first);
734
                    bool overlap = false;
735
                    for (int i = 0; i < queue.Count; ++i)
736
                    {
737
                        var second = queue[i];
738
                        overlap = devDept.Eyeshot.OrientedBoundingRect.DoOverlapOrTouch(first, second);
739
                        if (overlap)
740
                        {
741
                            var SecondMin = second.GetOrigin();
742
                            var SecondMax = SecondMin + second.GetAxis()[0] * second.Size.X + second.GetAxis()[1] * second.Size.Y;
743
744
                            var min = new devDept.Geometry.Point2D(Math.Min(FirstMin.X, SecondMin.X), Math.Min(FirstMin.Y, SecondMin.Y));
745
                            var max = new devDept.Geometry.Point2D(Math.Max(FirstMax.X, SecondMax.X), Math.Max(FirstMax.Y, SecondMax.Y));
746
                            double width = max.X - min.X;
747
                            double height = max.Y - min.Y;
748
749
                            #region 두 영역을 합친다.(작업 완료된 영역도 다시 queue에 넣는다.)
750
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(min, width, height);
751
                            queue.Add(rect);
752
                            queue.AddRange(DiffRegions);
753
                            DiffRegions.Clear();
754
                            queue.Remove(second);
755
                            #endregion
756
                            break;
757
                        }
758
                    }
759
760
                    if (!overlap) DiffRegions.Add(first);
761
                }
762
                #endregion
763
764
                DiffRegions.ForEach(x => DrawRevCloud(design2, x));
765
            }
766
            catch(Exception ex)
767
            {
768
                Console.Write($"Error : {ex.Message}");
769
            }
770
        }
771
772
        /// <summary>
773
        /// Revision mark를 그린다.
774
        /// </summary>
775
        /// <param name="design"></param>
776
        /// <param name="obr"></param>
777
        private void DrawRevCloud(Design design, devDept.Eyeshot.OrientedBoundingRect obr)
778
        {
779
            IList<IGCurve> DrawRevCloudLine(devDept.Geometry.Point2D start, devDept.Geometry.Point2D end)
780
            {
781
                var res = new List<IGCurve>();
782
783
                var AxisX = new devDept.Geometry.Vector3D(end.X - start.X, end.Y - start.Y);
784
                AxisX.Normalize();
785
                var AxisY = devDept.Geometry.Vector3D.Cross(devDept.Geometry.Vector3D.AxisZ, AxisX);
786
787
                double step = 10;
788
                double dist = start.DistanceTo(end);
789
                int count = Convert.ToInt32(dist / step);
790
                if (count == 0 && dist > 0)
791
                {
792
                    var tmp = (start + end) * 0.5;
793
794
                    var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
795
                    var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
796
                    GArc arc = new GArc(plane, center, start.DistanceTo(end) * 0.5, Math.PI, Math.PI * 2);
797
                    res.Add(arc);
798
                }
799
                else
800
                {
801
                    for (int i = 0; i < count; ++i)
802
                    {
803
                        var _start = (start + AxisX * i * step);
804
                        var _end = (start + AxisX * (i + 1) * step);
805
                        if (i == count - 1) _end = end;
806
                        var tmp = (_start + _end) * 0.5;
807
808
                        var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
809
                        var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
810
                        GArc arc = new GArc(plane, center, _start.DistanceTo(_end) * 0.5, Math.PI, Math.PI * 2);
811
                        res.Add(arc);
812
                    }
813
                }
814
815
                return res;
816
            }
817
818
            GCompositeCurve profile = new GCompositeCurve();
819
820
            var vertices = obr.GetVertices();
821
            for(int i = 0;i < vertices.Length;++i)
822
            {
823
                var curves = DrawRevCloudLine(vertices[i], vertices[(i + 1) % vertices.Length]);
824
                profile.CurveList.AddRange(curves);
825
            }
826
827
            var revcloud = new devDept.Eyeshot.Entities.CompositeCurve(profile);
828
            revcloud.LayerName = "AVEVA";
829
            revcloud.Color = Verification.RevCloudColor;
830
            revcloud.ColorMethod = colorMethodType.byEntity;
831
            design.Entities.Add(revcloud);
832
        }
833
834
        /// <summary>
835
        /// 주어진 두 엔터티를 비교한다.
836
        /// </summary>
837
        /// <param name="entVp1"></param>
838
        /// <param name="entVp2"></param>
839
        /// <returns></returns>
840
        private bool CompareIfEqual(Design design1, Entity entVp1, Design design2, Entity entVp2)
841
        {
842
            return AreEqual(design1, entVp1, design2, entVp2);
843
        }
844
845
        private bool CompareGEntityIfEqual(GEntity entVp1, GEntity entVp2)
846
        {
847
            return AreGEntityEqual(entVp1, entVp2);
848
        }
849
850
        /// <summary>
851
        /// 그래픽적으로 두 엔터티가 유사한지 검사한다.
852
        /// </summary>
853
        /// <param name="design1"></param>
854
        /// <param name="ent1"></param>
855
        /// <param name="design2"></param>
856
        /// <param name="ent2"></param>
857
        /// <returns></returns>
858
        private bool AreEqual(Design design1, Entity ent1, Design design2, Entity ent2)
859
        {
860
            if (ent1 is CompositeCurve cc1 && ent2 is CompositeCurve cc2)
861
            {
862
                if (cc1.CurveList.Count == cc2.CurveList.Count)
863
                {
864
                    int equalCurvesInListCount = 0;
865
                    foreach (var entC in cc1.CurveList)
866
                    {
867
                        foreach (var entC2 in cc2.CurveList)
868
                        {
869
                            if (entC.GetType() == entC2.GetType())
870
                            {
871
                                if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
872
                                {
873
                                    equalCurvesInListCount++;
874
                                    break;
875
                                }
876
                                else if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
877
                                {
878
                                    equalCurvesInListCount++;
879
                                    break;
880
                                }
881
                            }
882
                        }
883
                    }
884
885
                    if (cc1.CurveList.Count == equalCurvesInListCount)
886
                    {
887
                        return true;
888
                    }
889
                }
890
            }
891
            else if (ent1 is LinearPath lp1 && ent2 is LinearPath lp2)
892
            {
893
                if (lp1.Vertices.Length == lp2.Vertices.Length)
894
                {
895
                    for (int i = 0; i < lp1.Vertices.Length; i++)
896
                    {
897
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
898
                            return false;
899
                    }
900
901
                    return true;
902
                }
903
            }
904
            else if (ent1 is PlanarEntity pe1 && ent2 is PlanarEntity pe2)
905
            {
906
                if (ent1 is Arc arc1 && ent2 is Arc arc2)
907
                {
908
                    if (
909
                        arc1.Center.DistanceTo(arc2.Center) <= Verification.Tolerance &&
910
                        Math.Abs(arc1.Radius - arc2.Radius) <= Verification.Tolerance &&
911
                        Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Verification.Tolerance &&
912
                        Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Verification.Tolerance
913
                        )
914
                    {
915
                        return true;
916
                    }
917
                }
918
                else if (ent1 is Circle c1 && ent2 is Circle c2)
919
                {
920
                    if (
921
                        c1.Center.DistanceTo(c2.Center) <= Verification.Tolerance &&
922
                        Math.Abs(c1.Radius - c2.Radius) <= Verification.Tolerance
923
                        )
924
                    {
925
                        return true;
926
                    }
927
                }
928
                else if (ent1 is EllipticalArc e1 && ent2 is EllipticalArc e2)
929
                {
930
                    if (
931
                        e1.Center.DistanceTo(e2.Center) <= Verification.Tolerance &&
932
                        Math.Abs(e1.RadiusX - e2.RadiusX) <= Verification.Tolerance &&
933
                        Math.Abs(e1.RadiusY - e2.RadiusY) <= Verification.Tolerance &&
934
                        Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Verification.Tolerance &&
935
                        Math.Abs(e1.Domain.High - e2.Domain.High) <= Verification.Tolerance
936
                    )
937
                    {
938
                        return true;
939
                    }
940
                }
941
                else if (ent1 is Ellipse el1 && ent2 is Ellipse el2)
942
                {
943
                    if (
944
                        el1.Center.DistanceTo(el2.Center) <= Verification.Tolerance &&
945
                        Math.Abs(el1.RadiusX - el2.RadiusX) <= Verification.Tolerance &&
946
                        Math.Abs(el1.RadiusY - el2.RadiusY) <= Verification.Tolerance
947
                    )
948
                    {
949
                        return true;
950
                    }
951
                }
952
                #region 해치는 삽입점만 비교
953
                else if (ent1 is Hatch hatch1 && ent2 is Hatch hatch2)
954
                {
955
                    return hatch1.PatternOrigin.DistanceTo(hatch2.PatternOrigin) < Verification.Tolerance;
956
                }
957
                #endregion
958
                else if (ent1 is Text)
959
                {
960
                    if (ent1 is Dimension dim1 && ent2 is Dimension dim2)
961
                    {
962
                        if (
963
                            dim1.InsertionPoint.DistanceTo(dim2.InsertionPoint) <= Verification.Tolerance &&
964
                            dim1.DimLinePosition.DistanceTo(dim2.DimLinePosition) <= Verification.Tolerance
965
                            )
966
                        {
967
                            if (ent1 is AngularDim ad1 && ent2 is AngularDim ad2)
968
                            {
969
                                if (
970
                                    ad1.ExtLine1.DistanceTo(ad2.ExtLine1) <= Verification.Tolerance &&
971
                                    ad1.ExtLine2.DistanceTo(ad2.ExtLine2) <= Verification.Tolerance &&
972
                                    Math.Abs(ad1.StartAngle - ad2.StartAngle) <= Verification.Tolerance &&
973
                                    Math.Abs(ad1.EndAngle - ad2.EndAngle) <= Verification.Tolerance &&
974
                                    Math.Abs(ad1.Radius - ad2.Radius) <= Verification.Tolerance
975
                                    )
976
                                {
977
                                    return true;
978
                                }
979
                            }
980
                            else if (ent1 is LinearDim ld1 && ent2 is LinearDim ld2)
981
                            {
982
                                if (
983
                                    ld1.ExtLine1.DistanceTo(ld2.ExtLine1) <= Verification.Tolerance &&
984
                                    ld1.ExtLine2.DistanceTo(ld2.ExtLine2) <= Verification.Tolerance
985
                                    )
986
                                {
987
                                    return true;
988
                                }
989
                            }
990
                            else if (ent1 is DiametricDim dd1 && ent2 is DiametricDim dd2)
991
                            {
992
                                if (
993
                                    Math.Abs(dd1.Distance - dd2.Distance) <= Verification.Tolerance &&
994
                                    Math.Abs(dd1.Radius - dd2.Radius) <= Verification.Tolerance &&
995
                                    Math.Abs(dd1.CenterMarkSize - dd2.CenterMarkSize) <= Verification.Tolerance
996
                                )
997
                                {
998
                                    return true;
999
                                }
1000
                            }
1001
                            else if (ent1 is RadialDim rd1 && ent2 is RadialDim rd2)
1002
                            {
1003
                                if (
1004
                                    Math.Abs(rd1.Radius - rd2.Radius) <= Verification.Tolerance &&
1005
                                    Math.Abs(rd1.CenterMarkSize - rd2.CenterMarkSize) <= Verification.Tolerance
1006
                                )
1007
                                {
1008
                                    return true;
1009
                                }
1010
                            }
1011
                            else if (ent1 is OrdinateDim od1 && ent2 is OrdinateDim od2)
1012
                            {
1013
                                if (
1014
                                    od1.DefiningPoint.DistanceTo(od2.DefiningPoint) <= Verification.Tolerance &&
1015
                                    od1.Origin.DistanceTo(od2.Origin) <= Verification.Tolerance &&
1016
                                    od1.LeaderEndPoint.DistanceTo(od2.LeaderEndPoint) <= Verification.Tolerance
1017
                                )
1018
                                {
1019
                                    return true;
1020
                                }
1021
                            }
1022
                            else
1023
                            {
1024
                                Console.Write("Type " + ent1.GetType() + " not implemented.");
1025
                                return true;
1026
                            }
1027
                        }
1028
                    }
1029
1030
                    else if (ent1 is devDept.Eyeshot.Entities.Attribute att1 && ent2 is devDept.Eyeshot.Entities.Attribute att2)
1031
                    {
1032
                        if (
1033
                            att1.Value == att2.Value &&
1034
                            att1.InsertionPoint.DistanceTo(att2.InsertionPoint) <= Verification.Tolerance
1035
                            )
1036
                        {
1037
                            return true;
1038
                        }
1039
                    }
1040
                    else
1041
                    {
1042
                        Text tx1 = (Text)ent1;
1043
                        Text tx2 = (Text)ent2;
1044
1045
                        #region 대소문자, 공백을 무시하여 비교
1046
                        string string1 = tx1.TextString.Trim().ToUpper();
1047
                        string string2 = tx2.TextString.Trim().ToUpper();
1048
                        string1 = System.Text.RegularExpressions.Regex.Replace(string1, @"\s+", "");
1049
                        string2 = System.Text.RegularExpressions.Regex.Replace(string2, @"\s+", "");
1050
                        if (
1051
                            tx1.BoxMin.DistanceTo(tx2.BoxMin) <= Verification.Tolerance &&
1052
                            string1 == string2 &&
1053
                            Math.Abs(tx1.WidthFactor - tx2.WidthFactor) <= Verification.Tolerance &&
1054
                            Math.Abs(tx1.Height - tx2.Height) <= Verification.Tolerance
1055
                            )
1056
                        {
1057
                            return true;
1058
                        }
1059
                        #endregion
1060
                    }
1061
                }
1062
            }
1063
            else if (ent1 is Line line1 && ent2 is Line line2)
1064
            {
1065
                var dir1 = line1.Direction;
1066
                dir1.Normalize();
1067
                var dir2 = line2.Direction;
1068
                dir2.Normalize();
1069
                if (devDept.Geometry.Vector3D.AreParallel(dir1, dir2, 0.1) &&
1070
                    Math.Abs(line1.Length() - line2.Length()) <= Verification.Tolerance &&
1071
                    line1.MidPoint.DistanceTo(line2.MidPoint) <= Verification.Tolerance
1072
                )
1073
                {
1074
                    return true;
1075
                }
1076
            }
1077
            else if (ent1 is Line && ent2 is devDept.Eyeshot.Entities.TabulatedSurface lwpolyline && lwpolyline.ControlPoints.Length == 4)
1078
            {
1079
                line1 = ent1 as Line;
1080
                var start = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[0, 0].X, lwpolyline.ControlPoints[0, 0].Y, 0);
1081
                var end = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[1, 0].X, lwpolyline.ControlPoints[1, 0].Y, 0);
1082
                var vec = new devDept.Geometry.Vector3D(start, end);
1083
                vec.Normalize();
1084
                var dir = line1.Direction.Clone() as devDept.Geometry.Vector3D;
1085
                dir.Normalize();
1086
1087
                if (
1088
                    devDept.Geometry.Vector3D.AreParallel(dir, vec) &&
1089
                    line1.StartPoint.DistanceTo(start) <= Verification.Tolerance &&
1090
                    line1.EndPoint.DistanceTo(end) <= Verification.Tolerance
1091
                )
1092
                {
1093
                    return true;
1094
                }
1095
            }
1096
            else if (ent1 is devDept.Eyeshot.Entities.Point point1 && ent2 is devDept.Eyeshot.Entities.Point point2)
1097
            {
1098
                if (point1.Position.DistanceTo(point2.Position) <= Verification.Tolerance)
1099
                {
1100
                    return true;
1101
                }
1102
            }
1103
            else if (ent1 is Curve cu1 && ent2 is Curve cu2)
1104
            {
1105
                if (
1106
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1107
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1108
                    cu1.Degree == cu2.Degree
1109
                    )
1110
                {
1111
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1112
                    {
1113
                        if (cu1.ControlPoints[k].DistanceTo(cu2.ControlPoints[k]) > Verification.Tolerance)
1114
                        {
1115
                            return false;
1116
                        }
1117
                    }
1118
1119
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
1120
                    {
1121
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
1122
                        {
1123
                            return false;
1124
                        }
1125
                    }
1126
1127
                    return true;
1128
                }
1129
            }
1130
            else if (ent1 is Mesh m1 && ent2 is Mesh m2 && m1.Vertices.Count() == m2.Vertices.Count())
1131
            {
1132
                for (int i = 0; i < m1.Vertices.Count(); ++i)
1133
                {
1134
                    if (m1.Vertices[i].DistanceTo(m2.Vertices[i]) > Verification.Tolerance) return false;
1135
                }
1136
1137
                return true;
1138
            }
1139
            else if (ent1 is BlockReference blkref1 && ent2 is BlockReference blkref2)
1140
            {
1141
                int equalCurvesInEntityList = 0;
1142
1143
                #region Point, Attribute, Text 제거 및 LinePath를 라인으로 분리
1144
                var entities1 = blkref1.Explode(design1.Blocks).Where(x => x.LayerName != "AS_PORT" && !(x is devDept.Eyeshot.Entities.Point) &&
1145
                !(x is devDept.Eyeshot.Entities.Attribute) && !(x is devDept.Eyeshot.Entities.Text)).ToList();
1146
                var coll1 = new List<Entity>();
1147
                entities1.ForEach(x =>
1148
                {
1149
                    if (x is LinearPath lp)
1150
                    {
1151
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1152
                        {
1153
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1154
                            coll1.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1155
                        }
1156
                    }
1157
                    else
1158
                    {
1159
                        coll1.Add(x);
1160
                    }
1161
                });
1162
                #endregion
1163
1164
                #region Point 및 Nesting Block 제거 및 LinePath를 라인으로 분리
1165
                var entities2 = blkref2.Explode(design2.Blocks).Where(x => 
1166
                !(x is devDept.Eyeshot.Entities.BlockReference blkref && blkref.BlockName == "PORT") && !(x is devDept.Eyeshot.Entities.Point)).ToList();
1167
                var coll2 = new List<Entity>();
1168
                entities2.ForEach(x =>
1169
                {
1170
                    if (x is LinearPath lp)
1171
                    {
1172
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1173
                        {
1174
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1175
                            coll2.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1176
                        }
1177
                    }
1178
                    else if (x is devDept.Eyeshot.Entities.Attribute attr)
1179
                    {
1180
                        if (!attr.Invisible) coll2.Add(attr);
1181
                    }
1182
                    else if (x.GetType().Name == "AttributeReferenceData")
1183
                    {
1184
                    }
1185
                    else
1186
                    {
1187
                        coll2.Add(x);
1188
                    }
1189
                });
1190
                #endregion
1191
1192
                if (coll1.Count != coll2.Count) return false;
1193
1194
                foreach (var entC in coll1)
1195
                {
1196
                    foreach (var entC2 in coll2)
1197
                    {
1198
                        if (entC.GetType() == entC2.GetType())
1199
                        {
1200
                            if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
1201
                            {
1202
                                equalCurvesInEntityList++;
1203
                                break;
1204
                            }
1205
                        }
1206
                    }
1207
                }
1208
1209
                if (coll1.Count == equalCurvesInEntityList)
1210
                {
1211
                    return true;
1212
                }
1213
            }
1214
            else
1215
            {
1216
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1217
                return false;
1218
            }
1219
1220
            return false;
1221
        }
1222
1223
        private bool AreGEntityEqual(GEntity ent1, GEntity ent2)
1224
        {
1225
            if (ent1 is GCompositeCurve cc1 && ent2 is GCompositeCurve cc2)
1226
            {
1227
                if (cc1.CurveList.Count == cc2.CurveList.Count)
1228
                {
1229
                    int equalCurvesInListCount = 0;
1230
                    foreach (var entC in cc1.CurveList)
1231
                    {
1232
                        foreach (var entC2 in cc2.CurveList)
1233
                        {
1234
                            if (entC.GetType() == entC2.GetType())
1235
                            {
1236
                                if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
1237
                                {
1238
                                    equalCurvesInListCount++;
1239
                                    break;
1240
                                }
1241
                            }
1242
                        }
1243
                    }
1244
1245
                    if (cc1.CurveList.Count == equalCurvesInListCount)
1246
                    {
1247
                        return true;
1248
                    }
1249
                }
1250
            }
1251
            else if (ent1 is GLinearPath lp1 && ent2 is GLinearPath lp2)
1252
            {
1253
                if (lp1.Vertices.Length == lp2.Vertices.Length)
1254
                {
1255
                    for (int i = 0; i < lp1.Vertices.Length; i++)
1256
                    {
1257
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
1258
                            return false;
1259
                    }
1260
                    return true;
1261
                }
1262
            }
1263
1264
            else if (ent1 is GPlanarEntity pe1 && ent2 is GPlanarEntity pe2)
1265
            {
1266
                if (
1267
                    pe1.Plane.AxisZ == pe2.Plane.AxisZ &&
1268
                    pe1.Plane.AxisX == pe2.Plane.AxisX
1269
                    )
1270
                {
1271
                    if (ent1 is GArc arc1 && ent2 is GArc arc2)
1272
                    {
1273
                        if (
1274
                            arc1.Center.DistanceTo(arc2.Center) <= Verification.Tolerance &&
1275
                            Math.Abs(arc1.Radius - arc2.Radius) <= Verification.Tolerance &&
1276
                            Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Verification.Tolerance &&
1277
                            Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Verification.Tolerance
1278
                            )
1279
                        {
1280
                            return true;
1281
                        }
1282
                    }
1283
                    else if (ent1 is GCircle c1 && ent2 is GCircle c2)
1284
                    {
1285
                        if (c1.Center.DistanceTo(c2.Center) <= Verification.Tolerance && 
1286
                            Math.Abs(c1.Radius - c2.Radius) <= Verification.Tolerance)
1287
                        {
1288
                            return true;
1289
                        }
1290
                    }
1291
                    else if (ent1 is GEllipticalArc e1 && ent2 is GEllipticalArc e2)
1292
                    {
1293
                        if (
1294
                            e1.Center.DistanceTo(e2.Center) <= Verification.Tolerance &&
1295
                            Math.Abs(e1.RadiusX - e2.RadiusX) <= Verification.Tolerance &&
1296
                            Math.Abs(e1.RadiusY - e2.RadiusY) <= Verification.Tolerance &&
1297
                            Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Verification.Tolerance &&
1298
                            Math.Abs(e1.Domain.High - e2.Domain.High) <= Verification.Tolerance
1299
                        )
1300
                        {
1301
                            return true;
1302
                        }
1303
                    }
1304
                    else if (ent1 is GEllipse el1 && ent2 is GEllipse el2)
1305
                    {
1306
                        if (
1307
                            el1.Center.DistanceTo(el2.Center) <= Verification.Tolerance &&
1308
                            Math.Abs(el1.RadiusX - el2.RadiusX) <= Verification.Tolerance &&
1309
                            Math.Abs(el1.RadiusY - el2.RadiusY) <= Verification.Tolerance
1310
                        )
1311
                        {
1312
                            return true;
1313
                        }
1314
                    }
1315
                    else
1316
                    {
1317
                        Console.Write("Type " + ent1.GetType() + " not implemented.");
1318
                        return true;
1319
                    }
1320
                }
1321
            }
1322
1323
            else if (ent1 is GLine line1 && ent2 is GLine line2)
1324
            {
1325
                if (line1.StartPoint.DistanceTo(line2.StartPoint) <= Verification.Tolerance && 
1326
                    line1.EndPoint.DistanceTo(line2.EndPoint) <= Verification.Tolerance
1327
                )
1328
                {
1329
                    return true;
1330
                }
1331
            }
1332
#if NURBS
1333
            else if (ent1 is Curve)
1334
            {
1335
                Curve cu1 = (Curve)ent1;
1336
                Curve cu2 = (Curve)ent2;
1337
1338
                if (
1339
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1340
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1341
                    cu1.Degree == cu2.Degree
1342
                    )
1343
                {
1344
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1345
                    {
1346
                        if (cu1.ControlPoints[k] != cu2.ControlPoints[k])
1347
                        {
1348
                            return false;
1349
                        }
1350
                    }
1351
1352
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
1353
                    {
1354
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
1355
                        {
1356
                            return false;
1357
                        }
1358
                    }
1359
1360
                    return true;
1361
                }
1362
            }
1363
#endif
1364
1365
            else
1366
            {
1367
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1368
                return true;
1369
            }
1370
            return false;
1371
        }
1372
1373
        #region Camera Sync
1374
        private void CameraChanged(object sender, devDept.Eyeshot.Workspace.CameraMoveEventArgs e)
1375
        {
1376
            if (sender == this.designAutoCAD)
1377
            {
1378
                SyncCamera(this.designAutoCAD, this.designAVEVA);
1379
                SyncCamera(this.designAutoCAD, this.designCompare);
1380
            }
1381
            else if (sender == this.designAVEVA)
1382
            {
1383
                SyncCamera(this.designAVEVA, this.designAutoCAD);
1384
                SyncCamera(this.designAVEVA, this.designCompare);
1385
            }
1386
            else
1387
            {
1388
                SyncCamera(this.designCompare, this.designAutoCAD);
1389
                SyncCamera(this.designCompare, this.designAVEVA);
1390
            }
1391
        }
1392
1393
        private void SyncCamera(Design designMovedCamera, Design designCameraToMove)
1394
        {
1395
            Camera savedCamera;
1396
            designMovedCamera.SaveView(out savedCamera);
1397
1398
            // restores the camera to the other model
1399
            designCameraToMove.RestoreView(savedCamera);
1400
            designCameraToMove.AdjustNearAndFarPlanes();
1401
            designCameraToMove.Invalidate();
1402
        }
1403
        #endregion
1404
    }
1405
}
클립보드 이미지 추가 (최대 크기: 500 MB)