프로젝트

일반

사용자정보

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

hytos / ID2.Manager / ID2.Manager.Compare / Controls / Verification.cs @ 288ed615

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

1
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 string RevCloudLayer { get; } = "RevCloud";
35
        private static Color RevCloudColor = Color.Magenta;
36
        private static Color DiffColor = Color.Yellow;
37
        
38
        private static double Tolerance = 0;
39
        #endregion
40

    
41
        private RadProgressBarElement _progressBar = null;
42

    
43
        public Verification(RadProgressBarElement progressBar)
44
        {
45
            InitializeComponent();
46

    
47
            this.Load += Verification_Load;
48
            this.radSpinEditorTolerance.ValueChanged += RadSpinEditorTolerance_ValueChanged;
49
            this.radColorBoxAutoCADColor.ValueChanged += RadColorBoxAutoCADColor_ValueChanged;
50
            this.radColorBoxAVEVAColor.ValueChanged += RadColorBoxAVEVAColor_ValueChanged;
51
            this.radColorBoxDiffColor.ValueChanged += RadColorBoxDiffColor_ValueChanged;
52
            this.radColorBoxRevCloudColor.ValueChanged += RadColorBoxRevCloudColor_ValueChanged;
53

    
54
            this.designAutoCAD.ActionMode = actionType.SelectVisibleByPickDynamic;
55
            this.designAutoCAD.ActiveViewport.CoordinateSystemIcon.Visible = false;
56
            this.designAutoCAD.Selection.ColorDynamic = Color.FromArgb(80, Color.OrangeRed);
57
            this.designAutoCAD.Selection.HaloInnerColor = Color.FromArgb(255, Color.OrangeRed);
58
            this.designAutoCAD.Selection.HaloOuterColor = Color.FromArgb(64, Color.OrangeRed);
59
            this.designAutoCAD.Selection.HaloWidthPolygons = 4;
60
            this.designAutoCAD.Selection.HaloWidthWires = 2;
61
            this.designAutoCAD.ActiveViewport.OriginSymbol.Visible = false;
62

    
63
            this.designAVEVA.ActionMode = actionType.SelectVisibleByPickDynamic;
64
            this.designAVEVA.ActiveViewport.CoordinateSystemIcon.Visible = false;
65
            this.designAVEVA.ActiveViewport.OriginSymbol.Visible = false;
66
            this.designCompare.ActionMode = actionType.SelectVisibleByPickDynamic;
67
            this.designCompare.ActiveViewport.CoordinateSystemIcon.Visible = false;
68
            this.designCompare.ActiveViewport.OriginSymbol.Visible = false;
69

    
70
            this.radCheckBoxAutoCAD.CheckStateChanged += RadCheckBoxAutoCAD_CheckStateChanged;
71
            this.radCheckBoxAVEVA.CheckStateChanged += RadCheckBoxAVEVA_CheckStateChanged;
72
            this.radCheckBoxRevCloud.CheckStateChanged += RadCheckBoxRevCloud_CheckStateChanged;
73

    
74
            _progressBar = progressBar;
75

    
76
            #region Camera Sync
77
            this.designAutoCAD.ActiveViewport.Rotate.Enabled = false;
78
            this.designAVEVA.ActiveViewport.Rotate.Enabled = false;
79
            this.designCompare.ActiveViewport.Rotate.Enabled = false;
80

    
81
            this.designAutoCAD.ActiveViewport.ViewCubeIcon.Visible = false;
82
            this.designAVEVA.ActiveViewport.ViewCubeIcon.Visible = false;
83
            this.designCompare.ActiveViewport.ViewCubeIcon.Visible = false;
84

    
85
            this.designAutoCAD.AnimateCamera = false;
86
            this.designAVEVA.AnimateCamera = false;
87
            this.designCompare.AnimateCamera = false;
88

    
89
            this.designAutoCAD.CameraChangedFrequency = 200;
90
            this.designAVEVA.CameraChangedFrequency = 200;
91
            this.designCompare.CameraChangedFrequency = 200;
92

    
93
            this.designAutoCAD.CameraChanged += CameraChanged;
94
            this.designAVEVA.CameraChanged += CameraChanged;
95
            this.designCompare.CameraChanged += CameraChanged;
96
            #endregion
97
        }
98

    
99
        private void RadCheckBoxRevCloud_CheckStateChanged(object sender, EventArgs e)
100
        {
101
            var layer = this.designCompare.Layers.FirstOrDefault(x => x.Name.ToUpper() == Verification.RevCloudLayer.ToUpper());
102
            if (layer != null) layer.Visible = (sender as RadCheckBox).Checked;
103
            this.designCompare.Invalidate();
104
        }
105

    
106
        private void RadCheckBoxAVEVA_CheckStateChanged(object sender, EventArgs e)
107
        {
108
            var layer = this.designCompare.Layers.FirstOrDefault(x => x.Name.ToUpper() == Verification.AVEVALayer.ToUpper());
109
            if (layer != null) layer.Visible = (sender as RadCheckBox).Checked;
110
            this.designCompare.Invalidate();
111
        }
112

    
113
        private void RadCheckBoxAutoCAD_CheckStateChanged(object sender, EventArgs e)
114
        {
115
            var layer = this.designCompare.Layers.FirstOrDefault(x => x.Name.ToUpper() == Verification.AutoCADLayer.ToUpper());
116
            if (layer != null) layer.Visible = (sender as RadCheckBox).Checked;
117
            this.designCompare.Invalidate();
118
        }
119

    
120
        /// <summary>
121
        /// Cloud Mark의 색상을 설정한다.
122
        /// </summary>
123
        /// <param name="sender"></param>
124
        /// <param name="e"></param>
125
        private void RadColorBoxRevCloudColor_ValueChanged(object sender, EventArgs e)
126
        {
127
            Verification.RevCloudColor = this.radColorBoxRevCloudColor.Value;
128
            string color = $"{Verification.RevCloudColor.R},{Verification.RevCloudColor.G},{Verification.RevCloudColor.B}";
129
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "RevCloudColor", color);
130
        }
131

    
132
        /// <summary>
133
        /// 두 도면을 비교하여 결과를 PDF로 출력한다.
134
        /// </summary>
135
        /// <param name="sender"></param>
136
        /// <param name="e"></param>
137
        public void CompareDrawings(IList<Document> docs, bool Save = false)
138
        {
139
            string FileFolder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 
140
                Application.ProductName, "Compare");
141
            if (!System.IO.Directory.Exists(FileFolder)) System.IO.Directory.CreateDirectory(FileFolder);
142

    
143
            try
144
            {
145
                Size? size = new Size();
146
                RadFixedDocument FixedDoc = null;
147
                if (Save)
148
                {
149
                    size = new Size(1920 * 2, 1080 * 2);
150
                    FixedDoc = new RadFixedDocument();
151

    
152
                    designCompare.ActiveViewport.Background.BottomColor = Color.White;
153
                    designCompare.ActiveViewport.Background.TopColor = Color.White;
154
                }
155

    
156
                _progressBar.Maximum = docs.Count();
157
                _progressBar.Value1 = 0;
158
                foreach (var doc in docs)
159
                {
160
                    _progressBar.Text = doc.DocumentNo;
161
                    CompareDrawing(doc, Save);
162

    
163
                    if (Save)
164
                    {
165
                        using (var bmp = this.designCompare.RenderToBitmap(size.Value))
166
                        {
167
                            string FilePath = System.IO.Path.Combine(FileFolder, $"{doc.DocumentNo}.jpg");
168
                            bmp.Save(FilePath, System.Drawing.Imaging.ImageFormat.Jpeg);
169

    
170
                            var page = FixedDoc.Pages.AddPage();
171
                            page.Size = new Telerik.Documents.Primitives.Size(size.Value.Width, size.Value.Height);
172
                            var editor = new FixedContentEditor(page);
173
                            using (FileStream fs = new FileStream(FilePath, FileMode.Open))
174
                            {
175
                                editor.DrawImage(fs);
176
                            }
177
                        }
178
                    }
179

    
180
                    _progressBar.Value1 += 1;
181
                    Application.DoEvents();
182
                }
183

    
184
                if (Save)
185
                {
186
                    RadSaveFileDialog saveFileDialog = new RadSaveFileDialog()
187
                    {
188
                        Filter = "PDF files (*.pdf)|*.pdf",
189
                        RestoreDirectory = true
190
                    };
191
                    if (System.Windows.Forms.DialogResult.OK == saveFileDialog.ShowDialog())
192
                    {
193
                        string selectedFileName = saveFileDialog.FileName;
194

    
195
                        // 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: 
196
                        Telerik.Documents.ImageUtils.ImagePropertiesResolver defaultImagePropertiesResolver = new Telerik.Documents.ImageUtils.ImagePropertiesResolver();
197
                        Telerik.Windows.Documents.Extensibility.FixedExtensibilityManager.ImagePropertiesResolver = defaultImagePropertiesResolver;
198

    
199
                        var provider = new PdfFormatProvider();
200
                        File.WriteAllBytes(selectedFileName, provider.Export(FixedDoc));
201

    
202
                        RadMessageBox.Show("Comparing document is done");
203
                    }
204
                }
205
            }
