프로젝트

일반

사용자정보

통계
| 개정판:

hytos / ID2.Manager / ID2.Manager.Compare / Controls / Verification.cs @ 4b369ce1

이력 | 보기 | 이력해설 | 다운로드 (65.4 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 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
            LoadLayerSettings();
285
            #endregion
286
        }
287

    
288
        /// <summary>
289
        /// 레이어 설정을 읽는다.
290
        /// </summary>
291
        public void LoadLayerSettings()
292
        {
293
            Forms.ExceptLayer.ExceptLayers.Clear();
294

    
295
            string _ExceptLayers = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers");
296
            if (!string.IsNullOrEmpty(_ExceptLayers))
297
            {
298
                Forms.ExceptLayer.ExceptLayers.AddRange(_ExceptLayers.Split(',').ToList().ConvertAll(x => new Forms.ExceptLayer.Layer(x)));
299

    
300
                string _ExceptLayersVisible = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers Visible");
301
                if (!string.IsNullOrEmpty(_ExceptLayersVisible))
302
                {
303
                    var tokens = _ExceptLayersVisible.Split(',').ToList().ConvertAll(x => Convert.ToBoolean(x));
304
                    for (int i = 0; i < Forms.ExceptLayer.ExceptLayers.Count; ++i)
305
                    {
306
                        if (i < tokens.Count)
307
                        {
308
                            Forms.ExceptLayer.ExceptLayers[i].Visible = tokens[i];
309
                        }
310
                    }
311
                }
312
            }
313
        }
314

    
315
        /// <summary>
316
        /// 엔터티들의 색상을 바꾼다.
317
        /// </summary>
318
        /// <param name="design"></param>
319
        /// <param name="list"></param>
320
        public void ColorEntities(Design design, IList<Entity> list, Color color, colorMethodType colorMethod=colorMethodType.byEntity, bool ChangeBlkColor=true)
321
        {
322
            foreach (Entity ent in list)
323
            {
324
                ColorEntity(design, ent, color, colorMethod, ChangeBlkColor);
325
            }
326
        }
327

    
328
        /// <summary>
329
        /// 엔터티의 색상을 변경한다.
330
        /// </summary>
331
        /// <param name="design"></param>
332
        /// <param name="entity"></param>
333
        /// <param name="color"></param>
334
        private void ColorEntity(Design design, Entity entity, Color color, colorMethodType colorMethod = colorMethodType.byEntity, 
335
            bool ChangeBlkColor = true)
336
        {
337
            if (entity is BlockReference blkref)
338
            {
339
                blkref.Color = color;
340
                blkref.ColorMethod = colorMethod;
341

    
342
                if (ChangeBlkColor)
343
                {
344
                    var blk = design.Blocks.FirstOrDefault(x => x.Name == blkref.BlockName);
345
                    if (blk != null)
346
                    {
347
                        ColorEntities(design, blk.Entities, color, colorMethodType.byParent);
348
                        foreach (var attr in blkref.Attributes.Values)
349
                        {
350
                            attr.Color = color;
351
                            attr.ColorMethod = colorMethodType.byParent;
352
                        }
353
                    }
354
                }
355
            }
356
            else
357
            {
358
                entity.Color = color;
359
                entity.ColorMethod = colorMethod;
360
            }
361
        }
362

    
363
        /// <summary>
364
        /// 주어진 도면의 원본과 AVEVA를 비교한다.
365
        /// </summary>
366
        private void CompareDrawing(Document doc, bool ResultOnly = false)
