프로젝트

일반

사용자정보

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

hytos / ID2.Manager / ID2.Manager.Compare / Controls / Verification.cs @ 4142eefa

이력 | 보기 | 이력해설 | 다운로드 (70.6 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
        private static double LengthToleranceRatio { get; set; } = 0.1;
40
        #endregion
41

    
42
        private RadProgressBarElement _progressBar = null;
43

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

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

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

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

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

    
75
            _progressBar = progressBar;
76

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
319
            string _LengthToleranceRatio = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Length Tolerance Ratio");
320
            if (!string.IsNullOrEmpty(_LengthToleranceRatio))
321
            {
322
                LengthToleranceRatio = Convert.ToDouble(_LengthToleranceRatio);
323
            }
324

    
325
            #region Except Layer를 로딩한다.
326
            LoadLayerSettings();
327
            #endregion
328
        }
329

    
330
        /// <summary>
331
        /// 레이어 설정을 읽는다.
332
        /// </summary>
333
        public void LoadLayerSettings()
334
        {
335
            Forms.ExceptLayer.ExceptLayers.Clear();
336
            Forms.ExceptLayer.LineLayers.Clear();
337

    
338
            string _ExceptLayers = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers");
339
            if (!string.IsNullOrEmpty(_ExceptLayers))
340
            {
341
                Forms.ExceptLayer.ExceptLayers.AddRange(_ExceptLayers.Split(',').ToList().ConvertAll(x => new Forms.ExceptLayer.Layer(x)));
342

    
343
                string _ExceptLayersVisible = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers Visible");
344
                if (!string.IsNullOrEmpty(_ExceptLayersVisible))
345
                {
346
                    var tokens = _ExceptLayersVisible.Split(',').ToList().ConvertAll(x => Convert.ToBoolean(x));
347
                    for (int i = 0; i < Forms.ExceptLayer.ExceptLayers.Count; ++i)
348
                    {
349
                        if (i < tokens.Count)
350
                        {
351
                            Forms.ExceptLayer.ExceptLayers[i].Visible = tokens[i];
352
                        }
353
                    }
354
                }
355
            }
356

    
357
            string _LineLayers = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Line Layers");
358
            if (!string.IsNullOrEmpty(_LineLayers))
359
            {
360
                Forms.ExceptLayer.LineLayers.AddRange(_LineLayers.Split(',').ToList().ConvertAll(x => new Forms.ExceptLayer.Layer(x)));
361
            }
362
        }
363

    
364
        /// <summary>
365
        /// 엔터티들의 색상을 바꾼다.
366
        /// </summary>
367
        /// <param name="design"></param>
368
        /// <param name="list"></param>
369
        public void ColorEntities(Design design, IList<Entity> list, Color color, colorMethodType colorMethod=colorMethodType.byEntity, bool ChangeBlkColor=true)
370
        {
371
            foreach (Entity ent in list)
372
            {
373
                ColorEntity(design, ent, color, colorMethod, ChangeBlkColor);
374
            }
375
        }
376

    
377
        /// <summary>
378
        /// 엔터티의 색상을 변경한다.
379
        /// </summary>
380
        /// <param name="design"></param>
381
        /// <param name="entity"></param>
382
        /// <param name="color"></param>
383
        private void ColorEntity(Design design, Entity entity, Color color, colorMethodType colorMethod = colorMethodType.byEntity, 
384
            bool ChangeBlkColor = true)
385
        {
386
            if (entity is BlockReference blkref)
387
            {
388
                blkref.Color = color;
389
                blkref.ColorMethod = colorMethod;
390

    
391
                if (ChangeBlkColor)
392
                {
393
                    var blk = design.Blocks.FirstOrDefault(x => x.Name == blkref.BlockName);
394
                    if (blk != null)
395
                    {
396
                        ColorEntities(design, blk.Entities, color, colorMethodType.byParent);
397
                        foreach (var attr in blkref.Attributes.Values)
398
                        {
399
                            attr.Color = color;
400
                            attr.ColorMethod = colorMethodType.byParent;
401
                        }
402
                    }
403
                }
404
            }
405
            else
406
            {
407
                entity.Color = color;
408
                entity.ColorMethod = colorMethod;
409
            }
410
        }
411

    
412
        private List<Entity> ExplodeBlockReference(Design design, BlockReference blkref, string LayerName, Color color)