206
            catch(Exception ex)
207
            {
208
                RadMessageBox.Show(ex.Message);
209
            }
210
            finally
211
            {
212
                designCompare.ActiveViewport.Background.BottomColor = Color.Black;
213
                designCompare.ActiveViewport.Background.TopColor = Color.Black;
214
            }
215
        }
216

    
217
        /// <summary>
218
        /// 서로 다른 엔터티의 색상을 설정한다.
219
        /// </summary>
220
        /// <param name="sender"></param>
221
        /// <param name="e"></param>
222
        private void RadColorBoxDiffColor_ValueChanged(object sender, EventArgs e)
223
        {
224
            Verification.DiffColor = this.radColorBoxDiffColor.Value;
225
            string color = $"{Verification.DiffColor.R},{Verification.DiffColor.G},{Verification.DiffColor.B}";
226
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "DiffColor", color);
227
        }
228

    
229
        /// <summary>
230
        /// AutoCAD 엔터티의 색상을 설정한다.
231
        /// </summary>
232
        /// <param name="sender"></param>
233
        /// <param name="e"></param>
234
        private void RadColorBoxAutoCADColor_ValueChanged(object sender, EventArgs e)
235
        {
236
            Verification.AutoCADColor = this.radColorBoxAutoCADColor.Value;
237
            string color = $"{Verification.AutoCADColor.R},{Verification.AutoCADColor.G},{Verification.AutoCADColor.B}";
238
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "AutoCADColor", color);
239
        }
240

    
241
        /// <summary>
242
        /// AVEVA 엔터티의 색상을 설정한다.
243
        /// </summary>
244
        /// <param name="sender"></param>
245
        /// <param name="e"></param>
246
        private void RadColorBoxAVEVAColor_ValueChanged(object sender, EventArgs e)
247
        {
248
            Verification.AVEVAColor = this.radColorBoxAVEVAColor.Value;
249
            string color = $"{Verification.AVEVAColor.R},{Verification.AVEVAColor.G},{Verification.AVEVAColor.B}";
250
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "AVEVAColor", color);
251
        }
252

    
253
        /// <summary>
254
        /// 수정한 Tolerance를 시스템에 반영한다.
255
        /// </summary>
256
        /// <param name="sender"></param>
257
        /// <param name="e"></param>
258
        private void RadSpinEditorTolerance_ValueChanged(object sender, EventArgs e)
259
        {
260
            double toler = Convert.ToDouble(this.radSpinEditorTolerance.Value);
261
            Classes.ID2Helper.IniWriteValue(IniFilePath, "Verification", "Tolerance", toler.ToString());
262
            Verification.Tolerance = toler;
263
        }
264

    
265
        private void Verification_Load(object sender, EventArgs e)
266
        {
267
            string Toler = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Tolerance");
268
            if (!string.IsNullOrEmpty(Toler))
269
            {
270
                this.radSpinEditorTolerance.Value = Convert.ToDecimal(Toler);
271
                Verification.Tolerance = Convert.ToDouble(this.radSpinEditorTolerance.Value);
272
            }
273

    
274
            string _AutoCADColor = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "AutoCADColor");
275
            if (!string.IsNullOrEmpty(_AutoCADColor))
276
            {
277
                var tokens = _AutoCADColor.Split(',');
278
                if (tokens.Length == 3)
279
                {
280
                    this.radColorBoxAutoCADColor.Value =
281
                         Color.FromArgb(Convert.ToInt32(tokens[0]), Convert.ToInt32(tokens[1]), Convert.ToInt32(tokens[2]));
282
                }
283
            }
284

    
285
            string _AVEVAColor = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "AVEVAColor");
286
            if (!string.IsNullOrEmpty(_AVEVAColor))
287
            {
288
                var tokens = _AVEVAColor.Split(',');
289
                if (tokens.Length == 3)
290
                {
291
                    this.radColorBoxAVEVAColor.Value =
292
                        Color.FromArgb(Convert.ToInt32(tokens[0]), Convert.ToInt32(tokens[1]), Convert.ToInt32(tokens[2]));
293
                }
294
            }
295

    
296
            string _DiffColor = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "DiffColor");
297
            if (!string.IsNullOrEmpty(_DiffColor))
298
            {
299
                var tokens = _DiffColor.Split(',');
300
                if (tokens.Length == 3)
301
                {
302
                    this.radColorBoxDiffColor.Value =
303
                        Color.FromArgb(Convert.ToInt32(tokens[0]), Convert.ToInt32(tokens[1]), Convert.ToInt32(tokens[2]));
304
                }
305
            }
306

    
307
            string _RevCloudColor = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "RevCloudColor");
308
            if (!string.IsNullOrEmpty(_RevCloudColor))
309
            {
310
                var tokens = _RevCloudColor.Split(',');
311
                if (tokens.Length == 3)
312
                {
313
                    this.radColorBoxRevCloudColor.Value =
314
                        Color.FromArgb(Convert.ToInt32(tokens[0]), Convert.ToInt32(tokens[1]), Convert.ToInt32(tokens[2]));
315
                }
316
            }
317

    
318
            #region Except Layer를 로딩한다.
319
            LoadLayerSettings();
320
            #endregion
321
        }
322

    
323
        /// <summary>
324
        /// 레이어 설정을 읽는다.
325
        /// </summary>
326
        public void LoadLayerSettings()
327
        {
328
            Forms.ExceptLayer.ExceptLayers.Clear();
329
            Forms.ExceptLayer.LineLayers.Clear();
330

    
331
            string _ExceptLayers = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers");
332
            if (!string.IsNullOrEmpty(_ExceptLayers))
333
            {
334
                Forms.ExceptLayer.ExceptLayers.AddRange(_ExceptLayers.Split(',').ToList().ConvertAll(x => new Forms.ExceptLayer.Layer(x)));
335

    
336
                string _ExceptLayersVisible = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers Visible");
337
                if (!string.IsNullOrEmpty(_ExceptLayersVisible))
338
                {
339
                    var tokens = _ExceptLayersVisible.Split(',').ToList().ConvertAll(x => Convert.ToBoolean(x));
340
                    for (int i = 0; i < Forms.ExceptLayer.ExceptLayers.Count; ++i)
341
                    {
342
                        if (i < tokens.Count)
343
                        {
344
                            Forms.ExceptLayer.ExceptLayers[i].Visible = tokens[i];
345
                        }
346
                    }
347
                }
348
            }
349

    
350
            string _LineLayers = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Line Layers");
351
            if (!string.IsNullOrEmpty(_LineLayers))
352
            {
353
                Forms.ExceptLayer.LineLayers.AddRange(_LineLayers.Split(',').ToList().ConvertAll(x => new Forms.ExceptLayer.Layer(x)));
354
            }
355
        }
356

    
357
        /// <summary>
358
        /// 엔터티들의 색상을 바꾼다.
359
        /// </summary>
360
        /// <param name="design"></param>
361
        /// <param name="list"></param>
362
        public void ColorEntities(Design design, IList<Entity> list, Color color, colorMethodType colorMethod=colorMethodType.byEntity, bool ChangeBlkColor=true)
363
        {
364
            foreach (Entity ent in list)
365
            {
366
                ColorEntity(design, ent, color, colorMethod, ChangeBlkColor);
367
            }
368
        }