367
        {
368
            /// AutoCAD P&ID 파일을 화면에 표시한다.
369
            void ShowAutoCADFile(string FilePath, Design design, bool clear = true)
370
            {
371
                if (clear) design.Clear();
372
                if (System.IO.File.Exists(FilePath))
373
                {
374
                    try
375
                    {
376
                        devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(FilePath);
377
                        ra.DoWork();
378
                        if (!ra.Layers.Contains(Verification.AutoCADLayer)) ra.Layers.Add(Verification.AutoCADLayer, Verification.AutoCADColor);
379
                        foreach (var ent in ra.Entities)
380
                        {
381
                            ent.Color = Verification.AutoCADColor;
382
                            ent.ColorMethod = colorMethodType.byEntity;
383
                            if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
384
                            {
385
                                ent.LayerName = Verification.AutoCADLayer;
386
                            }
387
                        }
388
                        ra.AddToScene(design);
389
                    }
390
                    catch (Exception ex)
391
                    {
392
                        RadMessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, RadMessageIcon.Error);
393
                        return;
394
                    }
395

    
396
                    var AddEntities = new List<Entity>();
397
                    design.Entities.Where(x => x.LayerName == Verification.AutoCADLayer).ToList().ForEach(x =>
398
                    {
399
                        if (x is LinearPath lp)
400
                        {
401
                            int count = Convert.ToInt32(lp.Vertices.Length);
402
                            for (int i = 0; i < count - 1; ++i)
403
                            {
404
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
405
                                {
406
                                    LayerName = lp.LayerName,
407
                                    LineWeight = lp.LineWeight,
408
                                    LineTypeMethod = colorMethodType.byEntity
409
                                });
410
                            }
411
                        }
412
                        else if (x is BlockReference blkref && blkref.Attributes.Any())
413
                        {
414
                            var attributes = blkref.Attributes;
415
                            var entities = blkref.Explode(design.Blocks);
416
                            foreach (var ent in entities.Where(y => y is devDept.Eyeshot.Entities.Attribute))
417
                            {
418
                                var txt = ent as devDept.Eyeshot.Entities.Attribute;
419
                                txt.LayerName = Verification.AutoCADLayer;
420
                                KeyValuePair<string, AttributeReference>? kp = attributes.FirstOrDefault(z => z.Key == txt.TextString);
421
                                if (kp.HasValue) txt.TextString = (kp.Value.Value) != null ? kp.Value.Value.Value : string.Empty;
422
                            }
423

    
424
                            AddEntities.AddRange(entities.Where(y => 
425
                            {
426
                                if (y is devDept.Eyeshot.Entities.Attribute attr && !string.IsNullOrEmpty(attr.TextString)) return true;
427
                                if (y is devDept.Eyeshot.Entities.Text text && !string.IsNullOrEmpty(text.TextString)) return true;
428
                                return false;
429
                            }));
430
                            blkref.Attributes.Clear();
431
                            blkref.UpdateBoundingBox(new TraversalParams(design));
432
                        }
433
                    });
434

    
435
                    #region LinearPath 그리고 Except Layer에 있고 Visible=False 항목 제외
436
                    design.Entities.RemoveAll(x => (x is LinearPath && x.LayerName == Verification.AutoCADLayer) || 
437
                    Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
438
                    #endregion
439
                    design.Entities.AddRange(AddEntities);
440

    
441
                    #region 브랜치가 생성되는 부분에서 라인을 분할
442
                    var queue = design.Entities.Where(x => x is Line && x.LayerName == Verification.AutoCADLayer).ToList();
443
                    while (queue.Any())
444
                    {
445
                        var line1 = queue.First() as Line;
446
                        var dir1 = line1.Direction;
447
                        dir1.Normalize();
448
                        queue.Remove(line1);
449
                        for (int i = 0; i < queue.Count; ++i)
450
                        {
451
                            var line2 = queue.ElementAt(i) as Line;
452
                            var dir2 = line2.Direction;
453
                            dir2.Normalize();
454
                            if (devDept.Geometry.Vector3D.AreOrthogonal(dir1, dir2))
455
                            {
456
                                var intersects = line1.IntersectWith(line2);
457
                                if (intersects.Count() == 1)
458
                                {
459
                                    if (line1.StartPoint.DistanceTo(intersects[0]) > 0.1 && line1.EndPoint.DistanceTo(intersects[0]) > 0.1)
460
                                    {
461
                                        var split1 = new devDept.Eyeshot.Entities.Line(line1.StartPoint, intersects[0])
462
                                        {
463
                                            LayerName = line1.LayerName,
464
                                            LineWeight = line1.LineWeight,
465
                                            LineTypeMethod = colorMethodType.byEntity
466
                                        };
467
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line1.EndPoint)
468
                                        {
469
                                            LayerName = line1.LayerName,
470
                                            LineWeight = line1.LineWeight,
471
                                            LineTypeMethod = colorMethodType.byEntity
472
                                        };
473
                                        design.Entities.Add(split1);
474
                                        design.Entities.Add(split2);
475
                                        design.Entities.Remove(line1);
476

    
477
                                        queue.Add(split1);
478
                                        queue.Add(split2);
479

    
480
                                        break;
481
                                    }
482

    
483
                                    if (line2.StartPoint.DistanceTo(intersects[0]) > 0.1 && line2.EndPoint.DistanceTo(intersects[0]) > 0.1)
484
                                    {
485
                                        var split1 = new devDept.Eyeshot.Entities.Line(line2.StartPoint, intersects[0])
486
                                        {
487
                                            LayerName = line2.LayerName,
488
                                            LineWeight = line2.LineWeight,
489
                                            LineTypeMethod = colorMethodType.byEntity
490
                                        };
491
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line2.EndPoint)
492
                                        {
493
                                            LayerName = line2.LayerName,
494
                                            LineWeight = line2.LineWeight,
495
                                            LineTypeMethod = colorMethodType.byEntity
496
                                        };
497
                                        design.Entities.Add(split1);
498
                                        design.Entities.Add(split2);
499
                                        design.Entities.Remove(line2);
500

    
501
                                        queue.Remove(line2);
502
                                        queue.Add(split1);
503
                                        queue.Add(split2);
504
                                    }
505
                                }
506
                            }
507
                        }
508
                    }
509
                    #endregion
510

    
511
                    ColorEntities(design, design.Entities, Verification.AutoCADColor);
512

    
513
                    // Sets the view as Top
514
                    design.SetView(viewType.Top);
515
                    design.ZoomFit();
516
                    design.Invalidate();
517
                }
518
            }
519

    
520
            /// AVEVA P&ID 파일을 화면에 표시한다.
521
            void ShowAVEVAPIDFile(string FilePath, Design design, bool clear = true)