413
        {
414
            var res = new List<Entity>();
415

    
416
            var entities = blkref.Explode(design.Blocks);
417
            foreach (var ent in entities) ent.LayerName = LayerName;
418
            entities.ToList().ForEach(y =>
419
            {
420
                if (y is LinearPath lp)
421
                {
422
                    int count = Convert.ToInt32(lp.Vertices.Length);
423
                    for (int i = 0; i < count - 1; ++i)
424
                    {
425
                        var line = new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
426
                        {
427
                            LayerName = lp.LayerName,
428
                            LineWeight = lp.LineWeight,
429
                            LineTypeMethod = colorMethodType.byEntity,
430
                            Color = Verification.AutoCADColor,
431
                            ColorMethod = colorMethodType.byEntity
432
                        };
433
                        res.Add(line);
434
                    }
435
                }
436
                else if(y is BlockReference subblkref)
437
                {
438
                    res.AddRange(ExplodeBlockReference(design, subblkref, LayerName, color));
439
                }
440
            });
441

    
442
            var attributes = blkref.Attributes;
443
            foreach (var ent in entities.Where(y => y is devDept.Eyeshot.Entities.Attribute))
444
            {
445
                var txt = ent as devDept.Eyeshot.Entities.Attribute;
446
                txt.LayerName = LayerName;
447
                txt.Color = color;
448
                txt.ColorMethod = colorMethodType.byEntity;
449
                KeyValuePair<string, AttributeReference>? kp = attributes.FirstOrDefault(z => z.Key == txt.TextString);
450
                if (kp.HasValue) txt.TextString = (kp.Value.Value) != null ? kp.Value.Value.Value : string.Empty;
451
            }
452

    
453
            res.AddRange(entities.Where(y =>
454
            {
455
                if (y is devDept.Eyeshot.Entities.Attribute attr && string.IsNullOrEmpty(attr.TextString)) return false;
456
                if (y is devDept.Eyeshot.Entities.Text text && string.IsNullOrEmpty(text.TextString)) return false;
457
                if (y is BlockReference subblkref && subblkref.BlockName == "PORT") return false;
458
                if (y is LinearPath) return false;
459
                return true;
460
            }));
461

    
462
            blkref.Attributes.Clear();
463
            blkref.UpdateBoundingBox(new TraversalParams(design));
464

    
465
            return res;
466
        }
467

    
468
        /// <summary>
469
        /// 주어진 도면의 원본과 AVEVA를 비교한다.
470
        /// </summary>
471
        private void CompareDrawing(Document doc, bool ResultOnly = false)
472
        {
473
            /// AutoCAD P&ID 파일을 화면에 표시한다.
474
            void ShowAutoCADFile(string FilePath, Design design, bool clear = true)
475
            {
476
                if (clear) design.Clear();
477
                if (System.IO.File.Exists(FilePath))
478
                {
479
                    try
480
                    {
481
                        devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(FilePath);
482
                        ra.DoWork();
483
                        var min = ra.Min;
484
                        if (!ra.Layers.Contains(Verification.AutoCADLayer)) ra.Layers.Add(Verification.AutoCADLayer, Verification.AutoCADColor);
485
                        foreach (var ent in ra.Entities)
486
                        {
487
                            /// 도면을 원점으로 맞춘다.
488
                            ent.Translate(-min.X, -min.Y);
489
                        }
490
                        ra.AddToScene(design);
491
                        design.Entities.RemoveAll(x => Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
492
                    }
493
                    catch (Exception ex)
494
                    {
495
                        RadMessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, RadMessageIcon.Error);
496
                        return;
497
                    }
498

    
499
                    var AddEntities = new List<Entity>();
500
                    #region LinearPath를 Line으로 분할한다.
501
                    design.Entities.ForEach(x =>
502
                    {
503
                        if (x is LinearPath lp)
504
                        {
505
                            int count = Convert.ToInt32(lp.Vertices.Length);
506
                            for (int i = 0; i < count - 1; ++i)
507
                            {
508
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
509
                                {
510
                                    LayerName = lp.LayerName,
511
                                    LineWeight = lp.LineWeight,
512
                                    LineTypeMethod = colorMethodType.byEntity
513
                                });
514
                            }
515
                        }
516
                    });
517
                    design.Entities.RemoveAll(x => (x is LinearPath));
518
                    design.Entities.AddRange(AddEntities);
519
                    #endregion
520

    
521
                    #region 브랜치가 생성되는 부분에서 파이프 라인을 분할
522
                    var queue = design.Entities.Where(x => x is Line && 
523
                    Forms.ExceptLayer.LineLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper())).ToList();
524
                    while (queue.Any())
525
                    {
526
                        var line1 = queue.First() as Line;
527
                        var dir1 = line1.Direction;
528
                        dir1.Normalize();
529
                        queue.Remove(line1);
530
                        for (int i = 0; i < queue.Count; ++i)
531
                        {
532
                            var line2 = queue.ElementAt(i) as Line;
533
                            var dir2 = line2.Direction;
534
                            dir2.Normalize();
535
                            if (devDept.Geometry.Vector3D.AreOrthogonal(dir1, dir2))
536
                            {
537
                                var intersects = line1.IntersectWith(line2);
538
                                if (intersects.Count() == 1)
539
                                {
540
                                    if (line1.StartPoint.DistanceTo(intersects[0]) > 0.1 && line1.EndPoint.DistanceTo(intersects[0]) > 0.1)
541
                                    {
542
                                        var split1 = new devDept.Eyeshot.Entities.Line(line1.StartPoint, intersects[0])
543
                                        {
544
                                            LayerName = line1.LayerName,
545
                                            LineWeight = line1.LineWeight,
546
                                            LineTypeMethod = colorMethodType.byEntity
547
                                        };
548
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line1.EndPoint)
549
                                        {
550
                                            LayerName = line1.LayerName,
551
                                            LineWeight = line1.LineWeight,
552
                                            LineTypeMethod = colorMethodType.byEntity
553
                                        };
554
                                        design.Entities.Add(split1);
555
                                        design.Entities.Add(split2);
556
                                        design.Entities.Remove(line1);
557

    
558
                                        queue.Add(split1);
559
                                        queue.Add(split2);
560

    
561
                                        break;
562
                                    }
563

    
564
                                    if (line2.StartPoint.DistanceTo(intersects[0]) > 0.1 && line2.EndPoint.DistanceTo(intersects[0]) > 0.1)
565
                                    {
566
                                        var split1 = new devDept.Eyeshot.Entities.Line(line2.StartPoint, intersects[0])
567
                                        {
568
                                            LayerName = line2.LayerName,
569
                                            LineWeight = line2.LineWeight,
570
                                            LineTypeMethod = colorMethodType.byEntity
571
                                        };
572
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line2.EndPoint)
573
                                        {
574
                                            LayerName = line2.LayerName,
575
                                            LineWeight = line2.LineWeight,
576
                                            LineTypeMethod = colorMethodType.byEntity
577
                                        };
578
                                        design.Entities.Add(split1);
579
                                        design.Entities.Add(split2);
580
                                        design.Entities.Remove(line2);
581

    
582
                                        queue.Remove(line2);
583
                                        queue.Add(split1);
584
                                        queue.Add(split2);
585
                                    }
586
                                }
587
                            }
588
                        }