369

    
370
        /// <summary>
371
        /// 엔터티의 색상을 변경한다.
372
        /// </summary>
373
        /// <param name="design"></param>
374
        /// <param name="entity"></param>
375
        /// <param name="color"></param>
376
        private void ColorEntity(Design design, Entity entity, Color color, colorMethodType colorMethod = colorMethodType.byEntity, 
377
            bool ChangeBlkColor = true)
378
        {
379
            if (entity is BlockReference blkref)
380
            {
381
                blkref.Color = color;
382
                blkref.ColorMethod = colorMethod;
383

    
384
                if (ChangeBlkColor)
385
                {
386
                    var blk = design.Blocks.FirstOrDefault(x => x.Name == blkref.BlockName);
387
                    if (blk != null)
388
                    {
389
                        ColorEntities(design, blk.Entities, color, colorMethodType.byParent);
390
                        foreach (var attr in blkref.Attributes.Values)
391
                        {
392
                            attr.Color = color;
393
                            attr.ColorMethod = colorMethodType.byParent;
394
                        }
395
                    }
396
                }
397
            }
398
            else
399
            {
400
                entity.Color = color;
401
                entity.ColorMethod = colorMethod;
402
            }
403
        }
404

    
405
        /// <summary>
406
        /// 주어진 도면의 원본과 AVEVA를 비교한다.
407
        /// </summary>
408
        private void CompareDrawing(Document doc, bool ResultOnly = false)
409
        {
410
            /// AutoCAD P&ID 파일을 화면에 표시한다.
411
            void ShowAutoCADFile(string FilePath, Design design, bool clear = true)
412
            {
413
                if (clear) design.Clear();
414
                if (System.IO.File.Exists(FilePath))
415
                {
416
                    try
417
                    {
418
                        devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(FilePath);
419
                        ra.DoWork();
420
                        var min = ra.Min;
421
                        if (!ra.Layers.Contains(Verification.AutoCADLayer)) ra.Layers.Add(Verification.AutoCADLayer, Verification.AutoCADColor);
422
                        foreach (var ent in ra.Entities)
423
                        {
424
                            /// 도면을 원점으로 맞춘다.
425
                            ent.Translate(-min.X, -min.Y);
426
                        }
427
                        ra.AddToScene(design);
428
                    }
429
                    catch (Exception ex)
430
                    {
431
                        RadMessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, RadMessageIcon.Error);
432
                        return;
433
                    }
434

    
435
                    var AddEntities = new List<Entity>();
436
                    #region LinearPath를 Line으로 분할한다.
437
                    design.Entities.ForEach(x =>
438
                    {
439
                        if (x is LinearPath lp)
440
                        {
441
                            int count = Convert.ToInt32(lp.Vertices.Length);
442
                            for (int i = 0; i < count - 1; ++i)
443
                            {
444
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
445
                                {
446
                                    LayerName = lp.LayerName,
447
                                    LineWeight = lp.LineWeight,
448
                                    LineTypeMethod = colorMethodType.byEntity
449
                                });
450
                            }
451
                        }
452
                    });
453
                    design.Entities.RemoveAll(x => (x is LinearPath));
454
                    design.Entities.AddRange(AddEntities);
455
                    #endregion
456

    
457
                    #region 브랜치가 생성되는 부분에서 파이프 라인을 분할
458
                    var queue = design.Entities.Where(x => x is Line && 
459
                    Forms.ExceptLayer.LineLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper())).ToList();
460
                    while (queue.Any())
461
                    {
462
                        var line1 = queue.First() as Line;
463
                        var dir1 = line1.Direction;
464
                        dir1.Normalize();
465
                        queue.Remove(line1);
466
                        for (int i = 0; i < queue.Count; ++i)
467
                        {
468
                            var line2 = queue.ElementAt(i) as Line;
469
                            var dir2 = line2.Direction;
470
                            dir2.Normalize();
471
                            if (devDept.Geometry.Vector3D.AreOrthogonal(dir1, dir2))
472
                            {
473
                                var intersects = line1.IntersectWith(line2);
474
                                if (intersects.Count() == 1)
475
                                {
476
                                    if (line1.StartPoint.DistanceTo(intersects[0]) > 0.1 && line1.EndPoint.DistanceTo(intersects[0]) > 0.1)
477
                                    {
478
                                        var split1 = new devDept.Eyeshot.Entities.Line(line1.StartPoint, intersects[0])
479
                                        {
480
                                            LayerName = line1.LayerName,
481
                                            LineWeight = line1.LineWeight,
482
                                            LineTypeMethod = colorMethodType.byEntity
483
                                        };
484
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line1.EndPoint)
485
                                        {
486
                                            LayerName = line1.LayerName,
487
                                            LineWeight = line1.LineWeight,
488
                                            LineTypeMethod = colorMethodType.byEntity
489
                                        };
490
                                        design.Entities.Add(split1);
491
                                        design.Entities.Add(split2);
492
                                        design.Entities.Remove(line1);
493

    
494
                                        queue.Add(split1);
495
                                        queue.Add(split2);
496

    
497
                                        break;
498
                                    }
499

    
500
                                    if (line2.StartPoint.DistanceTo(intersects[0]) > 0.1 && line2.EndPoint.DistanceTo(intersects[0]) > 0.1)
501
                                    {
502
                                        var split1 = new devDept.Eyeshot.Entities.Line(line2.StartPoint, intersects[0])
503
                                        {
504
                                            LayerName = line2.LayerName,
505
                                            LineWeight = line2.LineWeight,
506
                                            LineTypeMethod = colorMethodType.byEntity
507
                                        };
508
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line2.EndPoint)
509
                                        {
510
                                            LayerName = line2.LayerName,
511
                                            LineWeight = line2.LineWeight,
512
                                            LineTypeMethod = colorMethodType.byEntity
513
                                        };
514
                                        design.Entities.Add(split1);
515
                                        design.Entities.Add(split2);
516
                                        design.Entities.Remove(line2);
517

    
518
                                        queue.Remove(line2);
519
                                        queue.Add(split1);
520
                                        queue.Add(split2);
521
                                    }
522
                                }
523
                            }
524
                        }
525
                    }
526
                    #endregion
527

    
528
                    #region 레이어 변경
529
                    foreach (var ent in design.Entities)
530
                    {
531
                        ent.Color = Verification.AutoCADColor;
532
                        ent.ColorMethod = colorMethodType.byEntity;
533
                        if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
534
                        {
535
                            ent.LayerName = Verification.AutoCADLayer;
536
                        }
537
                    }
538
                    #endregion
539

    
540
                    #region 블록을 깸
541
                    AddEntities.Clear();
542
                    design.Entities.Where(x => x.LayerName == Verification.AutoCADLayer).ToList().ForEach(x =>
543
                    {
544
                        if (x is BlockReference blkref)
545
                        {
546
                            var entities = blkref.Explode(design.Blocks);
547
                            foreach (var ent in entities) ent.LayerName = Verification.AutoCADLayer;
548
                            entities.ToList().ForEach(y =>
549
                            {
550
                                if (y is LinearPath lp)
551
                                {
552
                                    int count = Convert.ToInt32(lp.Vertices.Length);
553
                                    for (int i = 0; i < count - 1; ++i)
554
                                    {
555
                                        var line = new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
556
                                        {
557
                                            LayerName = lp.LayerName,
558
                                            LineWeight = lp.LineWeight,
559
                                            LineTypeMethod = colorMethodType.byEntity,
560
                                            Color = Verification.AutoCADColor,
561
                                            ColorMethod = colorMethodType.byEntity
562
                                        };
563
                                        AddEntities.Add(line);
564
                                    }
565
                                }
566
                            });
567

    
568
                            var attributes = blkref.Attributes;
569
                            foreach (var ent in entities.Where(y => y is devDept.Eyeshot.Entities.Attribute))
570
                            {
571
                                var txt = ent as devDept.Eyeshot.Entities.Attribute;
572
                                txt.LayerName = Verification.AutoCADLayer;
573
                                txt.Color = Verification.AutoCADColor;
574
                                txt.ColorMethod = colorMethodType.byEntity;
575
                                KeyValuePair<string, AttributeReference>? kp = attributes.FirstOrDefault(z => z.Key == txt.TextString);
576
                                if (kp.HasValue) txt.TextString = (kp.Value.Value) != null ? kp.Value.Value.Value : string.Empty;
577
                            }
578

    
579
                            AddEntities.AddRange(entities.Where(y => 
580
                            {
581
                                if (y is devDept.Eyeshot.Entities.Attribute attr && string.IsNullOrEmpty(attr.TextString)) return false;
582
                                if (y is devDept.Eyeshot.Entities.Text text && string.IsNullOrEmpty(text.TextString)) return false;
583
                                if (y is LinearPath) return false;
584
                                return true;
585
                            }));
586

    
587
                            blkref.Attributes.Clear();
588
                            blkref.UpdateBoundingBox(new TraversalParams(design));
589
                        }
590
                    });