522
            {
523
                if (clear) design.Clear();
524
                if (System.IO.File.Exists(FilePath))
525
                {
526
                    devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(FilePath);
527
                    ra.DoWork();
528
                    if (!ra.Layers.Contains(Verification.AVEVALayer)) ra.Layers.Add(Verification.AVEVALayer, Verification.AVEVAColor);
529
                    foreach (var ent in ra.Entities)
530
                    {
531
                        ent.Color = Verification.AVEVAColor;
532
                        ent.ColorMethod = colorMethodType.byEntity;
533
                        if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
534
                        {
535
                            ent.LayerName = Verification.AVEVALayer;
536
                        }
537
                    }
538
                    ra.AddToScene(design);
539

    
540
                    #region 멀티 라인들을 분할하여 추가한다.
541
                    var AddEntities = new List<Entity>();
542
                    design.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList().ForEach(x =>
543
                    {
544
                        if (x is Mesh mesh && (mesh.LayerName == "AS_PIPE" || mesh.LayerName == "AS_INST"))
545
                        {
546
                            int count = Convert.ToInt32(mesh.Vertices.Length * 0.5);
547
                            for (int i = 0; i < count - 1; ++i)
548
                            {
549
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(mesh.Vertices[i], mesh.Vertices[i + 1])
550
                                {
551
                                    LayerName = mesh.LayerName,
552
                                    LineWeight = 3.0f,
553
                                    LineTypeMethod = colorMethodType.byEntity,
554
                                    Color = Verification.AVEVAColor,
555
                                    ColorMethod = colorMethodType.byEntity
556
                                });
557
                            }
558
                        }
559
                        else if (x is TabulatedSurface tf && (tf.LayerName == "AS_PIPE" || tf.LayerName == "AS_INST"))
560
                        {
561
                            int count = Convert.ToInt32(tf.ControlPoints.Length * 0.5);
562
                            for (int i = 0; i < count - 1; ++i)
563
                            {
564
                                AddEntities.Add(
565
                                    new devDept.Eyeshot.Entities.Line(
566
                                    new devDept.Geometry.Point3D(tf.ControlPoints[i, 0].X, tf.ControlPoints[i, 0].Y, 0),
567
                                    new devDept.Geometry.Point3D(tf.ControlPoints[i + 1, 0].X, tf.ControlPoints[i + 1, 0].Y, 0))
568
                                    {
569
                                        LayerName = tf.LayerName,
570
                                        LineWeight = 3.0f,
571
                                        LineTypeMethod = colorMethodType.byEntity,
572
                                        Color = Verification.AVEVAColor,
573
                                        ColorMethod = colorMethodType.byEntity
574
                                    }
575
                                );
576
                            }
577
                        }
578
                        else if (x is LinearPath lp)
579
                        {
580
                            int count = Convert.ToInt32(lp.Vertices.Length);
581
                            for (int i = 0; i < count - 1; ++i)
582
                            {
583
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
584
                                {
585
                                    LayerName = lp.LayerName,
586
                                    LineWeight = lp.LineWeight,
587
                                    LineTypeMethod = colorMethodType.byEntity
588
                                });
589
                            }
590
                        }
591
                        else if(x is BlockReference blkref)
592
                        {
593
                            var attributes = blkref.Attributes;
594
                            var entities = blkref.Explode(design.Blocks);
595
                            foreach (var ent in entities.Where(y => y is devDept.Eyeshot.Entities.Attribute))
596
                            {
597
                                var txt = ent as devDept.Eyeshot.Entities.Attribute;
598
                                txt.LayerName = Verification.AVEVALayer;
599
                                KeyValuePair<string, AttributeReference>? kp = attributes.FirstOrDefault(z => z.Key == txt.TextString);
600
                                if (kp.HasValue) txt.TextString = (kp.Value.Value) != null ? kp.Value.Value.Value : string.Empty;
601
                            }
602

    
603
                            AddEntities.AddRange(entities.Where(y =>
604
                            {
605
                                if (y is devDept.Eyeshot.Entities.Attribute attr && !string.IsNullOrEmpty(attr.TextString)) return true;
606
                                if (y is devDept.Eyeshot.Entities.Text text && !string.IsNullOrEmpty(text.TextString)) return true;
607
                                return false;
608
                            }));
609
                            blkref.Attributes.Clear();
610
                            blkref.UpdateBoundingBox(new TraversalParams(design));
611
                        }
612
                    });
613
                    design.Entities.RemoveAll(x =>
614
                    ((x is Mesh || x is TabulatedSurface) && (x.LayerName == "AS_PIPE" || x.LayerName == "AS_INST")) ||
615
                    (x is LinearPath && x.LayerName == Verification.AVEVALayer) ||
616
                    Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
617
                    design.Entities.AddRange(AddEntities);
618
                    #endregion
619

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

    
622
                    #region 블럭 이름이 PSNODE, PENODE인 블럭은 보이지 않도록 한다.
623
                    design.Entities.ForEach(x =>
624
                    {
625
                        if (x is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE" ||
626
                        blkref.BlockName.StartsWith("ARROW")))
627
                            blkref.Visible = false;
628
                    });
629
                    #endregion
630

    
631
                    design.SetView(viewType.Top);
632
                    design.ZoomFit();
633
                    design.Invalidate();
634
                }
635
            }
636

    
637
            string dwgExtension = ".dwg";
638
            string ID2DrawingFolder = Program.AutoCADFolder;
639
            string dwgFilePath = System.IO.Path.Combine(ID2DrawingFolder, $"{doc.DocumentNo}{dwgExtension}");
640
            if (!ResultOnly) ShowAutoCADFile(dwgFilePath, this.designAutoCAD);
641
            ShowAutoCADFile(dwgFilePath, this.designCompare);
642

    
643
            string AVEVAPIDFolder = Program.AVEVAPIDFolder;
644
            string AVEVAPIDFilePath = string.Empty;
645
            if (AVEVAPIDFolder != null)
646
            {
647
                AVEVAPIDFilePath = System.IO.Path.Combine(AVEVAPIDFolder, $"{doc.DocumentNo}{dwgExtension}");
648
                if (!ResultOnly) ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designAVEVA);
649
                ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designCompare, false);
650
            }
651

    
652
            if (System.IO.File.Exists(dwgFilePath) && System.IO.File.Exists(AVEVAPIDFilePath))
653
            {
654
                var AutoCADEntities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AutoCADLayer).ToList();
655
                var AVEVAtities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList();
656
                CompareAndMark(this.designCompare, AutoCADEntities, this.designCompare, AVEVAtities);
657
            }
658
        }
659

    
660
        /// <summary>
661
        /// 주어진 두 엔터티 리스트를 비교하여 틀린 엔터티의 색상을 설정한 색상으로 변경한다.
662
        /// </summary>
663
        /// <param name="entList1"></param>
664
        /// <param name="entList2"></param>
665
        private void CompareAndMark(Design design1, IList<Entity> AutoCADEntities, Design design2, IList<Entity> AVEVAEntities)
666
        {
667
            var DiffRegions = new List<devDept.Eyeshot.OrientedBoundingRect>();
668

    
669
            int[] equalEntitiesInV1 = new int[AVEVAEntities.Count];
670
            bool[] equalEntitiesInV2 = new bool[AVEVAEntities.Count];
671

    
672
            /// 서로 검사 가능한 타입인지 확인한다.
673
            bool CheckType(Entity ent1, Entity ent2)
674
            {
675
                return ent1.GetType() == ent2.GetType() ||
676
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Text) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText)) ||
677
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
678
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Line) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.TabulatedSurface)) ||
679
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
680
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText));
681
            }