589
                    }
590
                    #endregion
591

    
592
                    #region 레이어 변경
593
                    foreach (var ent in design.Entities)
594
                    {
595
                        ent.Color = Verification.AutoCADColor;
596
                        ent.ColorMethod = colorMethodType.byEntity;
597
                        if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
598
                        {
599
                            ent.LayerName = Verification.AutoCADLayer;
600
                        }
601
                    }
602
                    #endregion
603

    
604
                    #region 블록을 깸
605
                    AddEntities.Clear();
606
                    design.Entities.Where(x => x.LayerName == Verification.AutoCADLayer).ToList().ForEach(x =>
607
                    {
608
                        if (x is BlockReference blkref)
609
                        {
610
                            AddEntities.AddRange(ExplodeBlockReference(design, blkref, Verification.AutoCADLayer, Verification.AutoCADColor));
611
                        }
612
                    });
613

    
614
                    design.Entities.RemoveAll(x => (x is BlockReference) || Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
615
                    design.Entities.AddRange(AddEntities);
616

    
617
                    #region 눈에 보이지 않는 라인은 제거
618
                    design.Entities.RemoveAll(x => x is Line line && line.Length() < 0.001);
619
                    #endregion
620
                    #endregion
621

    
622
                    ColorEntities(design, design.Entities, Verification.AutoCADColor);
623

    
624
                    // Sets the view as Top
625
                    design.SetView(viewType.Top);
626
                    design.ZoomFit();
627
                    design.Invalidate();
628
                }
629
            }
630

    
631
            /// AVEVA P&ID 파일을 화면에 표시한다.
632
            void ShowAVEVAPIDFile(string FilePath, Design design, bool clear = true)
633
            {
634
                if (clear) design.Clear();
635
                if (System.IO.File.Exists(FilePath))
636
                {
637
                    devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(FilePath);
638
                    ra.DoWork();
639
                    var min = ra.Min;
640
                    var AddEntities = new List<Entity>();
641

    
642
                    if (!ra.Layers.Contains(Verification.AVEVALayer)) ra.Layers.Add(Verification.AVEVALayer, Verification.AVEVAColor);
643
                    foreach (var ent in ra.Entities)
644
                    {
645
                        /// 도면을 원점으로 맞춘다.
646
                        ent.Translate(-min.X, -min.Y);
647

    
648
                        #region 멀티 라인들을 분할하여 추가한다.
649
                        if (ent is Mesh mesh && (mesh.LayerName == "AS_PIPE" || mesh.LayerName == "AS_INST"))
650
                        {
651
                            int count = Convert.ToInt32(mesh.Vertices.Length * 0.5);
652
                            for (int i = 0; i < count - 1; ++i)
653
                            {
654
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(mesh.Vertices[i], mesh.Vertices[i + 1])
655
                                {
656
                                    LayerName = Verification.AVEVALayer,
657
                                    LineWeight = 3.0f,
658
                                    LineTypeMethod = colorMethodType.byEntity,
659
                                    Color = Verification.AVEVAColor,
660
                                    ColorMethod = colorMethodType.byEntity
661
                                });
662
                            }
663
                        }
664
                        else if (ent is TabulatedSurface tf && (tf.LayerName == "AS_PIPE" || tf.LayerName == "AS_INST"))
665
                        {
666
                            int count = Convert.ToInt32(tf.ControlPoints.Length * 0.5);
667
                            for (int i = 0; i < count - 1; ++i)
668
                            {
669
                                AddEntities.Add(
670
                                    new devDept.Eyeshot.Entities.Line(
671
                                    new devDept.Geometry.Point3D(tf.ControlPoints[i, 0].X, tf.ControlPoints[i, 0].Y, 0),
672
                                    new devDept.Geometry.Point3D(tf.ControlPoints[i + 1, 0].X, tf.ControlPoints[i + 1, 0].Y, 0))
673
                                    {
674
                                        LayerName = Verification.AVEVALayer,
675
                                        LineWeight = 3.0f,
676
                                        LineTypeMethod = colorMethodType.byEntity,
677
                                        Color = Verification.AVEVAColor,
678
                                        ColorMethod = colorMethodType.byEntity
679
                                    }
680
                                );
681
                            }
682
                        }
683
                        else if (ent is LinearPath lp)
684
                        {
685
                            int count = Convert.ToInt32(lp.Vertices.Length);
686
                            for (int i = 0; i < count - 1; ++i)
687
                            {
688
                                AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
689
                                {
690
                                    LayerName = Verification.AVEVALayer,
691
                                    LineWeight = lp.LineWeight,
692
                                    Color = Verification.AVEVAColor,
693
                                    LineTypeMethod = colorMethodType.byEntity
694
                                });
695
                            }
696
                        }
697
                        #endregion
698

    
699
                        ent.Color = Verification.AVEVAColor;
700
                        ent.ColorMethod = colorMethodType.byEntity;
701
                        if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
702
                        {
703
                            ent.LayerName = Verification.AVEVALayer;
704
                        }
705
                    }