591

    
592
                    design.Entities.RemoveAll(x => (x is BlockReference) || Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
593
                    design.Entities.AddRange(AddEntities);
594
                    #endregion
595

    
596
                    ColorEntities(design, design.Entities, Verification.AutoCADColor);
597

    
598
                    // Sets the view as Top
599
                    design.SetView(viewType.Top);
600
                    design.ZoomFit();
601
                    design.Invalidate();
602
                }
603
            }
604

    
605
            /// AVEVA P&ID 파일을 화면에 표시한다.
606
            void ShowAVEVAPIDFile(string FilePath, Design design, bool clear = true)
607
            {
608
                if (clear) design.Clear();
609
                if (System.IO.File.Exists(FilePath))
610
                {
611
                    devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(FilePath);
612
                    ra.DoWork();
613
                    var min = ra.Min;
614
                    var AddEntities = new List<Entity>();
615

    
616
                    if (!ra.Layers.Contains(Verification.AVEVALayer)) ra.Layers.Add(Verification.AVEVALayer, Verification.AVEVAColor);
617
                    foreach (var ent in ra.Entities)
618
                    {
619
                        /// 도면을 원점으로 맞춘다.
620
                        ent.Translate(-min.X, -min.Y);
621

    
622
                        #region 멀티 라인들을 분할하여 추가한다.
623
                        if (ent is Mesh mesh && (mesh.LayerName == "AS_PIPE" || mesh.LayerName == "AS_INST"))
624
                        {
625
                            int count = Convert.ToInt32(mesh.Vertices.Length * 0.5);
626
                            for (int i = 0; i < count - 1; ++i)
627
                            {
628
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(mesh.Vertices[i], mesh.Vertices[i + 1])
629
                                {
630
                                    LayerName = Verification.AVEVALayer,
631
                                    LineWeight = 3.0f,
632
                                    LineTypeMethod = colorMethodType.byEntity,
633
                                    Color = Verification.AVEVAColor,
634
                                    ColorMethod = colorMethodType.byEntity
635
                                });
636
                            }
637
                        }
638
                        else if (ent is TabulatedSurface tf && (tf.LayerName == "AS_PIPE" || tf.LayerName == "AS_INST"))
639
                        {
640
                            int count = Convert.ToInt32(tf.ControlPoints.Length * 0.5);
641
                            for (int i = 0; i < count - 1; ++i)
642
                            {
643
                                AddEntities.Add(
644
                                    new devDept.Eyeshot.Entities.Line(
645
                                    new devDept.Geometry.Point3D(tf.ControlPoints[i, 0].X, tf.ControlPoints[i, 0].Y, 0),
646
                                    new devDept.Geometry.Point3D(tf.ControlPoints[i + 1, 0].X, tf.ControlPoints[i + 1, 0].Y, 0))
647
                                    {
648
                                        LayerName = Verification.AVEVALayer,
649
                                        LineWeight = 3.0f,
650
                                        LineTypeMethod = colorMethodType.byEntity,
651
                                        Color = Verification.AVEVAColor,
652
                                        ColorMethod = colorMethodType.byEntity
653
                                    }
654
                                );
655
                            }
656
                        }
657
                        else if (ent is LinearPath lp)
658
                        {
659
                            int count = Convert.ToInt32(lp.Vertices.Length);
660
                            for (int i = 0; i < count - 1; ++i)
661
                            {
662
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
663
                                {
664
                                    LayerName = Verification.AVEVALayer,
665
                                    LineWeight = lp.LineWeight,
666
                                    Color = Verification.AVEVAColor,
667
                                    LineTypeMethod = colorMethodType.byEntity
668
                                });
669
                            }
670
                        }
671
                        #endregion
672

    
673
                        ent.Color = Verification.AVEVAColor;
674
                        ent.ColorMethod = colorMethodType.byEntity;
675
                        if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
676
                        {
677
                            ent.LayerName = Verification.AVEVALayer;
678
                        }
679
                    }
680
                    ra.AddToScene(design);
681

    
682
                    #region 블럭을 깸
683
                    design.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList().ForEach(x =>
684
                    {
685
                        if(x is BlockReference blkref)
686
                        {
687
                            var attributes = blkref.Attributes;
688
                            var entities = blkref.Explode(design.Blocks);
689
                            entities.ToList().ForEach(y =>
690
                            {
691
                                if (y is LinearPath lp)
692
                                {
693
                                    int count = Convert.ToInt32(lp.Vertices.Length);
694
                                    for (int i = 0; i < count - 1; ++i)
695
                                    {
696
                                        var line = new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
697
                                        {
698
                                            LayerName = Verification.AVEVALayer,
699
                                            LineWeight = lp.LineWeight,
700
                                            LineTypeMethod = colorMethodType.byEntity,
701
                                            Color = Verification.AVEVAColor,
702
                                            ColorMethod = colorMethodType.byEntity
703
                                        };
704
                                        AddEntities.Add(line);
705
                                    }
706
                                }
707
                                else
708
                                {
709
                                    y.LayerName = Verification.AVEVALayer;
710
                                    y.Color = Verification.AVEVAColor;
711
                                    y.ColorMethod = colorMethodType.byEntity;
712
                                }
713
                            });
714

    
715
                            foreach (var ent in entities.Where(y => y is devDept.Eyeshot.Entities.Attribute))
716
                            {
717
                                var txt = ent as devDept.Eyeshot.Entities.Attribute;
718
                                txt.LayerName = Verification.AVEVALayer;
719
                                txt.Color = Verification.AVEVAColor;
720
                                txt.ColorMethod = colorMethodType.byEntity;
721
                                KeyValuePair<string, AttributeReference>? kp = attributes.FirstOrDefault(z => z.Key == txt.TextString);
722
                                if (kp.HasValue) txt.TextString = (kp.Value.Value) != null ? kp.Value.Value.Value : string.Empty;
723
                            }
724

    
725
                            AddEntities.AddRange(entities.Where(y =>
726
                            {
727
                                if (y is devDept.Eyeshot.Entities.Attribute attr && string.IsNullOrEmpty(attr.TextString)) return false;
728
                                if (y is devDept.Eyeshot.Entities.Text text && string.IsNullOrEmpty(text.TextString)) return false;
729
                                if (y is LinearPath) return false;
730
                                return true;
731
                            }));
732
                            blkref.Attributes.Clear();
733
                            blkref.UpdateBoundingBox(new TraversalParams(design));
734
                        }
735
                    });
736
                    design.Entities.RemoveAll(x =>
737
                    ((x is Mesh || x is TabulatedSurface) && (x.LayerName == Verification.AVEVALayer)) ||
738
                    (x is LinearPath && x.LayerName == Verification.AVEVALayer) || (x is BlockReference) ||
739
                    Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
740
                    design.Entities.AddRange(AddEntities);
741
                    #endregion
742

    
743
                    ColorEntities(design, design.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList(), Verification.AVEVAColor);
744

    
745
                    #region 블럭 이름이 PSNODE, PENODE인 블럭은 보이지 않도록 한다.
746
                    design.Entities.ForEach(x =>
747
                    {
748
                        if (x is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE" ||
749
                        blkref.BlockName.StartsWith("ARROW")))
750
                            blkref.Visible = false;
751
                    });
752
                    #endregion
753

    
754
                    design.SetView(viewType.Top);
755
                    design.ZoomFit();
756
                    design.Invalidate();