682

    
683
            try
684
            {
685
                for (int i = 0; i < AutoCADEntities.Count(); i++)
686
                {
687
                    Entity entVp1 = AutoCADEntities[i];
688
                    bool foundEqual = false;
689

    
690
                    for (int j = 0; j < AVEVAEntities.Count(); j++)
691
                    {
692
                        Entity entVp2 = AVEVAEntities[j];
693

    
694
                        if (entVp2 is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE")) continue;
695
                        if (!equalEntitiesInV2[j] && CheckType(entVp1, entVp2) && 
696
                            CompareIfEqual(design1, entVp1, design2, entVp2))
697
                        {
698
                            equalEntitiesInV1[j] = i;
699
                            equalEntitiesInV2[j] = true;
700
                            foundEqual = true;
701
                            break;
702
                        }
703
                    }
704
                    if (!foundEqual)
705
                    {
706
                        ColorEntity(design1, AutoCADEntities[i], Verification.DiffColor, colorMethodType.byEntity, false);
707

    
708
                        #region 틀린 엔터티의 BoundingBox를 구함
709
                        var origin = new devDept.Geometry.Point2D(entVp1.BoxMin.X - 1, entVp1.BoxMin.Y - 1);
710
                        double width = entVp1.BoxMax.X - entVp1.BoxMin.X;
711
                        double height = entVp1.BoxMax.Y - entVp1.BoxMin.Y;
712
                        var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
713
                        DiffRegions.Add(rect);
714
                        #endregion
715
                    }
716
                }
717

    
718
                for (int j = 0; j < AVEVAEntities.Count; j++)
719
                {
720
                    if (!equalEntitiesInV2[j])
721
                    {
722
                        ColorEntity(design2, AVEVAEntities[j], Verification.DiffColor, colorMethodType.byEntity, false);
723

    
724
                        #region 틀린 엔터티의 BoundingBox를 구함 
725
                        var origin = new devDept.Geometry.Point2D(AVEVAEntities[j].BoxMin.X - 1, AVEVAEntities[j].BoxMin.Y - 1);
726
                        double width = AVEVAEntities[j].BoxMax.X - AVEVAEntities[j].BoxMin.X;
727
                        double height = AVEVAEntities[j].BoxMax.Y - AVEVAEntities[j].BoxMin.Y;
728
                        var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
729
                        DiffRegions.Add(rect);
730
                        #endregion
731
                    }
732
                }
733

    
734
                #region 인접한 영역을 하나로 합친다.
735
                var queue = new List<devDept.Eyeshot.OrientedBoundingRect>(DiffRegions);
736
                DiffRegions.Clear();
737
                while (queue.Any())
738
                {
739
                    var first = queue[0];
740
                    var FirstMin = first.GetOrigin();
741
                    var FirstMax = FirstMin + first.GetAxis()[0] * first.Size.X + first.GetAxis()[1] * first.Size.Y;
742

    
743
                    queue.Remove(first);
744
                    bool overlap = false;
745
                    for (int i = 0; i < queue.Count; ++i)
746
                    {
747
                        var second = queue[i];
748
                        overlap = devDept.Eyeshot.OrientedBoundingRect.DoOverlapOrTouch(first, second);
749
                        if (overlap)
750
                        {
751
                            var SecondMin = second.GetOrigin();
752
                            var SecondMax = SecondMin + second.GetAxis()[0] * second.Size.X + second.GetAxis()[1] * second.Size.Y;
753

    
754
                            var min = new devDept.Geometry.Point2D(Math.Min(FirstMin.X, SecondMin.X), Math.Min(FirstMin.Y, SecondMin.Y));
755
                            var max = new devDept.Geometry.Point2D(Math.Max(FirstMax.X, SecondMax.X), Math.Max(FirstMax.Y, SecondMax.Y));
756
                            double width = max.X - min.X;
757
                            double height = max.Y - min.Y;
758

    
759
                            #region 두 영역을 합친다.(작업 완료된 영역도 다시 queue에 넣는다.)
760
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(min, width, height);
761
                            queue.Add(rect);
762
                            queue.AddRange(DiffRegions);
763
                            DiffRegions.Clear();
764
                            queue.Remove(second);
765
                            #endregion
766
                            break;
767
                        }
768
                    }
769

    
770
                    if (!overlap) DiffRegions.Add(first);
771
                }
772
                #endregion
773

    
774
                DiffRegions.ForEach(x => DrawRevCloud(design2, x));
775
            }
776
            catch(Exception ex)
777
            {
778
                Console.Write($"Error : {ex.Message}");
779
            }
780
        }
781

    
782
        /// <summary>
783
        /// Revision mark를 그린다.
784
        /// </summary>
785
        /// <param name="design"></param>
786
        /// <param name="obr"></param>
787
        private void DrawRevCloud(Design design, devDept.Eyeshot.OrientedBoundingRect obr)