706
                    ra.AddToScene(design);
707

    
708
                    #region 불필요한 블럭들은 제거
709
                    design.Entities.RemoveAll(x => x is BlockReference blkref && (blkref.BlockName == "LBRK" || 
710
                    blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE" || blkref.BlockName.StartsWith("ARROW")));
711
                    #endregion
712

    
713
                    #region 블럭을 깸
714
                    design.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList().ForEach(x =>
715
                    {
716
                        if(x is BlockReference blkref)
717
                        {
718
                            AddEntities.AddRange(ExplodeBlockReference(design, blkref, Verification.AVEVALayer, Verification.AVEVAColor));
719
                        }
720
                    });
721
                    design.Entities.RemoveAll(x =>
722
                    ((x is Mesh || x is TabulatedSurface) && (x.LayerName == Verification.AVEVALayer)) ||
723
                    (x is LinearPath && x.LayerName == Verification.AVEVALayer) || (x is BlockReference) ||
724
                    Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
725
                    design.Entities.AddRange(AddEntities);
726
                    #endregion
727

    
728
                    #region 눈에 보이지 않는 라인은 제거
729
                    design.Entities.RemoveAll(x => x is Line line && line.Length() < 0.001);
730
                    #endregion
731

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

    
734
                    design.SetView(viewType.Top);
735
                    design.ZoomFit();
736
                    design.Invalidate();
737
                }
738
            }
739

    
740
            string dwgExtension = ".dwg";
741
            string ID2DrawingFolder = Program.AutoCADFolder;
742
            string dwgFilePath = System.IO.Path.Combine(ID2DrawingFolder, $"{doc.DocumentNo}{dwgExtension}");
743
            if (!ResultOnly) ShowAutoCADFile(dwgFilePath, this.designAutoCAD);
744
            ShowAutoCADFile(dwgFilePath, this.designCompare);
745

    
746
            string AVEVAPIDFolder = Program.AVEVAPIDFolder;
747
            string AVEVAPIDFilePath = string.Empty;
748
            if (AVEVAPIDFolder != null)
749
            {
750
                AVEVAPIDFilePath = System.IO.Path.Combine(AVEVAPIDFolder, $"{doc.DocumentNo}{dwgExtension}");
751
                if (!ResultOnly) ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designAVEVA);
752
                ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designCompare, false);
753
            }
754

    
755
            if (System.IO.File.Exists(dwgFilePath) && System.IO.File.Exists(AVEVAPIDFilePath))
756
            {
757
                var AutoCADEntities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AutoCADLayer).ToList();
758
                var AVEVAtities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList();
759
                CompareAndMark(this.designCompare, AutoCADEntities, this.designCompare, AVEVAtities);
760
                this.designCompare.Entities.ForEach(x => 
761
                {
762
                    if (x.LayerName != Verification.AVEVALayer && x.LayerName != Verification.AutoCADLayer &&
763
                    x.LayerName != Verification.RevCloudLayer) x.LayerName = Verification.AutoCADLayer;
764
                });
765
            }
766
        }
767

    
768
        /// <summary>
769
        /// 주어진 두 엔터티 리스트를 비교하여 틀린 엔터티의 색상을 설정한 색상으로 변경한다.
770
        /// </summary>
771
        /// <param name="entList1"></param>
772
        /// <param name="entList2"></param>
773
        private void CompareAndMark(Design design1, IList<Entity> AutoCADEntities, Design design2, IList<Entity> AVEVAEntities)
774
        {
775
            var DiffRegions = new List<devDept.Eyeshot.OrientedBoundingRect>();
776

    
777
            int[] equalEntitiesInV1 = new int[AVEVAEntities.Count];
778
            bool[] equalEntitiesInV2 = new bool[AVEVAEntities.Count];
779

    
780
            /// 서로 검사 가능한 타입인지 확인한다.
781
            bool CheckType(Entity ent1, Entity ent2)
782
            {
783
                return ent1.GetType() == ent2.GetType() ||
784
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Text) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText)) ||
785
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
786
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Line) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.TabulatedSurface)) ||
787
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
788
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText));
789
            }
790

    
791
            try