757
                }
758
            }
759

    
760
            string dwgExtension = ".dwg";
761
            string ID2DrawingFolder = Program.AutoCADFolder;
762
            string dwgFilePath = System.IO.Path.Combine(ID2DrawingFolder, $"{doc.DocumentNo}{dwgExtension}");
763
            if (!ResultOnly) ShowAutoCADFile(dwgFilePath, this.designAutoCAD);
764
            ShowAutoCADFile(dwgFilePath, this.designCompare);
765

    
766
            string AVEVAPIDFolder = Program.AVEVAPIDFolder;
767
            string AVEVAPIDFilePath = string.Empty;
768
            if (AVEVAPIDFolder != null)
769
            {
770
                AVEVAPIDFilePath = System.IO.Path.Combine(AVEVAPIDFolder, $"{doc.DocumentNo}{dwgExtension}");
771
                if (!ResultOnly) ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designAVEVA);
772
                ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designCompare, false);
773
            }
774

    
775
            if (System.IO.File.Exists(dwgFilePath) && System.IO.File.Exists(AVEVAPIDFilePath))
776
            {
777
                var AutoCADEntities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AutoCADLayer).ToList();
778
                var AVEVAtities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList();
779
                CompareAndMark(this.designCompare, AutoCADEntities, this.designCompare, AVEVAtities);
780
                this.designCompare.Entities.ForEach(x => 
781
                {
782
                    if (x.LayerName != Verification.AVEVALayer && x.LayerName != Verification.AutoCADLayer &&
783
                    x.LayerName != Verification.RevCloudLayer) x.LayerName = Verification.AutoCADLayer;
784
                });
785
            }
786
        }
787

    
788
        /// <summary>
789
        /// 주어진 두 엔터티 리스트를 비교하여 틀린 엔터티의 색상을 설정한 색상으로 변경한다.
790
        /// </summary>
791
        /// <param name="entList1"></param>
792
        /// <param name="entList2"></param>
793
        private void CompareAndMark(Design design1, IList<Entity> AutoCADEntities, Design design2, IList<Entity> AVEVAEntities)
794
        {
795
            var DiffRegions = new List<devDept.Eyeshot.OrientedBoundingRect>();
796

    
797
            int[] equalEntitiesInV1 = new int[AVEVAEntities.Count];
798
            bool[] equalEntitiesInV2 = new bool[AVEVAEntities.Count];
799

    
800
            /// 서로 검사 가능한 타입인지 확인한다.
801
            bool CheckType(Entity ent1, Entity ent2)
802
            {
803
                return ent1.GetType() == ent2.GetType() ||
804
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Text) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText)) ||
805
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
806
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Line) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.TabulatedSurface)) ||
807
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
808
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText));
809
            }
810

    
811
            try
812
            {
813
                for (int i = 0; i < AutoCADEntities.Count(); i++)
814
                {
815
                    Entity entVp1 = AutoCADEntities[i];
816
                    bool foundEqual = false;
817

    
818
                    for (int j = 0; j < AVEVAEntities.Count(); j++)
819
                    {
820
                        Entity entVp2 = AVEVAEntities[j];
821

    
822
                        if (entVp2 is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE")) continue;
823
                        if (!equalEntitiesInV2[j] && CheckType(entVp1, entVp2) && 
824
                            CompareIfEqual(design1, entVp1, design2, entVp2))
825
                        {
826
                            equalEntitiesInV1[j] = i;
827
                            equalEntitiesInV2[j] = true;
828
                            foundEqual = true;
829

    
830
                            design2.Entities.Remove(entVp2);
831
                            break;
832
                        }
833
                    }
834
                    if (!foundEqual)
835
                    {
836
                        ColorEntity(design1, AutoCADEntities[i], Verification.DiffColor, colorMethodType.byEntity, false);
837

    
838
                        #region 틀린 엔터티의 BoundingBox를 구함
839
                        var origin = new devDept.Geometry.Point2D(entVp1.BoxMin.X - 1, entVp1.BoxMin.Y - 1);
840
                        double width = entVp1.BoxMax.X - entVp1.BoxMin.X;
841
                        double height = entVp1.BoxMax.Y - entVp1.BoxMin.Y;
842
                        var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
843
                        DiffRegions.Add(rect);
844
                        #endregion
845
                    }
846
                }
847

    
848
                for (int j = 0; j < AVEVAEntities.Count; j++)
849
                {
850
                    if (!equalEntitiesInV2[j])
851
                    {
852
                        ColorEntity(design2, AVEVAEntities[j], Verification.DiffColor, colorMethodType.byEntity, false);
853

    
854
                        #region 틀린 엔터티의 BoundingBox를 구함 
855
                        var origin = new devDept.Geometry.Point2D(AVEVAEntities[j].BoxMin.X - 1, AVEVAEntities[j].BoxMin.Y - 1);
856
                        double width = AVEVAEntities[j].BoxMax.X - AVEVAEntities[j].BoxMin.X;
857
                        double height = AVEVAEntities[j].BoxMax.Y - AVEVAEntities[j].BoxMin.Y;
858
                        var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
859
                        DiffRegions.Add(rect);
860
                        #endregion
861
                    }
862
                }
863

    
864
                #region 인접한 영역을 하나로 합친다.
865
                var queue = new List<devDept.Eyeshot.OrientedBoundingRect>(DiffRegions);
866
                DiffRegions.Clear();
867
                while (queue.Any())
868
                {
869
                    var first = queue[0];
870
                    var FirstMin = first.GetOrigin();
871
                    var FirstMax = FirstMin + first.GetAxis()[0] * first.Size.X + first.GetAxis()[1] * first.Size.Y;
872

    
873
                    queue.Remove(first);
874
                    bool overlap = false;
875
                    for (int i = 0; i < queue.Count; ++i)
876
                    {
877
                        var second = queue[i];
878
                        overlap = devDept.Eyeshot.OrientedBoundingRect.DoOverlapOrTouch(first, second);
879
                        if (overlap)
880
                        {
881
                            var SecondMin = second.GetOrigin();
882
                            var SecondMax = SecondMin + second.GetAxis()[0] * second.Size.X + second.GetAxis()[1] * second.Size.Y;
883

    
884
                            var min = new devDept.Geometry.Point2D(Math.Min(FirstMin.X, SecondMin.X), Math.Min(FirstMin.Y, SecondMin.Y));
885
                            var max = new devDept.Geometry.Point2D(Math.Max(FirstMax.X, SecondMax.X), Math.Max(FirstMax.Y, SecondMax.Y));
886
                            double width = max.X - min.X;
887
                            double height = max.Y - min.Y;
888

    
889
                            #region 두 영역을 합친다.(작업 완료된 영역도 다시 queue에 넣는다.)
890
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(min, width, height);
891
                            queue.Add(rect);
892
                            queue.AddRange(DiffRegions);
893
                            DiffRegions.Clear();
894
                            queue.Remove(second);
895
                            #endregion
896
                            break;
897
                        }
898
                    }
899

    
900
                    if (!overlap) DiffRegions.Add(first);
901
                }
902
                #endregion
903

    
904
                if (!design2.Layers.Contains(Verification.RevCloudLayer))
905
                    design2.Layers.Add(Verification.RevCloudLayer.ToUpper(), Verification.RevCloudColor);
906
                DiffRegions.ForEach(x => DrawRevCloud(design2, x));
907
            }
908
            catch(Exception ex)
909
            {
910
                Console.Write($"Error : {ex.Message}");
911
            }
912
        }
913

    
914
        /// <summary>
915
        /// Revision mark를 그린다.
916
        /// </summary>
917
        /// <param name="design"></param>
918
        /// <param name="obr"></param>
919
        private void DrawRevCloud(Design design, devDept.Eyeshot.OrientedBoundingRect obr)