788
        {
789
            IList<IGCurve> DrawRevCloudLine(devDept.Geometry.Point2D start, devDept.Geometry.Point2D end)
790
            {
791
                var res = new List<IGCurve>();
792

    
793
                var AxisX = new devDept.Geometry.Vector3D(end.X - start.X, end.Y - start.Y);
794
                AxisX.Normalize();
795
                var AxisY = devDept.Geometry.Vector3D.Cross(devDept.Geometry.Vector3D.AxisZ, AxisX);
796

    
797
                double step = 10;
798
                double dist = start.DistanceTo(end);
799
                int count = Convert.ToInt32(dist / step);
800
                if (count == 0 && dist > 0)
801
                {
802
                    var tmp = (start + end) * 0.5;
803

    
804
                    var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
805
                    var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
806
                    GArc arc = new GArc(plane, center, start.DistanceTo(end) * 0.5, Math.PI, Math.PI * 2);
807
                    res.Add(arc);
808
                }
809
                else
810
                {
811
                    for (int i = 0; i < count; ++i)
812
                    {
813
                        var _start = (start + AxisX * i * step);
814
                        var _end = (start + AxisX * (i + 1) * step);
815
                        if (i == count - 1) _end = end;
816
                        var tmp = (_start + _end) * 0.5;
817

    
818
                        var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
819
                        var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
820
                        GArc arc = new GArc(plane, center, _start.DistanceTo(_end) * 0.5, Math.PI, Math.PI * 2);
821
                        res.Add(arc);
822
                    }
823
                }
824

    
825
                return res;
826
            }
827

    
828
            GCompositeCurve profile = new GCompositeCurve();
829

    
830
            var vertices = obr.GetVertices();
831
            for(int i = 0;i < vertices.Length;++i)
832
            {
833
                var curves = DrawRevCloudLine(vertices[i], vertices[(i + 1) % vertices.Length]);
834
                profile.CurveList.AddRange(curves);
835
            }
836

    
837
            var revcloud = new devDept.Eyeshot.Entities.CompositeCurve(profile);
838
            revcloud.LayerName = "AVEVA";
839
            revcloud.Color = Verification.RevCloudColor;
840
            revcloud.ColorMethod = colorMethodType.byEntity;
841
            design.Entities.Add(revcloud);
842
        }
843

    
844
        /// <summary>
845
        /// 주어진 두 엔터티를 비교한다.
846
        /// </summary>
847
        /// <param name="entVp1"></param>
848
        /// <param name="entVp2"></param>
849
        /// <returns></returns>
850
        private bool CompareIfEqual(Design design1, Entity entVp1, Design design2, Entity entVp2)
851
        {
852
            return AreEqual(design1, entVp1, design2, entVp2);
853
        }
854

    
855
        private bool CompareGEntityIfEqual(GEntity entVp1, GEntity entVp2)
856
        {
857
            return AreGEntityEqual(entVp1, entVp2);
858
        }
859

    
860
        /// <summary>
861
        /// 그래픽적으로 두 엔터티가 유사한지 검사한다.
862
        /// </summary>
863
        /// <param name="design1"></param>
864
        /// <param name="ent1"></param>
865
        /// <param name="design2"></param>
866
        /// <param name="ent2"></param>
867
        /// <returns></returns>
868
        private bool AreEqual(Design design1, Entity ent1, Design design2, Entity ent2)