792
            {
793
                for (int i = 0; i < AutoCADEntities.Count(); i++)
794
                {
795
                    Entity entVp1 = AutoCADEntities[i];
796
                    bool foundEqual = false;
797

    
798
                    for (int j = 0; j < AVEVAEntities.Count(); j++)
799
                    {
800
                        Entity entVp2 = AVEVAEntities[j];
801

    
802
                        if (entVp2 is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE")) continue;
803
                        if (!equalEntitiesInV2[j] && CheckType(entVp1, entVp2) && 
804
                            CompareIfEqual(design1, entVp1, design2, entVp2))
805
                        {
806
                            equalEntitiesInV1[j] = i;
807
                            equalEntitiesInV2[j] = true;
808
                            foundEqual = true;
809
                            break;
810
                        }
811
                    }
812
                    if (!foundEqual)
813
                    {
814
                        ColorEntity(design1, AutoCADEntities[i], Verification.DiffColor, colorMethodType.byEntity, false);
815

    
816
                        #region 틀린 엔터티의 BoundingBox를 구함
817
                        var origin = new devDept.Geometry.Point2D(entVp1.BoxMin.X - 1, entVp1.BoxMin.Y - 1);
818
                        double width = entVp1.BoxMax.X - entVp1.BoxMin.X;
819
                        double height = entVp1.BoxMax.Y - entVp1.BoxMin.Y;
820
                        if (Math.Abs(width) != double.PositiveInfinity && Math.Abs(height) != double.PositiveInfinity)
821
                        {
822
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
823
                            DiffRegions.Add(rect);
824
                        }
825
                        #endregion
826
                    }
827
                }
828

    
829
                for (int j = 0; j < AVEVAEntities.Count; j++)
830
                {
831
                    if (!equalEntitiesInV2[j])
832
                    {
833
                        ColorEntity(design2, AVEVAEntities[j], Verification.DiffColor, colorMethodType.byEntity, false);
834

    
835
                        #region 틀린 엔터티의 BoundingBox를 구함 
836
                        var origin = new devDept.Geometry.Point2D(AVEVAEntities[j].BoxMin.X - 1, AVEVAEntities[j].BoxMin.Y - 1);
837
                        double width = AVEVAEntities[j].BoxMax.X - AVEVAEntities[j].BoxMin.X;
838
                        double height = AVEVAEntities[j].BoxMax.Y - AVEVAEntities[j].BoxMin.Y;
839
                        if (Math.Abs(width) != double.PositiveInfinity && Math.Abs(height) != double.PositiveInfinity)
840
                        {
841
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
842
                            DiffRegions.Add(rect);
843
                        }
844
                        #endregion
845
                    }
846
                }
847

    
848
                #region 인접한 영역을 하나로 합친다.
849
                var queue = new List<devDept.Eyeshot.OrientedBoundingRect>(DiffRegions);
850
                DiffRegions.Clear();
851
                while (queue.Any())
852
                {
853
                    var first = queue[0];
854
                    var FirstMin = first.GetOrigin();
855
                    var FirstMax = FirstMin + first.GetAxis()[0] * first.Size.X + first.GetAxis()[1] * first.Size.Y;
856

    
857
                    queue.Remove(first);
858
                    bool overlap = false;
859
                    for (int i = 0; i < queue.Count; ++i)
860
                    {
861
                        var second = queue[i];
862
                        overlap = devDept.Eyeshot.OrientedBoundingRect.DoOverlapOrTouch(first, second);
863
                        if (overlap)
864
                        {
865
                            var SecondMin = second.GetOrigin();
866
                            var SecondMax = SecondMin + second.GetAxis()[0] * second.Size.X + second.GetAxis()[1] * second.Size.Y;
867

    
868
                            var min = new devDept.Geometry.Point2D(Math.Min(FirstMin.X, SecondMin.X), Math.Min(FirstMin.Y, SecondMin.Y));
869
                            var max = new devDept.Geometry.Point2D(Math.Max(FirstMax.X, SecondMax.X), Math.Max(FirstMax.Y, SecondMax.Y));
870
                            double width = max.X - min.X;
871
                            double height = max.Y - min.Y;
872

    
873
                            #region 두 영역을 합친다.(작업 완료된 영역도 다시 queue에 넣는다.)
874
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(min, width, height);
875
                            queue.Add(rect);
876
                            queue.AddRange(DiffRegions);
877
                            DiffRegions.Clear();
878
                            queue.Remove(second);
879
                            #endregion
880
                            break;
881
                        }
882
                    }
883

    
884
                    if (!overlap) DiffRegions.Add(first);
885
                }
886
                #endregion
887

    
888
                if (!design2.Layers.Contains(Verification.RevCloudLayer))
889
                    design2.Layers.Add(Verification.RevCloudLayer.ToUpper(), Verification.RevCloudColor);
890
                DiffRegions.ForEach(x => DrawRevCloud(design2, x));
891
            }
892
            catch(Exception ex)
893
            {
894
                Console.Write($"Error : {ex.Message}");
895
            }
896
        }
897

    
898
        /// <summary>
899
        /// Revision mark를 그린다.
900
        /// </summary>
901
        /// <param name="design"></param>
902
        /// <param name="obr"></param>
903
        private void DrawRevCloud(Design design, devDept.Eyeshot.OrientedBoundingRect obr)