920
        {
921
            IList<IGCurve> DrawRevCloudLine(devDept.Geometry.Point2D start, devDept.Geometry.Point2D end)
922
            {
923
                var res = new List<IGCurve>();
924

    
925
                var AxisX = new devDept.Geometry.Vector3D(end.X - start.X, end.Y - start.Y);
926
                AxisX.Normalize();
927
                var AxisY = devDept.Geometry.Vector3D.Cross(devDept.Geometry.Vector3D.AxisZ, AxisX);
928

    
929
                double step = 10;
930
                double dist = start.DistanceTo(end);
931
                int count = Convert.ToInt32(dist / step);
932
                if (count == 0 && dist > 0)
933
                {
934
                    var tmp = (start + end) * 0.5;
935

    
936
                    var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
937
                    var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
938
                    GArc arc = new GArc(plane, center, start.DistanceTo(end) * 0.5, Math.PI, Math.PI * 2);
939
                    res.Add(arc);
940
                }
941
                else
942
                {
943
                    for (int i = 0; i < count; ++i)
944
                    {
945
                        var _start = (start + AxisX * i * step);
946
                        var _end = (start + AxisX * (i + 1) * step);
947
                        if (i == count - 1) _end = end;
948
                        var tmp = (_start + _end) * 0.5;
949

    
950
                        var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
951
                        var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
952
                        GArc arc = new GArc(plane, center, _start.DistanceTo(_end) * 0.5, Math.PI, Math.PI * 2);
953
                        res.Add(arc);
954
                    }
955
                }
956

    
957
                return res;
958
            }
959

    
960
            GCompositeCurve profile = new GCompositeCurve();
961

    
962
            var vertices = obr.GetVertices();
963
            for(int i = 0;i < vertices.Length;++i)
964
            {
965
                var curves = DrawRevCloudLine(vertices[i], vertices[(i + 1) % vertices.Length]);
966
                profile.CurveList.AddRange(curves);
967
            }
968

    
969
            var revcloud = new devDept.Eyeshot.Entities.CompositeCurve(profile);
970
            revcloud.LayerName = Verification.RevCloudLayer;
971
            revcloud.Color = Verification.RevCloudColor;
972
            revcloud.ColorMethod = colorMethodType.byEntity;
973
            design.Entities.Add(revcloud);
974
        }
975

    
976
        /// <summary>
977
        /// 주어진 두 엔터티를 비교한다.
978
        /// </summary>
979
        /// <param name="entVp1"></param>
980
        /// <param name="entVp2"></param>
981
        /// <returns></returns>
982
        private bool CompareIfEqual(Design design1, Entity entVp1, Design design2, Entity entVp2)
983
        {
984
            return AreEqual(design1, entVp1, design2, entVp2);
985
        }
986

    
987
        private bool CompareGEntityIfEqual(GEntity entVp1, GEntity entVp2)
988
        {
989
            return AreGEntityEqual(entVp1, entVp2);
990
        }
991

    
992
        /// <summary>
993
        /// 그래픽적으로 두 엔터티가 유사한지 검사한다.
994
        /// </summary>
995
        /// <param name="design1"></param>
996
        /// <param name="ent1"></param>
997
        /// <param name="design2"></param>
998
        /// <param name="ent2"></param>
999
        /// <returns></returns>
1000
        private bool AreEqual(Design design1, Entity ent1, Design design2, Entity ent2)
1001
        {
1002
            if (ent1 is CompositeCurve cc1 && ent2 is CompositeCurve cc2)
1003
            {
1004
                if (cc1.CurveList.Count == cc2.CurveList.Count)
1005
                {
1006
                    int equalCurvesInListCount = 0;
1007
                    foreach (var entC in cc1.CurveList)
1008
                    {
1009
                        foreach (var entC2 in cc2.CurveList)
1010
                        {
1011
                            if (entC.GetType() == entC2.GetType())
1012
                            {
1013
                                if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
1014
                                {
1015
                                    equalCurvesInListCount++;
1016
                                    break;
1017
                                }
1018
                                else if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
1019
                                {
1020
                                    equalCurvesInListCount++;
1021
                                    break;
1022
                                }
1023
                            }
1024
                        }
1025
                    }
1026

    
1027
                    if (cc1.CurveList.Count == equalCurvesInListCount)
1028
                    {
1029
                        return true;
1030
                    }
1031
                }
1032
            }
1033
            else if (ent1 is LinearPath lp1 && ent2 is LinearPath lp2)
1034
            {
1035
                if (lp1.Vertices.Length == lp2.Vertices.Length)
1036
                {
1037
                    for (int i = 0; i < lp1.Vertices.Length; i++)
1038
                    {
1039
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
1040
                            return false;
1041
                    }
1042

    
1043
                    return true;
1044
                }
1045
            }
1046
            else if (ent1 is PlanarEntity pe1 && ent2 is PlanarEntity pe2)
1047
            {
1048
                if (ent1 is Arc arc1 && ent2 is Arc arc2)
1049
                {
1050
                    if (
1051
                        arc1.Center.DistanceTo(arc2.Center) <= Verification.Tolerance &&
1052
                        Math.Abs(arc1.Radius - arc2.Radius) <= Verification.Tolerance &&
1053
                        Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Verification.Tolerance &&
1054
                        Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Verification.Tolerance
1055
                        )
1056
                    {
1057
                        return true;
1058
                    }
1059
                }
1060
                else if (ent1 is Circle c1 && ent2 is Circle c2)
1061
                {
1062
                    if (
1063
                        c1.Center.DistanceTo(c2.Center) <= Verification.Tolerance &&
1064
                        Math.Abs(c1.Radius - c2.Radius) <= Verification.Tolerance
1065
                        )
1066
                    {
1067
                        return true;
1068
                    }
1069
                }
1070
                else if (ent1 is EllipticalArc e1 && ent2 is EllipticalArc e2)
1071
                {
1072
                    if (
1073
                        e1.Center.DistanceTo(e2.Center) <= Verification.Tolerance &&
1074
                        Math.Abs(e1.RadiusX - e2.RadiusX) <= Verification.Tolerance &&
1075
                        Math.Abs(e1.RadiusY - e2.RadiusY) <= Verification.Tolerance &&
1076
                        Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Verification.Tolerance &&
1077
                        Math.Abs(e1.Domain.High - e2.Domain.High) <= Verification.Tolerance
1078
                    )
1079
                    {
1080
                        return true;
1081
                    }
1082
                }
1083
                else if (ent1 is Ellipse el1 && ent2 is Ellipse el2)
1084
                {
1085
                    if (
1086
                        el1.Center.DistanceTo(el2.Center) <= Verification.Tolerance &&
1087
                        Math.Abs(el1.RadiusX - el2.RadiusX) <= Verification.Tolerance &&
1088
                        Math.Abs(el1.RadiusY - el2.RadiusY) <= Verification.Tolerance
1089
                    )
1090
                    {
1091
                        return true;
1092
                    }
1093
                }
1094
                #region 해치는 삽입점만 비교
1095
                else if (ent1 is Hatch hatch1 && ent2 is Hatch hatch2)
1096
                {
1097
                    var center1 = (hatch1.BoxMin + hatch1.BoxMax) * 0.5;
1098
                    center1.Z = 0;
1099
                    var center2 = (hatch2.BoxMin + hatch2.BoxMax) * 0.5;
1100
                    center2.Z = 0;
1101
                    return center1.DistanceTo(center2) < Verification.Tolerance;
1102
                }
1103
                #endregion
1104
                else if (ent1 is Text)
1105
                {
1106
                    if (ent1 is Dimension dim1 && ent2 is Dimension dim2)
1107
                    {
1108
                        if (
1109
                            dim1.InsertionPoint.DistanceTo(dim2.InsertionPoint) <= Verification.Tolerance &&
1110
                            dim1.DimLinePosition.DistanceTo(dim2.DimLinePosition) <= Verification.Tolerance
1111
                            )
1112
                        {
1113
                            if (ent1 is AngularDim ad1 && ent2 is AngularDim ad2)
1114
                            {
1115
                                if (
1116
                                    ad1.ExtLine1.DistanceTo(ad2.ExtLine1) <= Verification.Tolerance &&
1117
                                    ad1.ExtLine2.DistanceTo(ad2.ExtLine2) <= Verification.Tolerance &&
1118
                                    Math.Abs(ad1.StartAngle - ad2.StartAngle) <= Verification.Tolerance &&
1119
                                    Math.Abs(ad1.EndAngle - ad2.EndAngle) <= Verification.Tolerance &&
1120
                                    Math.Abs(ad1.Radius - ad2.Radius) <= Verification.Tolerance
1121
                                    )
1122
                                {
1123
                                    return true;
1124
                                }
1125
                            }
1126
                            else if (ent1 is LinearDim ld1 && ent2 is LinearDim ld2)
1127
                            {
1128
                                if (
1129
                                    ld1.ExtLine1.DistanceTo(ld2.ExtLine1) <= Verification.Tolerance &&
1130
                                    ld1.ExtLine2.DistanceTo(ld2.ExtLine2) <= Verification.Tolerance
1131
                                    )
1132
                                {
1133
                                    return true;
1134
                                }
1135
                            }
1136
                            else if (ent1 is DiametricDim dd1 && ent2 is DiametricDim dd2)
1137
                            {
1138
                                if (
1139
                                    Math.Abs(dd1.Distance - dd2.Distance) <= Verification.Tolerance &&
1140
                                    Math.Abs(dd1.Radius - dd2.Radius) <= Verification.Tolerance &&
1141
                                    Math.Abs(dd1.CenterMarkSize - dd2.CenterMarkSize) <= Verification.Tolerance
1142
                                )
1143
                                {
1144
                                    return true;
1145
                                }
1146
                            }
1147
                            else if (ent1 is RadialDim rd1 && ent2 is RadialDim rd2)
1148
                            {
1149
                                if (
1150
                                    Math.Abs(rd1.Radius - rd2.Radius) <= Verification.Tolerance &&
1151
                                    Math.Abs(rd1.CenterMarkSize - rd2.CenterMarkSize) <= Verification.Tolerance
1152
                                )
1153
                                {
1154
                                    return true;
1155
                                }
1156
                            }
1157
                            else if (ent1 is OrdinateDim od1 && ent2 is OrdinateDim od2)
1158
                            {
1159
                                if (
1160
                                    od1.DefiningPoint.DistanceTo(od2.DefiningPoint) <= Verification.Tolerance &&
1161
                                    od1.Origin.DistanceTo(od2.Origin) <= Verification.Tolerance &&
1162
                                    od1.LeaderEndPoint.DistanceTo(od2.LeaderEndPoint) <= Verification.Tolerance
1163
                                )
1164
                                {
1165
                                    return true;
1166
                                }
1167
                            }
1168
                            else
1169
                            {
1170
                                Console.Write("Type " + ent1.GetType() + " not implemented.");
1171
                                return true;
1172
                            }
1173
                        }
1174
                    }
1175

    
1176
                    else if (ent1 is devDept.Eyeshot.Entities.Attribute att1 && ent2 is devDept.Eyeshot.Entities.Attribute att2)
1177
                    {
1178
                        if (
1179
                            att1.Value == att2.Value &&
1180
                            att1.InsertionPoint.DistanceTo(att2.InsertionPoint) <= Verification.Tolerance
1181
                            )
1182
                        {
1183
                            return true;
1184
                        }
1185
                    }
1186
                    else
1187
                    {
1188
                        Text tx1 = (Text)ent1;
1189
                        Text tx2 = (Text)ent2;
1190

    
1191
                        #region 대소문자, 공백을 무시하여 비교
1192
                        string string1 = tx1.TextString.Trim().ToUpper();
1193
                        string string2 = tx2.TextString.Trim().ToUpper();
1194
                        string1 = System.Text.RegularExpressions.Regex.Replace(string1, @"\s+", "");
1195
                        string2 = System.Text.RegularExpressions.Regex.Replace(string2, @"\s+", "");
1196
                        if (
1197
                            tx1.BoxMin.DistanceTo(tx2.BoxMin) <= Verification.Tolerance &&
1198
                            string1 == string2 &&
1199
                            Math.Abs(tx1.WidthFactor - tx2.WidthFactor) <= Verification.Tolerance &&
1200
                            Math.Abs(tx1.Height - tx2.Height) <= Verification.Tolerance
1201
                            )
1202
                        {
1203
                            return true;
1204
                        }
1205
                        #endregion
1206
                    }
1207
                }
1208
            }
1209
            else if (ent1 is Line line1 && ent2 is Line line2)
1210
            {
1211
                var dir1 = line1.Direction;
1212
                dir1.Normalize();
1213
                var dir2 = line2.Direction;
1214
                dir2.Normalize();
1215
                if (devDept.Geometry.Vector3D.AreParallel(dir1, dir2, 0.1) &&
1216
                    Math.Abs(line1.Length() - line2.Length()) <= 0.1 &&
1217
                    line1.MidPoint.DistanceTo(line2.MidPoint) <= Verification.Tolerance
1218
                )
1219
                {
1220
                    return true;
1221
                }
1222
            }
1223
            else if (ent1 is Line && ent2 is devDept.Eyeshot.Entities.TabulatedSurface lwpolyline && lwpolyline.ControlPoints.Length == 4)
1224
            {
1225
                line1 = ent1 as Line;
1226
                var start = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[0, 0].X, lwpolyline.ControlPoints[0, 0].Y, 0);
1227
                var end = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[1, 0].X, lwpolyline.ControlPoints[1, 0].Y, 0);