869
        {
870
            if (ent1 is CompositeCurve cc1 && ent2 is CompositeCurve cc2)
871
            {
872
                if (cc1.CurveList.Count == cc2.CurveList.Count)
873
                {
874
                    int equalCurvesInListCount = 0;
875
                    foreach (var entC in cc1.CurveList)
876
                    {
877
                        foreach (var entC2 in cc2.CurveList)
878
                        {
879
                            if (entC.GetType() == entC2.GetType())
880
                            {
881
                                if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
882
                                {
883
                                    equalCurvesInListCount++;
884
                                    break;
885
                                }
886
                                else if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
887
                                {
888
                                    equalCurvesInListCount++;
889
                                    break;
890
                                }
891
                            }
892
                        }
893
                    }
894

    
895
                    if (cc1.CurveList.Count == equalCurvesInListCount)
896
                    {
897
                        return true;
898
                    }
899
                }
900
            }
901
            else if (ent1 is LinearPath lp1 && ent2 is LinearPath lp2)
902
            {
903
                if (lp1.Vertices.Length == lp2.Vertices.Length)
904
                {
905
                    for (int i = 0; i < lp1.Vertices.Length; i++)
906
                    {
907
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
908
                            return false;
909
                    }
910

    
911
                    return true;
912
                }
913
            }
914
            else if (ent1 is PlanarEntity pe1 && ent2 is PlanarEntity pe2)
915
            {
916
                if (ent1 is Arc arc1 && ent2 is Arc arc2)
917
                {
918
                    if (
919
                        arc1.Center.DistanceTo(arc2.Center) <= Verification.Tolerance &&
920
                        Math.Abs(arc1.Radius - arc2.Radius) <= Verification.Tolerance &&
921
                        Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Verification.Tolerance &&
922
                        Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Verification.Tolerance
923
                        )
924
                    {
925
                        return true;
926
                    }
927
                }
928
                else if (ent1 is Circle c1 && ent2 is Circle c2)
929
                {
930
                    if (
931
                        c1.Center.DistanceTo(c2.Center) <= Verification.Tolerance &&
932
                        Math.Abs(c1.Radius - c2.Radius) <= Verification.Tolerance
933
                        )
934
                    {
935
                        return true;
936
                    }
937
                }
938
                else if (ent1 is EllipticalArc e1 && ent2 is EllipticalArc e2)
939
                {
940
                    if (
941
                        e1.Center.DistanceTo(e2.Center) <= Verification.Tolerance &&
942
                        Math.Abs(e1.RadiusX - e2.RadiusX) <= Verification.Tolerance &&
943
                        Math.Abs(e1.RadiusY - e2.RadiusY) <= Verification.Tolerance &&
944
                        Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Verification.Tolerance &&
945
                        Math.Abs(e1.Domain.High - e2.Domain.High) <= Verification.Tolerance
946
                    )
947
                    {
948
                        return true;
949
                    }
950
                }
951
                else if (ent1 is Ellipse el1 && ent2 is Ellipse el2)
952
                {
953
                    if (
954
                        el1.Center.DistanceTo(el2.Center) <= Verification.Tolerance &&
955
                        Math.Abs(el1.RadiusX - el2.RadiusX) <= Verification.Tolerance &&
956
                        Math.Abs(el1.RadiusY - el2.RadiusY) <= Verification.Tolerance
957
                    )
958
                    {
959
                        return true;
960
                    }
961
                }
962
                #region 해치는 삽입점만 비교
963
                else if (ent1 is Hatch hatch1 && ent2 is Hatch hatch2)
964
                {
965
                    return hatch1.PatternOrigin.DistanceTo(hatch2.PatternOrigin) < Verification.Tolerance;
966
                }
967
                #endregion
968
                else if (ent1 is Text)
969
                {
970
                    if (ent1 is Dimension dim1 && ent2 is Dimension dim2)
971
                    {
972
                        if (
973
                            dim1.InsertionPoint.DistanceTo(dim2.InsertionPoint) <= Verification.Tolerance &&
974
                            dim1.DimLinePosition.DistanceTo(dim2.DimLinePosition) <= Verification.Tolerance
975
                            )
976
                        {
977
                            if (ent1 is AngularDim ad1 && ent2 is AngularDim ad2)
978
                            {
979
                                if (
980
                                    ad1.ExtLine1.DistanceTo(ad2.ExtLine1) <= Verification.Tolerance &&
981
                                    ad1.ExtLine2.DistanceTo(ad2.ExtLine2) <= Verification.Tolerance &&
982
                                    Math.Abs(ad1.StartAngle - ad2.StartAngle) <= Verification.Tolerance &&
983
                                    Math.Abs(ad1.EndAngle - ad2.EndAngle) <= Verification.Tolerance &&
984
                                    Math.Abs(ad1.Radius - ad2.Radius) <= Verification.Tolerance
985
                                    )
986
                                {
987
                                    return true;
988
                                }
989
                            }
990
                            else if (ent1 is LinearDim ld1 && ent2 is LinearDim ld2)
991
                            {
992
                                if (
993
                                    ld1.ExtLine1.DistanceTo(ld2.ExtLine1) <= Verification.Tolerance &&
994
                                    ld1.ExtLine2.DistanceTo(ld2.ExtLine2) <= Verification.Tolerance
995
                                    )
996
                                {
997
                                    return true;
998
                                }
999
                            }
1000
                            else if (ent1 is DiametricDim dd1 && ent2 is DiametricDim dd2)
1001
                            {
1002
                                if (
1003
                                    Math.Abs(dd1.Distance - dd2.Distance) <= Verification.Tolerance &&
1004
                                    Math.Abs(dd1.Radius - dd2.Radius) <= Verification.Tolerance &&
1005
                                    Math.Abs(dd1.CenterMarkSize - dd2.CenterMarkSize) <= Verification.Tolerance
1006
                                )
1007
                                {
1008
                                    return true;
1009
                                }
1010
                            }
1011
                            else if (ent1 is RadialDim rd1 && ent2 is RadialDim rd2)
1012
                            {
1013
                                if (
1014
                                    Math.Abs(rd1.Radius - rd2.Radius) <= Verification.Tolerance &&
1015
                                    Math.Abs(rd1.CenterMarkSize - rd2.CenterMarkSize) <= Verification.Tolerance
1016
                                )
1017
                                {
1018
                                    return true;
1019
                                }
1020
                            }
1021
                            else if (ent1 is OrdinateDim od1 && ent2 is OrdinateDim od2)
1022
                            {
1023
                                if (
1024
                                    od1.DefiningPoint.DistanceTo(od2.DefiningPoint) <= Verification.Tolerance &&
1025
                                    od1.Origin.DistanceTo(od2.Origin) <= Verification.Tolerance &&
1026
                                    od1.LeaderEndPoint.DistanceTo(od2.LeaderEndPoint) <= Verification.Tolerance
1027
                                )
1028
                                {
1029
                                    return true;
1030
                                }
1031
                            }
1032
                            else
1033
                            {
1034
                                Console.Write("Type " + ent1.GetType() + " not implemented.");
1035
                                return true;
1036
                            }
1037
                        }
1038
                    }
1039

    
1040
                    else if (ent1 is devDept.Eyeshot.Entities.Attribute att1 && ent2 is devDept.Eyeshot.Entities.Attribute att2)
1041
                    {
1042
                        if (
1043
                            att1.Value == att2.Value &&
1044
                            att1.InsertionPoint.DistanceTo(att2.InsertionPoint) <= Verification.Tolerance
1045
                            )
1046
                        {
1047
                            return true;
1048
                        }
1049
                    }
1050
                    else
1051
                    {
1052
                        Text tx1 = (Text)ent1;
1053
                        Text tx2 = (Text)ent2;
1054

    
1055
                        #region 대소문자, 공백을 무시하여 비교
1056
                        string string1 = tx1.TextString.Trim().ToUpper();
1057
                        string string2 = tx2.TextString.Trim().ToUpper();
1058
                        string1 = System.Text.RegularExpressions.Regex.Replace(string1, @"\s+", "");
1059
                        string2 = System.Text.RegularExpressions.Regex.Replace(string2, @"\s+", "");
1060
                        if (
1061
                            tx1.BoxMin.DistanceTo(tx2.BoxMin) <= Verification.Tolerance &&
1062
                            string1 == string2 &&
1063
                            Math.Abs(tx1.WidthFactor - tx2.WidthFactor) <= Verification.Tolerance &&
1064
                            Math.Abs(tx1.Height - tx2.Height) <= Verification.Tolerance
1065
                            )
1066
                        {
1067
                            return true;
1068
                        }
1069
                        #endregion
1070
                    }
1071
                }
1072
            }
1073
            else if (ent1 is Line line1 && ent2 is Line line2)
1074
            {
1075
                var dir1 = line1.Direction;
1076
                dir1.Normalize();
1077
                var dir2 = line2.Direction;
1078
                dir2.Normalize();
1079
                if (devDept.Geometry.Vector3D.AreParallel(dir1, dir2, 0.1) &&
1080
                    Math.Abs(line1.Length() - line2.Length()) <= Verification.Tolerance &&
1081
                    line1.MidPoint.DistanceTo(line2.MidPoint) <= Verification.Tolerance
1082
                )
1083
                {
1084
                    return true;
1085
                }
1086
            }
1087
            else if (ent1 is Line && ent2 is devDept.Eyeshot.Entities.TabulatedSurface lwpolyline && lwpolyline.ControlPoints.Length == 4)
1088
            {
1089
                line1 = ent1 as Line;
1090
                var start = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[0, 0].X, lwpolyline.ControlPoints[0, 0].Y, 0);
1091
                var end = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[1, 0].X, lwpolyline.ControlPoints[1, 0].Y, 0);