904
        {
905
            IList<IGCurve> DrawRevCloudLine(devDept.Geometry.Point2D start, devDept.Geometry.Point2D end)
906
            {
907
                var res = new List<IGCurve>();
908

    
909
                var AxisX = new devDept.Geometry.Vector3D(end.X - start.X, end.Y - start.Y);
910
                AxisX.Normalize();
911
                var AxisY = devDept.Geometry.Vector3D.Cross(devDept.Geometry.Vector3D.AxisZ, AxisX);
912

    
913
                double step = 10;
914
                double dist = start.DistanceTo(end);
915
                int count = Convert.ToInt32(dist / step);
916
                if (count == 0 && dist > 0)
917
                {
918
                    var tmp = (start + end) * 0.5;
919

    
920
                    var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
921
                    var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
922
                    GArc arc = new GArc(plane, center, start.DistanceTo(end) * 0.5, Math.PI, Math.PI * 2);
923
                    res.Add(arc);
924
                }
925
                else
926
                {
927
                    for (int i = 0; i < count; ++i)
928
                    {
929
                        var _start = (start + AxisX * i * step);
930
                        var _end = (start + AxisX * (i + 1) * step);
931
                        if (i == count - 1) _end = end;
932
                        var tmp = (_start + _end) * 0.5;
933

    
934
                        var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
935
                        var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
936
                        GArc arc = new GArc(plane, center, _start.DistanceTo(_end) * 0.5, Math.PI, Math.PI * 2);
937
                        res.Add(arc);
938
                    }
939
                }
940

    
941
                return res;
942
            }
943

    
944
            GCompositeCurve profile = new GCompositeCurve();
945

    
946
            var vertices = obr.GetVertices();
947
            for(int i = 0;i < vertices.Length;++i)
948
            {
949
                var curves = DrawRevCloudLine(vertices[i], vertices[(i + 1) % vertices.Length]);
950
                profile.CurveList.AddRange(curves);
951
            }
952

    
953
            var revcloud = new devDept.Eyeshot.Entities.CompositeCurve(profile);
954
            revcloud.LayerName = Verification.RevCloudLayer;
955
            revcloud.Color = Verification.RevCloudColor;
956
            revcloud.ColorMethod = colorMethodType.byEntity;
957
            revcloud.LineWeight = 10;
958
            revcloud.LineWeightMethod = colorMethodType.byEntity;
959
            design.Entities.Add(revcloud);
960
        }
961

    
962
        /// <summary>
963
        /// 주어진 두 엔터티를 비교한다.
964
        /// </summary>
965
        /// <param name="entVp1"></param>
966
        /// <param name="entVp2"></param>
967
        /// <returns></returns>
968
        private bool CompareIfEqual(Design design1, Entity entVp1, Design design2, Entity entVp2)
969
        {
970
            return AreEqual(design1, entVp1, design2, entVp2);
971
        }
972

    
973
        private bool CompareGEntityIfEqual(GEntity entVp1, GEntity entVp2)
974
        {
975
            return AreGEntityEqual(entVp1, entVp2);
976
        }
977

    
978
        /// <summary>
979
        /// 그래픽적으로 두 엔터티가 유사한지 검사한다.
980
        /// </summary>
981
        /// <param name="design1"></param>
982
        /// <param name="ent1"></param>
983
        /// <param name="design2"></param>
984
        /// <param name="ent2"></param>
985
        /// <returns></returns>
986
        private bool AreEqual(Design design1, Entity ent1, Design design2, Entity ent2)