1228
                var vec = new devDept.Geometry.Vector3D(start, end);
1229
                vec.Normalize();
1230
                var dir = line1.Direction.Clone() as devDept.Geometry.Vector3D;
1231
                dir.Normalize();
1232

    
1233
                if (
1234
                    devDept.Geometry.Vector3D.AreParallel(dir, vec) &&
1235
                    line1.StartPoint.DistanceTo(start) <= Verification.Tolerance &&
1236
                    line1.EndPoint.DistanceTo(end) <= Verification.Tolerance
1237
                )
1238
                {
1239
                    return true;
1240
                }
1241
            }
1242
            else if (ent1 is devDept.Eyeshot.Entities.Point point1 && ent2 is devDept.Eyeshot.Entities.Point point2)
1243
            {
1244
                if (point1.Position.DistanceTo(point2.Position) <= Verification.Tolerance)
1245
                {
1246
                    return true;
1247
                }
1248
            }
1249
            else if (ent1 is Curve cu1 && ent2 is Curve cu2)
1250
            {
1251
                if (
1252
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1253
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1254
                    cu1.Degree == cu2.Degree
1255
                    )
1256
                {
1257
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1258
                    {
1259
                        if (cu1.ControlPoints[k].DistanceTo(cu2.ControlPoints[k]) > Verification.Tolerance)
1260
                        {
1261
                            return false;
1262
                        }
1263
                    }
1264

    
1265
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
1266
                    {
1267
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
1268
                        {
1269
                            return false;
1270
                        }
1271
                    }
1272

    
1273
                    return true;
1274
                }
1275
            }
1276
            else if (ent1 is Mesh m1 && ent2 is Mesh m2 && m1.Vertices.Count() == m2.Vertices.Count())
1277
            {
1278
                for (int i = 0; i < m1.Vertices.Count(); ++i)
1279
                {
1280
                    if (m1.Vertices[i].DistanceTo(m2.Vertices[i]) > Verification.Tolerance) return false;
1281
                }
1282

    
1283
                return true;
1284
            }
1285
            else if (ent1 is BlockReference blkref1 && ent2 is BlockReference blkref2)