1092
                var vec = new devDept.Geometry.Vector3D(start, end);
1093
                vec.Normalize();
1094
                var dir = line1.Direction.Clone() as devDept.Geometry.Vector3D;
1095
                dir.Normalize();
1096

    
1097
                if (
1098
                    devDept.Geometry.Vector3D.AreParallel(dir, vec) &&
1099
                    line1.StartPoint.DistanceTo(start) <= Verification.Tolerance &&
1100
                    line1.EndPoint.DistanceTo(end) <= Verification.Tolerance
1101
                )
1102
                {
1103
                    return true;
1104
                }
1105
            }
1106
            else if (ent1 is devDept.Eyeshot.Entities.Point point1 && ent2 is devDept.Eyeshot.Entities.Point point2)
1107
            {
1108
                if (point1.Position.DistanceTo(point2.Position) <= Verification.Tolerance)
1109
                {
1110
                    return true;
1111
                }
1112
            }
1113
            else if (ent1 is Curve cu1 && ent2 is Curve cu2)
1114
            {
1115
                if (
1116
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1117
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1118
                    cu1.Degree == cu2.Degree
1119
                    )
1120
                {
1121
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1122
                    {
1123
                        if (cu1.ControlPoints[k].DistanceTo(cu2.ControlPoints[k]) > Verification.Tolerance)
1124
                        {
1125
                            return false;
1126
                        }
1127
                    }
1128

    
1129
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
1130
                    {
1131
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
1132
                        {
1133
                            return false;
1134
                        }
1135
                    }
1136

    
1137
                    return true;
1138
                }
1139
            }
1140
            else if (ent1 is Mesh m1 && ent2 is Mesh m2 && m1.Vertices.Count() == m2.Vertices.Count())
1141
            {
1142
                for (int i = 0; i < m1.Vertices.Count(); ++i)
1143
                {
1144
                    if (m1.Vertices[i].DistanceTo(m2.Vertices[i]) > Verification.Tolerance) return false;
1145
                }
1146

    
1147
                return true;
1148
            }
1149
            else if (ent1 is BlockReference blkref1 && ent2 is BlockReference blkref2)
1150
            {
1151
                int equalCurvesInEntityList = 0;
1152

    
1153
                #region Point, Attribute, Text 제거 및 LinePath를 라인으로 분리
1154
                var entities1 = blkref1.Explode(design1.Blocks).Where(x => x.LayerName != "AS_PORT" && !(x is devDept.Eyeshot.Entities.Point) &&
1155
                !(x is devDept.Eyeshot.Entities.Attribute) && !(x is devDept.Eyeshot.Entities.Text)).ToList();
1156
                var coll1 = new List<Entity>();
1157
                entities1.ForEach(x =>
1158
                {
1159
                    if (x is LinearPath lp)
1160
                    {
1161
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1162
                        {
1163
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1164
                            coll1.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1165
                        }
1166
                    }
1167
                    else
1168
                    {
1169
                        coll1.Add(x);
1170
                    }
1171
                });
1172
                #endregion
1173

    
1174
                #region Point 및 Nesting Block 제거 및 LinePath를 라인으로 분리
1175
                var entities2 = blkref2.Explode(design2.Blocks).Where(x => 
1176
                !(x is devDept.Eyeshot.Entities.BlockReference blkref && blkref.BlockName == "PORT") && !(x is devDept.Eyeshot.Entities.Point)).ToList();
1177
                var coll2 = new List<Entity>();
1178
                entities2.ForEach(x =>
1179
                {
1180
                    if (x is LinearPath lp)
1181
                    {
1182
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1183
                        {
1184
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1185
                            coll2.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1186
                        }
1187
                    }
1188
                    else if (x is devDept.Eyeshot.Entities.Attribute attr)
1189
                    {
1190
                        if (!attr.Invisible) coll2.Add(attr);
1191
                    }
1192
                    else if (x.GetType().Name == "AttributeReferenceData")
1193
                    {
1194
                    }
1195
                    else
1196
                    {
1197
                        coll2.Add(x);
1198
                    }
1199
                });
1200
                #endregion
1201

    
1202
                if (coll1.Count != coll2.Count) return false;
1203

    
1204
                foreach (var entC in coll1)
1205
                {
1206
                    foreach (var entC2 in coll2)
1207
                    {
1208
                        if (entC.GetType() == entC2.GetType())
1209
                        {
1210
                            if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
1211
                            {
1212
                                equalCurvesInEntityList++;
1213
                                break;
1214
                            }
1215
                        }
1216
                    }
1217
                }
1218

    
1219
                if (coll1.Count == equalCurvesInEntityList)
1220
                {
1221
                    return true;
1222
                }
1223
            }
1224
            else
1225
            {
1226
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1227
                return false;
1228
            }
1229

    
1230
            return false;
1231
        }
1232

    
1233
        private bool AreGEntityEqual(GEntity ent1, GEntity ent2)