987
        {
988
            if (ent1 is CompositeCurve cc1 && ent2 is CompositeCurve cc2)
989
            {
990
                if (cc1.CurveList.Count == cc2.CurveList.Count)
991
                {
992
                    int equalCurvesInListCount = 0;
993
                    foreach (var entC in cc1.CurveList)
994
                    {
995
                        foreach (var entC2 in cc2.CurveList)
996
                        {
997
                            if (entC.GetType() == entC2.GetType())
998
                            {
999
                                if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
1000
                                {
1001
                                    equalCurvesInListCount++;
1002
                                    break;
1003
                                }
1004
                                else if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
1005
                                {
1006
                                    equalCurvesInListCount++;
1007
                                    break;
1008
                                }
1009
                            }
1010
                        }
1011
                    }
1012

    
1013
                    if (cc1.CurveList.Count == equalCurvesInListCount)
1014
                    {
1015
                        return true;
1016
                    }
1017
                }
1018
            }
1019
            else if (ent1 is LinearPath lp1 && ent2 is LinearPath lp2)
1020
            {
1021
                if (lp1.Vertices.Length == lp2.Vertices.Length)
1022
                {
1023
                    for (int i = 0; i < lp1.Vertices.Length; i++)
1024
                    {
1025
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
1026
                            return false;
1027
                    }
1028

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

    
1162
                    else if (ent1 is devDept.Eyeshot.Entities.Attribute att1 && ent2 is devDept.Eyeshot.Entities.Attribute att2)
1163
                    {
1164
                        if (
1165
                            att1.Value == att2.Value &&
1166
                            att1.InsertionPoint.DistanceTo(att2.InsertionPoint) <= Verification.Tolerance
1167
                            )
1168
                        {
1169
                            return true;
1170
                        }
1171
                    }
1172
                    else
1173
                    {
1174
                        Text tx1 = (Text)ent1;
1175
                        Text tx2 = (Text)ent2;
1176

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

    
1219
                if (
1220
                    devDept.Geometry.Vector3D.AreParallel(dir, vec) &&
1221
                    line1.StartPoint.DistanceTo(start) <= Verification.Tolerance &&
1222
                    line1.EndPoint.DistanceTo(end) <= Verification.Tolerance
1223
                )
1224
                {
1225
                    return true;
1226
                }
1227
            }
1228
            else if (ent1 is devDept.Eyeshot.Entities.Point point1 && ent2 is devDept.Eyeshot.Entities.Point point2)
1229
            {
1230
                if (point1.Position.DistanceTo(point2.Position) <= Verification.Tolerance)
1231
                {
1232
                    return true;
1233
                }
1234
            }
1235
            else if (ent1 is Curve cu1 && ent2 is Curve cu2)
1236
            {
1237
                if (
1238
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1239
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1240
                    cu1.Degree == cu2.Degree
1241
                    )
1242
                {
1243
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1244
                    {
1245
                        if (cu1.ControlPoints[k].DistanceTo(cu2.ControlPoints[k]) > Verification.Tolerance)
1246
                        {
1247
                            return false;
1248
                        }
1249
                    }
1250

    
1251
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
1252
                    {
1253
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
1254
                        {
1255
                            return false;
1256
                        }
1257
                    }
1258

    
1259
                    return true;
1260
                }
1261
            }
1262
            else if (ent1 is Mesh m1 && ent2 is Mesh m2 && m1.Vertices.Count() == m2.Vertices.Count())
1263
            {
1264
                for (int i = 0; i < m1.Vertices.Count(); ++i)
1265
                {
1266
                    if (m1.Vertices[i].DistanceTo(m2.Vertices[i]) > Verification.Tolerance) return false;
1267
                }
1268

    
1269
                return true;
1270
            }
1271
            else if (ent1 is BlockReference blkref1 && ent2 is BlockReference blkref2)
1272
            {
1273
                int equalCurvesInEntityList = 0;
1274

    
1275
                #region Point, Attribute, Text 제거 및 LinePath를 라인으로 분리
1276
                var entities1 = blkref1.Explode(design1.Blocks).Where(x => x.LayerName != "AS_PORT" && !(x is devDept.Eyeshot.Entities.Point) &&
1277
                !(x is devDept.Eyeshot.Entities.Attribute) && !(x is devDept.Eyeshot.Entities.Text)).ToList();
1278
                var coll1 = new List<Entity>();
1279
                entities1.ForEach(x =>
1280
                {
1281
                    if (x is LinearPath lp)
1282
                    {
1283
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1284
                        {
1285
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1286
                            coll1.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1287
                        }
1288
                    }
1289
                    else
1290
                    {
1291
                        coll1.Add(x);
1292
                    }
1293
                });
1294
                #endregion
1295

    
1296
                #region Point 및 Nesting Block 제거 및 LinePath를 라인으로 분리
1297
                var entities2 = blkref2.Explode(design2.Blocks).Where(x => 
1298
                !(x is devDept.Eyeshot.Entities.BlockReference blkref && blkref.BlockName == "PORT") && !(x is devDept.Eyeshot.Entities.Point)).ToList();
1299
                var coll2 = new List<Entity>();
1300
                entities2.ForEach(x =>
1301
                {
1302
                    if (x is LinearPath lp)
1303
                    {
1304
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1305
                        {
1306
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1307
                            coll2.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1308
                        }
1309
                    }
1310
                    else if (x is devDept.Eyeshot.Entities.Attribute attr)
1311
                    {
1312
                        if (!attr.Invisible) coll2.Add(attr);
1313
                    }
1314
                    else if (x.GetType().Name == "AttributeReferenceData")
1315
                    {
1316
                    }
1317
                    else
1318
                    {
1319
                        coll2.Add(x);
1320
                    }
1321
                });
1322
                #endregion
1323

    
1324
                if (coll1.Count != coll2.Count) return false;
1325

    
1326
                foreach (var entC in coll1)
1327
                {
1328
                    foreach (var entC2 in coll2)
1329
                    {
1330
                        if (entC.GetType() == entC2.GetType())
1331
                        {
1332
                            if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
1333
                            {
1334
                                equalCurvesInEntityList++;
1335
                                break;
1336
                            }
1337
                        }
1338
                    }
1339
                }
1340

    
1341
                if (coll1.Count == equalCurvesInEntityList)
1342
                {
1343
                    return true;
1344
                }
1345
            }
1346
            else
1347
            {
1348
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1349
                return false;
1350
            }
1351

    
1352
            return false;
1353
        }
1354

    
1355
        private bool AreGEntityEqual(GEntity ent1, GEntity ent2)
1356
        {
1357
            if (ent1 is GCompositeCurve cc1 && ent2 is GCompositeCurve cc2)
1358
            {
1359
                if (cc1.CurveList.Count == cc2.CurveList.Count)
1360
                {
1361
                    int equalCurvesInListCount = 0;
1362
                    foreach (var entC in cc1.CurveList)
1363
                    {
1364
                        foreach (var entC2 in cc2.CurveList)
1365
                        {
1366
                            if (entC.GetType() == entC2.GetType())
1367
                            {
1368
                                if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
1369
                                {
1370
                                    equalCurvesInListCount++;
1371
                                    break;
1372
                                }
1373
                            }
1374
                        }
1375
                    }
1376

    
1377
                    if (cc1.CurveList.Count == equalCurvesInListCount)
1378
                    {
1379
                        return true;
1380
                    }
1381
                }
1382
            }
1383
            else if (ent1 is GLinearPath lp1 && ent2 is GLinearPath lp2)
1384
            {
1385
                if (lp1.Vertices.Length == lp2.Vertices.Length)
1386
                {
1387
                    for (int i = 0; i < lp1.Vertices.Length; i++)
1388
                    {
1389
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
1390
                            return false;
1391
                    }
1392
                    return true;
1393
                }
1394
            }
1395

    
1396
            else if (ent1 is GPlanarEntity pe1 && ent2 is GPlanarEntity pe2)
1397
            {
1398
                if (
1399
                    pe1.Plane.AxisZ == pe2.Plane.AxisZ &&
1400
                    pe1.Plane.AxisX == pe2.Plane.AxisX
1401
                    )
1402
                {
1403
                    if (ent1 is GArc arc1 && ent2 is GArc arc2)
1404
                    {
1405
                        if (
1406
                            arc1.Center.DistanceTo(arc2.Center) <= Verification.Tolerance &&
1407
                            Math.Abs(arc1.Radius - arc2.Radius) <= Verification.Tolerance &&
1408
                            Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Verification.Tolerance &&
1409
                            Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Verification.Tolerance
1410
                            )
1411
                        {
1412
                            return true;
1413
                        }
1414
                    }
1415
                    else if (ent1 is GCircle c1 && ent2 is GCircle c2)
1416
                    {
1417
                        if (c1.Center.DistanceTo(c2.Center) <= Verification.Tolerance && 
1418
                            Math.Abs(c1.Radius - c2.Radius) <= Verification.Tolerance)
1419
                        {
1420
                            return true;
1421
                        }
1422
                    }
1423
                    else if (ent1 is GEllipticalArc e1 && ent2 is GEllipticalArc e2)
1424
                    {
1425
                        if (
1426
                            e1.Center.DistanceTo(e2.Center) <= Verification.Tolerance &&
1427
                            Math.Abs(e1.RadiusX - e2.RadiusX) <= Verification.Tolerance &&
1428
                            Math.Abs(e1.RadiusY - e2.RadiusY) <= Verification.Tolerance &&
1429
                            Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Verification.Tolerance &&
1430
                            Math.Abs(e1.Domain.High - e2.Domain.High) <= Verification.Tolerance
1431
                        )
1432
                        {
1433
                            return true;
1434
                        }
1435
                    }
1436
                    else if (ent1 is GEllipse el1 && ent2 is GEllipse el2)
1437
                    {
1438
                        if (
1439
                            el1.Center.DistanceTo(el2.Center) <= Verification.Tolerance &&
1440
                            Math.Abs(el1.RadiusX - el2.RadiusX) <= Verification.Tolerance &&
1441
                            Math.Abs(el1.RadiusY - el2.RadiusY) <= Verification.Tolerance
1442
                        )
1443
                        {
1444
                            return true;
1445
                        }
1446
                    }
1447
                    else
1448
                    {
1449
                        Console.Write("Type " + ent1.GetType() + " not implemented.");
1450
                        return true;
1451
                    }
1452
                }
1453
            }
1454

    
1455
            else if (ent1 is GLine line1 && ent2 is GLine line2)
1456
            {
1457
                if (line1.StartPoint.DistanceTo(line2.StartPoint) <= Verification.Tolerance && 
1458
                    line1.EndPoint.DistanceTo(line2.EndPoint) <= Verification.Tolerance
1459
                )
1460
                {
1461
                    return true;
1462
                }
1463
            }
1464
#if NURBS
1465
            else if (ent1 is Curve)
1466
            {
1467
                Curve cu1 = (Curve)ent1;
1468
                Curve cu2 = (Curve)ent2;
1469

    
1470
                if (
1471
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1472
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1473
                    cu1.Degree == cu2.Degree
1474
                    )
1475
                {
1476
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1477
                    {
1478
                        if (cu1.ControlPoints[k] != cu2.ControlPoints[k])
1479
                        {
1480
                            return false;
1481
                        }
1482
                    }
1483

    
1484
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
1485
                    {
1486
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
1487
                        {
1488
                            return false;
1489
                        }
1490
                    }
1491

    
1492
                    return true;
1493
                }
1494
            }
1495
#endif
1496

    
1497
            else
1498
            {
1499
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1500
                return true;
1501
            }
1502
            return false;
1503
        }
1504

    
1505
        #region Camera Sync
1506
        private void CameraChanged(object sender, devDept.Eyeshot.Workspace.CameraMoveEventArgs e)
1507
        {
1508
            if (sender == this.designAutoCAD)
1509
            {
1510
                SyncCamera(this.designAutoCAD, this.designAVEVA);
1511
                SyncCamera(this.designAutoCAD, this.designCompare);
1512
            }
1513
            else if (sender == this.designAVEVA)
1514
            {
1515
                SyncCamera(this.designAVEVA, this.designAutoCAD);
1516
                SyncCamera(this.designAVEVA, this.designCompare);
1517
            }
1518
            else
1519
            {
1520
                SyncCamera(this.designCompare, this.designAutoCAD);
1521
                SyncCamera(this.designCompare, this.designAVEVA);
1522
            }
1523
        }
1524

    
1525
        private void SyncCamera(Design designMovedCamera, Design designCameraToMove)
1526
        {
1527
            Camera savedCamera;
1528
            designMovedCamera.SaveView(out savedCamera);
1529

    
1530
            // restores the camera to the other model
1531
            designCameraToMove.RestoreView(savedCamera);
1532
            designCameraToMove.AdjustNearAndFarPlanes();
1533
            designCameraToMove.Invalidate();
1534
        }
1535
        #endregion
1536
    }
1537
}
클립보드 이미지 추가 (최대 크기: 500 MB)