1286
            {
1287
                int equalCurvesInEntityList = 0;
1288

    
1289
                #region Point, Attribute, Text 제거 및 LinePath를 라인으로 분리
1290
                var entities1 = blkref1.Explode(design1.Blocks).Where(x => x.LayerName != "AS_PORT" && !(x is devDept.Eyeshot.Entities.Point) &&
1291
                !(x is devDept.Eyeshot.Entities.Attribute) && !(x is devDept.Eyeshot.Entities.Text)).ToList();
1292
                var coll1 = new List<Entity>();
1293
                entities1.ForEach(x =>
1294
                {
1295
                    if (x is LinearPath lp)
1296
                    {
1297
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1298
                        {
1299
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1300
                            coll1.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1301
                        }
1302
                    }
1303
                    else
1304
                    {
1305
                        coll1.Add(x);
1306
                    }
1307
                });
1308
                #endregion
1309

    
1310
                #region Point 및 Nesting Block 제거 및 LinePath를 라인으로 분리
1311
                var entities2 = blkref2.Explode(design2.Blocks).Where(x => 
1312
                !(x is devDept.Eyeshot.Entities.BlockReference blkref && blkref.BlockName == "PORT") && !(x is devDept.Eyeshot.Entities.Point)).ToList();
1313
                var coll2 = new List<Entity>();
1314
                entities2.ForEach(x =>
1315
                {
1316
                    if (x is LinearPath lp)
1317
                    {
1318
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1319
                        {
1320
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1321
                            coll2.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1322
                        }
1323
                    }
1324
                    else if (x is devDept.Eyeshot.Entities.Attribute attr)
1325
                    {
1326
                        if (!attr.Invisible) coll2.Add(attr);
1327
                    }
1328
                    else if (x.GetType().Name == "AttributeReferenceData")
1329
                    {
1330
                    }
1331
                    else
1332
                    {
1333
                        coll2.Add(x);
1334
                    }
1335
                });
1336
                #endregion
1337

    
1338
                if (coll1.Count != coll2.Count) return false;
1339

    
1340
                foreach (var entC in coll1)
1341
                {
1342
                    foreach (var entC2 in coll2)
1343
                    {
1344
                        if (entC.GetType() == entC2.GetType())
1345
                        {
1346
                            if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
1347
                            {
1348
                                equalCurvesInEntityList++;
1349
                                break;
1350
                            }
1351
                        }
1352
                    }
1353
                }
1354

    
1355
                if (coll1.Count == equalCurvesInEntityList)
1356
                {
1357
                    return true;
1358
                }
1359
            }
1360
            else
1361
            {
1362
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1363
                return false;
1364
            }
1365

    
1366
            return false;
1367
        }
1368

    
1369
        private bool AreGEntityEqual(GEntity ent1, GEntity ent2)
1370
        {
1371
            if (ent1 is GCompositeCurve cc1 && ent2 is GCompositeCurve cc2)
1372
            {
1373
                if (cc1.CurveList.Count == cc2.CurveList.Count)
1374
                {
1375
                    int equalCurvesInListCount = 0;
1376
                    foreach (var entC in cc1.CurveList)
1377
                    {
1378
                        foreach (var entC2 in cc2.CurveList)
1379
                        {
1380
                            if (entC.GetType() == entC2.GetType())
1381
                            {
1382
                                if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
1383
                                {
1384
                                    equalCurvesInListCount++;
1385
                                    break;
1386
                                }
1387
                            }
1388
                        }
1389
                    }
1390

    
1391
                    if (cc1.CurveList.Count == equalCurvesInListCount)
1392
                    {
1393
                        return true;
1394
                    }
1395
                }
1396
            }
1397
            else if (ent1 is GLinearPath lp1 && ent2 is GLinearPath lp2)
1398
            {
1399
                if (lp1.Vertices.Length == lp2.Vertices.Length)
1400
                {
1401
                    for (int i = 0; i < lp1.Vertices.Length; i++)
1402
                    {
1403
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
1404
                            return false;
1405
                    }
1406
                    return true;
1407
                }
1408
            }
1409

    
1410
            else if (ent1 is GPlanarEntity pe1 && ent2 is GPlanarEntity pe2)
1411
            {
1412
                if (
1413
                    pe1.Plane.AxisZ == pe2.Plane.AxisZ &&
1414
                    pe1.Plane.AxisX == pe2.Plane.AxisX
1415
                    )
1416
                {
1417
                    if (ent1 is GArc arc1 && ent2 is GArc arc2)
1418
                    {
1419
                        if (
1420
                            arc1.Center.DistanceTo(arc2.Center) <= Verification.Tolerance &&
1421
                            Math.Abs(arc1.Radius - arc2.Radius) <= Verification.Tolerance &&
1422
                            Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Verification.Tolerance &&
1423
                            Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Verification.Tolerance
1424
                            )
1425
                        {
1426
                            return true;
1427
                        }
1428
                    }
1429
                    else if (ent1 is GCircle c1 && ent2 is GCircle c2)
1430
                    {
1431
                        if (c1.Center.DistanceTo(c2.Center) <= Verification.Tolerance && 
1432
                            Math.Abs(c1.Radius - c2.Radius) <= Verification.Tolerance)
1433
                        {
1434
                            return true;
1435
                        }
1436
                    }
1437
                    else if (ent1 is GEllipticalArc e1 && ent2 is GEllipticalArc e2)
1438
                    {
1439
                        if (
1440
                            e1.Center.DistanceTo(e2.Center) <= Verification.Tolerance &&
1441
                            Math.Abs(e1.RadiusX - e2.RadiusX) <= Verification.Tolerance &&
1442
                            Math.Abs(e1.RadiusY - e2.RadiusY) <= Verification.Tolerance &&
1443
                            Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Verification.Tolerance &&
1444
                            Math.Abs(e1.Domain.High - e2.Domain.High) <= Verification.Tolerance
1445
                        )
1446
                        {
1447
                            return true;
1448
                        }
1449
                    }
1450
                    else if (ent1 is GEllipse el1 && ent2 is GEllipse el2)
1451
                    {
1452
                        if (
1453
                            el1.Center.DistanceTo(el2.Center) <= Verification.Tolerance &&
1454
                            Math.Abs(el1.RadiusX - el2.RadiusX) <= Verification.Tolerance &&
1455
                            Math.Abs(el1.RadiusY - el2.RadiusY) <= Verification.Tolerance
1456
                        )
1457
                        {
1458
                            return true;
1459
                        }
1460
                    }
1461
                    else
1462
                    {
1463
                        Console.Write("Type " + ent1.GetType() + " not implemented.");
1464
                        return true;
1465
                    }
1466
                }
1467
            }
1468

    
1469
            else if (ent1 is GLine line1 && ent2 is GLine line2)
1470
            {
1471
                if (line1.StartPoint.DistanceTo(line2.StartPoint) <= Verification.Tolerance && 
1472
                    line1.EndPoint.DistanceTo(line2.EndPoint) <= Verification.Tolerance
1473
                )
1474
                {
1475
                    return true;
1476
                }
1477
            }
1478
#if NURBS
1479
            else if (ent1 is Curve)
1480
            {
1481
                Curve cu1 = (Curve)ent1;
1482
                Curve cu2 = (Curve)ent2;
1483

    
1484
                if (
1485
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1486
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1487
                    cu1.Degree == cu2.Degree
1488
                    )
1489
                {
1490
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1491
                    {
1492
                        if (cu1.ControlPoints[k] != cu2.ControlPoints[k])
1493
                        {
1494
                            return false;
1495
                        }
1496
                    }
1497

    
1498
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
1499
                    {
1500
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
1501
                        {
1502
                            return false;
1503
                        }
1504
                    }
1505

    
1506
                    return true;
1507
                }
1508
            }
1509
#endif
1510

    
1511
            else
1512
            {
1513
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1514
                return true;
1515
            }
1516
            return false;
1517
        }
1518

    
1519
        #region Camera Sync
1520
        private void CameraChanged(object sender, devDept.Eyeshot.Workspace.CameraMoveEventArgs e)
1521
        {
1522
            if (sender == this.designAutoCAD)
1523
            {
1524
                SyncCamera(this.designAutoCAD, this.designAVEVA);
1525
                SyncCamera(this.designAutoCAD, this.designCompare);
1526
            }
1527
            else if (sender == this.designAVEVA)
1528
            {
1529
                SyncCamera(this.designAVEVA, this.designAutoCAD);
1530
                SyncCamera(this.designAVEVA, this.designCompare);
1531
            }
1532
            else
1533
            {
1534
                SyncCamera(this.designCompare, this.designAutoCAD);
1535
                SyncCamera(this.designCompare, this.designAVEVA);
1536
            }
1537
        }
1538

    
1539
        private void SyncCamera(Design designMovedCamera, Design designCameraToMove)
1540
        {
1541
            Camera savedCamera;
1542
            designMovedCamera.SaveView(out savedCamera);
1543

    
1544
            // restores the camera to the other model
1545
            designCameraToMove.RestoreView(savedCamera);
1546
            designCameraToMove.AdjustNearAndFarPlanes();
1547
            designCameraToMove.Invalidate();
1548
        }
1549
        #endregion
1550
    }
1551
}
클립보드 이미지 추가 (최대 크기: 500 MB)