1234
        {
1235
            if (ent1 is GCompositeCurve cc1 && ent2 is GCompositeCurve cc2)
1236
            {
1237
                if (cc1.CurveList.Count == cc2.CurveList.Count)
1238
                {
1239
                    int equalCurvesInListCount = 0;
1240
                    foreach (var entC in cc1.CurveList)
1241
                    {
1242
                        foreach (var entC2 in cc2.CurveList)
1243
                        {
1244
                            if (entC.GetType() == entC2.GetType())
1245
                            {
1246
                                if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
1247
                                {
1248
                                    equalCurvesInListCount++;
1249
                                    break;
1250
                                }
1251
                            }
1252
                        }
1253
                    }
1254

    
1255
                    if (cc1.CurveList.Count == equalCurvesInListCount)
1256
                    {
1257
                        return true;
1258
                    }
1259
                }
1260
            }
1261
            else if (ent1 is GLinearPath lp1 && ent2 is GLinearPath lp2)
1262
            {
1263
                if (lp1.Vertices.Length == lp2.Vertices.Length)
1264
                {
1265
                    for (int i = 0; i < lp1.Vertices.Length; i++)
1266
                    {
1267
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
1268
                            return false;
1269
                    }
1270
                    return true;
1271
                }
1272
            }
1273

    
1274
            else if (ent1 is GPlanarEntity pe1 && ent2 is GPlanarEntity pe2)
1275
            {
1276
                if (
1277
                    pe1.Plane.AxisZ == pe2.Plane.AxisZ &&
1278
                    pe1.Plane.AxisX == pe2.Plane.AxisX
1279
                    )
1280
                {
1281
                    if (ent1 is GArc arc1 && ent2 is GArc arc2)
1282
                    {
1283
                        if (
1284
                            arc1.Center.DistanceTo(arc2.Center) <= Verification.Tolerance &&
1285
                            Math.Abs(arc1.Radius - arc2.Radius) <= Verification.Tolerance &&
1286
                            Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Verification.Tolerance &&
1287
                            Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Verification.Tolerance
1288
                            )
1289
                        {
1290
                            return true;
1291
                        }
1292
                    }
1293
                    else if (ent1 is GCircle c1 && ent2 is GCircle c2)
1294
                    {
1295
                        if (c1.Center.DistanceTo(c2.Center) <= Verification.Tolerance && 
1296
                            Math.Abs(c1.Radius - c2.Radius) <= Verification.Tolerance)
1297
                        {
1298
                            return true;
1299
                        }
1300
                    }
1301
                    else if (ent1 is GEllipticalArc e1 && ent2 is GEllipticalArc e2)
1302
                    {
1303
                        if (
1304
                            e1.Center.DistanceTo(e2.Center) <= Verification.Tolerance &&
1305
                            Math.Abs(e1.RadiusX - e2.RadiusX) <= Verification.Tolerance &&
1306
                            Math.Abs(e1.RadiusY - e2.RadiusY) <= Verification.Tolerance &&
1307
                            Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Verification.Tolerance &&
1308
                            Math.Abs(e1.Domain.High - e2.Domain.High) <= Verification.Tolerance
1309
                        )
1310
                        {
1311
                            return true;
1312
                        }
1313
                    }
1314
                    else if (ent1 is GEllipse el1 && ent2 is GEllipse el2)
1315
                    {
1316
                        if (
1317
                            el1.Center.DistanceTo(el2.Center) <= Verification.Tolerance &&
1318
                            Math.Abs(el1.RadiusX - el2.RadiusX) <= Verification.Tolerance &&
1319
                            Math.Abs(el1.RadiusY - el2.RadiusY) <= Verification.Tolerance
1320
                        )
1321
                        {
1322
                            return true;
1323
                        }
1324
                    }
1325
                    else
1326
                    {
1327
                        Console.Write("Type " + ent1.GetType() + " not implemented.");
1328
                        return true;
1329
                    }
1330
                }
1331
            }
1332

    
1333
            else if (ent1 is GLine line1 && ent2 is GLine line2)
1334
            {
1335
                if (line1.StartPoint.DistanceTo(line2.StartPoint) <= Verification.Tolerance && 
1336
                    line1.EndPoint.DistanceTo(line2.EndPoint) <= Verification.Tolerance
1337
                )
1338
                {
1339
                    return true;
1340
                }
1341
            }
1342
#if NURBS
1343
            else if (ent1 is Curve)
1344
            {
1345
                Curve cu1 = (Curve)ent1;
1346
                Curve cu2 = (Curve)ent2;
1347

    
1348
                if (
1349
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1350
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1351
                    cu1.Degree == cu2.Degree
1352
                    )
1353
                {
1354
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1355
                    {
1356
                        if (cu1.ControlPoints[k] != cu2.ControlPoints[k])
1357
                        {
1358
                            return false;
1359
                        }
1360
                    }
1361

    
1362
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
1363
                    {
1364
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
1365
                        {
1366
                            return false;
1367
                        }
1368
                    }
1369

    
1370
                    return true;
1371
                }
1372
            }
1373
#endif
1374

    
1375
            else
1376
            {
1377
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1378
                return true;
1379
            }
1380
            return false;
1381
        }
1382

    
1383
        #region Camera Sync
1384
        private void CameraChanged(object sender, devDept.Eyeshot.Workspace.CameraMoveEventArgs e)
1385
        {
1386
            if (sender == this.designAutoCAD)
1387
            {
1388
                SyncCamera(this.designAutoCAD, this.designAVEVA);
1389
                SyncCamera(this.designAutoCAD, this.designCompare);
1390
            }
1391
            else if (sender == this.designAVEVA)
1392
            {
1393
                SyncCamera(this.designAVEVA, this.designAutoCAD);
1394
                SyncCamera(this.designAVEVA, this.designCompare);
1395
            }
1396
            else
1397
            {
1398
                SyncCamera(this.designCompare, this.designAutoCAD);
1399
                SyncCamera(this.designCompare, this.designAVEVA);
1400
            }
1401
        }
1402

    
1403
        private void SyncCamera(Design designMovedCamera, Design designCameraToMove)
1404
        {
1405
            Camera savedCamera;
1406
            designMovedCamera.SaveView(out savedCamera);
1407

    
1408
            // restores the camera to the other model
1409
            designCameraToMove.RestoreView(savedCamera);
1410
            designCameraToMove.AdjustNearAndFarPlanes();
1411
            designCameraToMove.Invalidate();
1412
        }
1413
        #endregion
1414
    }
1415
}
클립보드 이미지 추가 (최대 크기: 500 MB)