프로젝트

일반

사용자정보

통계
| 개정판:

hytos / ID2.Manager / ID2.Manager.Compare / Controls / Verification.cs @ 2ade1e61

이력 | 보기 | 이력해설 | 다운로드 (76.9 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
            this.designAutoCAD.SetView(viewType.Trimetric);
64

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

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

    
76
            _progressBar = progressBar;
77

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
326
            string _ArrowMaxLength = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Arrow Max Length");
327
            if (!string.IsNullOrEmpty(_ArrowMaxLength))
328
            {
329
                Forms.ExceptLayer.ArrowMaxLength = Convert.ToDouble(_ArrowMaxLength);
330
            }
331

    
332
            #region Except Layer를 로딩한다.
333
            LoadLayerSettings();
334
            #endregion
335
        }
336

    
337
        /// <summary>
338
        /// 레이어 설정을 읽는다.
339
        /// </summary>
340
        public void LoadLayerSettings()
341
        {
342
            Forms.ExceptLayer.ExceptLayers.Clear();
343
            Forms.ExceptLayer.LineLayers.Clear();
344

    
345
            string _ExceptLayers = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers");
346
            if (!string.IsNullOrEmpty(_ExceptLayers))
347
            {
348
                Forms.ExceptLayer.ExceptLayers.AddRange(_ExceptLayers.Split(',').ToList().ConvertAll(x => new Forms.ExceptLayer.Layer(x)));
349

    
350
                string _ExceptLayersVisible = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Except Layers Visible");
351
                if (!string.IsNullOrEmpty(_ExceptLayersVisible))
352
                {
353
                    var tokens = _ExceptLayersVisible.Split(',').ToList().ConvertAll(x => Convert.ToBoolean(x));
354
                    for (int i = 0; i < Forms.ExceptLayer.ExceptLayers.Count; ++i)
355
                    {
356
                        if (i < tokens.Count)
357
                        {
358
                            Forms.ExceptLayer.ExceptLayers[i].Visible = tokens[i];
359
                        }
360
                    }
361
                }
362
            }
363

    
364
            string _LineLayers = Classes.ID2Helper.IniReadValue(IniFilePath, "Verification", "Line Layers");
365
            if (!string.IsNullOrEmpty(_LineLayers))
366
            {
367
                Forms.ExceptLayer.LineLayers.AddRange(_LineLayers.Split(',').ToList().ConvertAll(x => new Forms.ExceptLayer.Layer(x)));
368
            }
369
        }
370

    
371
        /// <summary>
372
        /// 엔터티들의 색상을 바꾼다.
373
        /// </summary>
374
        /// <param name="design"></param>
375
        /// <param name="list"></param>
376
        public void ColorEntities(Design design, IList<Entity> list, Color color, colorMethodType colorMethod=colorMethodType.byEntity, bool ChangeBlkColor=true)
377
        {
378
            foreach (Entity ent in list)
379
            {
380
                ColorEntity(design, ent, color, colorMethod, ChangeBlkColor);
381
            }
382
        }
383

    
384
        /// <summary>
385
        /// 엔터티의 색상을 변경한다.
386
        /// </summary>
387
        /// <param name="design"></param>
388
        /// <param name="entity"></param>
389
        /// <param name="color"></param>
390
        private void ColorEntity(Design design, Entity entity, Color color, colorMethodType colorMethod = colorMethodType.byEntity, 
391
            bool ChangeBlkColor = true)
392
        {
393
            if (entity is BlockReference blkref)
394
            {
395
                blkref.Color = color;
396
                blkref.ColorMethod = colorMethod;
397

    
398
                if (ChangeBlkColor)
399
                {
400
                    var blk = design.Blocks.FirstOrDefault(x => x.Name == blkref.BlockName);
401
                    if (blk != null)
402
                    {
403
                        ColorEntities(design, blk.Entities, color, colorMethodType.byParent);
404
                        foreach (var attr in blkref.Attributes.Values)
405
                        {
406
                            attr.Color = color;
407
                            attr.ColorMethod = colorMethodType.byParent;
408
                        }
409
                    }
410
                }
411
            }
412
            else
413
            {
414
                entity.Color = color;
415
                entity.ColorMethod = colorMethod;
416
            }
417
        }
418

    
419
        /// <summary>
420
        /// 블럭 참조를 깨어 블럭의 구성 요소들을 리트스트 리턴한다.
421
        /// </summary>
422
        /// <param name="design"></param>
423
        /// <param name="blkref"></param>
424
        /// <param name="LayerName"></param>
425
        /// <param name="color"></param>
426
        /// <returns></returns>
427
        private List<Entity> ExplodeBlockReference(BlockKeyedCollection Blocks, BlockReference blkref, string LayerName, Color color)
428
        {
429
            var res = new List<Entity>();
430

    
431
            var entities = blkref.Explode(Blocks);
432
            entities.ToList().ForEach(y =>
433
            {
434
                #region 블럭 이름이 ARROW로 시작되는 경우 Hatch로 화살표를 그려준다.
435
                if (y is LinearPath arrow && arrow.Vertices.Length == 2 && blkref.BlockName.StartsWith("ARROW"))
436
                {
437
                    double weight = arrow.LineWeight * blkref.GetScaleFactorY();
438
                    var dir = new devDept.Geometry.Vector3D(arrow.Vertices[0], arrow.Vertices[1]);
439
                    dir.Normalize();
440
                    var cross = devDept.Geometry.Vector3D.Cross(devDept.Geometry.Vector3D.AxisZ, dir);
441
                    var pts = new devDept.Geometry.Point3D[]
442
                    {
443
                        arrow.Vertices[1] + cross * weight * 0.5,
444
                        arrow.Vertices[0],
445
                        arrow.Vertices[1] - cross * weight * 0.5
446
                    };
447

    
448
                    var hatch = new Hatch("SOLID", new List<ICurve>() { new LinearPath(pts)});
449
                    res.Add(hatch);
450
                }
451
                #endregion
452
                else if (y is LinearPath lp)
453
                {
454
                    int count = Convert.ToInt32(lp.Vertices.Length);
455
                    for (int i = 0; i < count - 1; ++i)
456
                    {
457
                        var line = new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
458
                        {
459
                            LayerName = lp.LayerName,
460
                            LineWeight = lp.LineWeight,
461
                            LineTypeMethod = colorMethodType.byEntity,
462
                            Color = lp.Color,
463
                            ColorMethod = colorMethodType.byEntity
464
                        };
465
                        res.Add(line);
466
                    }
467
                }
468
                /// PORT, ARROW로 시작하는 블럭은 제외
469
                else if(y is BlockReference subblkref && subblkref.BlockName != "PORT")
470
                {
471
                    res.AddRange(ExplodeBlockReference(Blocks, subblkref, LayerName, color));
472
                }
473
            });
474

    
475
            var attributes = blkref.Attributes;
476
            foreach (var ent in entities.Where(y => y is devDept.Eyeshot.Entities.Attribute attr && !attr.Invisible))
477
            {
478
                var txt = ent as devDept.Eyeshot.Entities.Attribute;
479
                #region 텍스트가 뒤집어지는 것을 방지하기 위해 평면을 교체
480
                if (txt.Plane.AxisX.Equals(devDept.Geometry.Vector3D.AxisMinusX) && txt.Plane.AxisY.Equals(devDept.Geometry.Vector3D.AxisY))
481
                {
482
                    txt.Plane = new devDept.Geometry.Plane(txt.Plane.Origin, devDept.Geometry.Vector3D.AxisX, devDept.Geometry.Vector3D.AxisY);
483
                }
484
                #endregion
485
                txt.LayerName = LayerName;
486
                txt.Color = color;
487
                txt.ColorMethod = colorMethodType.byEntity;
488
                KeyValuePair<string, AttributeReference>? kp = attributes.FirstOrDefault(z => z.Key == txt.TextString);
489
                if (kp.HasValue) txt.TextString = (kp.Value.Value) != null ? kp.Value.Value.Value : string.Empty;
490
            }
491

    
492
            res.AddRange(entities.Where(y =>
493
            {
494
                if (y is devDept.Eyeshot.Entities.Attribute attr && (string.IsNullOrEmpty(attr.TextString) || attr.Invisible)) return false;
495
                if (y is devDept.Eyeshot.Entities.Text text && string.IsNullOrEmpty(text.TextString)) return false;
496
                if (y is devDept.Eyeshot.Entities.Point) return false;
497
                if (y is BlockReference subblkref) return false;
498
                if (y is LinearPath) return false;
499
                if (y.LayerName.ToUpper() == "AS_PORT") return false;
500
                return true;
501
            }));
502

    
503
            #region 제외 레이어에 속한 항목은 포함하지 않는다.
504
            res.RemoveAll(x =>
505
            {
506
                return Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible);
507
            });
508
            #endregion
509
            foreach (var ent in res) ent.LayerName = LayerName;
510

    
511
            blkref.Attributes.Clear();
512
            ///blkref.UpdateBoundingBox(new TraversalParams(design));
513

    
514
            return res;
515
        }
516

    
517
        /// <summary>
518
        /// 주어진 도면의 원본과 AVEVA를 비교한다.
519
        /// </summary>
520
        private void CompareDrawing(Document doc, bool ResultOnly = false)
521
        {
522
            /// AutoCAD P&ID 파일을 화면에 표시한다.
523
            void ShowAutoCADFile(string FilePath, Design design, bool clear = true)
524
            {
525
                if (clear) design.Clear();
526
                var AddEntities = new List<Entity>();
527

    
528
                if (System.IO.File.Exists(FilePath))
529
                {
530
                    try
531
                    {
532
                        #region 다른 프로세스에서 파일을 열고 있는 경우 처리
533
                        using (var fs = File.Open(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
534
                        #endregion
535

    
536
                        {
537
                            devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(fs);
538
                            ra.DoWork();
539
                            var min = ra.Min;
540
                            if (!ra.Layers.Contains(Verification.AutoCADLayer)) ra.Layers.Add(Verification.AutoCADLayer, Verification.AutoCADColor);
541
                            foreach (var ent in ra.Entities)
542
                            {
543
                                /// 도면을 원점으로 맞춘다.
544
                                if (min.X != 0 && min.Y != 0) ent.Translate(-min.X, -min.Y);
545

    
546
                                if (ent is BlockReference blkref)
547
                                {
548
                                    AddEntities.AddRange(ExplodeBlockReference(ra.Blocks, blkref, Verification.AutoCADLayer, Verification.AutoCADColor));
549
                                }
550
                            }
551
                            ra.AddToScene(design);
552
                        }
553
                    }
554
                    catch (Exception ex)
555
                    {
556
                        RadMessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, RadMessageIcon.Error);
557
                        return;
558
                    }
559

    
560
                    #region LinearPath를 Line으로 분할한다.
561
                    design.Entities.ForEach(x =>
562
                    {
563
                        if (x is LinearPath lp)
564
                        {
565
                            #region 정점 수가 2이고 LineWeight이 0 초과이고 길이가 ArrowMaxLength보다 작을때 화살표를 그려준다.
566
                            if (lp.Vertices.Count() == 2 && lp.LineWeight > 0 && lp.Length() < Forms.ExceptLayer.ArrowMaxLength)
567
                            {
568
                                double weight = lp.LineWeight;
569
                                var dir = new devDept.Geometry.Vector3D(lp.Vertices[0], lp.Vertices[1]);
570
                                dir.Normalize();
571
                                var cross = devDept.Geometry.Vector3D.Cross(devDept.Geometry.Vector3D.AxisZ, dir);
572
                                var pts = new devDept.Geometry.Point3D[]
573
                                {
574
                                    lp.Vertices[1] + cross * weight * 0.5,
575
                                    lp.Vertices[0],
576
                                    lp.Vertices[1] - cross * weight * 0.5
577
                                };
578

    
579
                                var hatch = new Hatch("SOLID", new List<ICurve>() { new LinearPath(pts) });
580
                                AddEntities.Add(hatch);
581
                            }
582
                            #endregion
583
                            else
584
                            {
585
                                int count = Convert.ToInt32(lp.Vertices.Length);
586
                                for (int i = 0; i < count - 1; ++i)
587
                                {
588
                                    AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
589
                                    {
590
                                        LayerName = lp.LayerName,
591
                                        LineWeight = lp.LineWeight,
592
                                        LineTypeMethod = colorMethodType.byEntity
593
                                    });
594
                                }
595
                            }
596
                        }
597
                    });
598
                    design.Entities.RemoveAll(x => (x is LinearPath));
599
                    #endregion
600

    
601
                    design.Entities.AddRange(AddEntities);
602

    
603
                    #region 브랜치가 생성되는 부분에서 파이프 라인을 분할
604
                    var queue = design.Entities.Where(x => x is Line && 
605
                    Forms.ExceptLayer.LineLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper())).ToList();
606
                    while (queue.Any())
607
                    {
608
                        var line1 = queue.First() as Line;
609
                        var dir1 = line1.Direction;
610
                        dir1.Normalize();
611
                        queue.Remove(line1);
612
                        for (int i = 0; i < queue.Count; ++i)
613
                        {
614
                            var line2 = queue.ElementAt(i) as Line;
615
                            var dir2 = line2.Direction;
616
                            dir2.Normalize();
617
                            if (devDept.Geometry.Vector3D.AreOrthogonal(dir1, dir2))
618
                            {
619
                                var intersects = line1.IntersectWith(line2);
620
                                if (intersects.Count() == 1)
621
                                {
622
                                    if (line1.StartPoint.DistanceTo(intersects[0]) > 0.1 && line1.EndPoint.DistanceTo(intersects[0]) > 0.1)
623
                                    {
624
                                        var split1 = new devDept.Eyeshot.Entities.Line(line1.StartPoint, intersects[0])
625
                                        {
626
                                            LayerName = line1.LayerName,
627
                                            LineWeight = line1.LineWeight,
628
                                            LineTypeMethod = colorMethodType.byEntity
629
                                        };
630
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line1.EndPoint)
631
                                        {
632
                                            LayerName = line1.LayerName,
633
                                            LineWeight = line1.LineWeight,
634
                                            LineTypeMethod = colorMethodType.byEntity
635
                                        };
636
                                        design.Entities.Add(split1);
637
                                        design.Entities.Add(split2);
638
                                        design.Entities.Remove(line1);
639

    
640
                                        queue.Add(split1);
641
                                        queue.Add(split2);
642

    
643
                                        break;
644
                                    }
645

    
646
                                    if (line2.StartPoint.DistanceTo(intersects[0]) > 0.1 && line2.EndPoint.DistanceTo(intersects[0]) > 0.1)
647
                                    {
648
                                        var split1 = new devDept.Eyeshot.Entities.Line(line2.StartPoint, intersects[0])
649
                                        {
650
                                            LayerName = line2.LayerName,
651
                                            LineWeight = line2.LineWeight,
652
                                            LineTypeMethod = colorMethodType.byEntity
653
                                        };
654
                                        var split2 = new devDept.Eyeshot.Entities.Line(intersects[0], line2.EndPoint)
655
                                        {
656
                                            LayerName = line2.LayerName,
657
                                            LineWeight = line2.LineWeight,
658
                                            LineTypeMethod = colorMethodType.byEntity
659
                                        };
660
                                        design.Entities.Add(split1);
661
                                        design.Entities.Add(split2);
662
                                        design.Entities.Remove(line2);
663

    
664
                                        queue.Remove(line2);
665
                                        queue.Add(split1);
666
                                        queue.Add(split2);
667
                                    }
668
                                }
669
                            }
670
                        }
671
                    }
672
                    #endregion
673

    
674
                    #region 레이어 변경
675
                    foreach (var ent in design.Entities)
676
                    {
677
                        ent.Color = Verification.AutoCADColor;
678
                        ent.ColorMethod = colorMethodType.byEntity;
679
                        if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
680
                        {
681
                            ent.LayerName = Verification.AutoCADLayer;
682
                        }
683
                    }
684
                    #endregion
685

    
686
                    #region 블럭이거나 제외 레이어에 속한 항목은 제거
687
                    design.Entities.RemoveAll(x => (x is BlockReference) || Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
688
                    #endregion
689

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

    
694
                    ColorEntities(design, design.Entities, Verification.AutoCADColor);
695

    
696
                    // Sets the view as Top
697
                    design.SetView(viewType.Top);
698
                    design.ZoomFit();
699
                    design.Invalidate();
700
                }
701
            }
702

    
703
            /// AVEVA P&ID 파일을 화면에 표시한다.
704
            void ShowAVEVAPIDFile(string FilePath, Design design, bool clear = true)
705
            {
706
                if (clear) design.Clear();
707
                if (System.IO.File.Exists(FilePath))
708
                {
709
                    var AddEntities = new List<Entity>();
710

    
711
                    #region 다른 프로세스에서 파일을 열고 있는 경우 처리
712
                    using (var fs = File.Open(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
713
                    #endregion
714
                    {
715
                        devDept.Eyeshot.Translators.ReadAutodesk ra = new devDept.Eyeshot.Translators.ReadAutodesk(fs);
716
                        ra.DoWork();
717

    
718
                        if (!ra.Layers.Contains(Verification.AVEVALayer)) ra.Layers.Add(Verification.AVEVALayer, Verification.AVEVAColor);
719
                        var min = ra.Min;
720
                        foreach (var ent in ra.Entities)
721
                        {
722
                            /// 도면을 원점으로 맞춘다.
723
                            if (min.X != 0 && min.Y != 0) ent.Translate(-min.X, -min.Y);
724

    
725
                            #region 멀티 라인들을 분할하여 추가한다.
726
                            if (ent is Mesh mesh && (mesh.LayerName == "AS_PIPE" || mesh.LayerName == "AS_INST"))
727
                            {
728
                                int count = Convert.ToInt32(mesh.Vertices.Length * 0.5);
729
                                for (int i = 0; i < count - 1; ++i)
730
                                {
731
                                    AddEntities.Add(new devDept.Eyeshot.Entities.Line(mesh.Vertices[i], mesh.Vertices[i + 1])
732
                                    {
733
                                        LayerName = Verification.AVEVALayer,
734
                                        LineWeight = 3.0f,
735
                                        LineTypeMethod = colorMethodType.byEntity,
736
                                        Color = Verification.AVEVAColor,
737
                                        ColorMethod = colorMethodType.byEntity
738
                                    });
739
                                }
740
                            }
741
                            else if (ent is TabulatedSurface tf && (tf.LayerName == "AS_PIPE" || tf.LayerName == "AS_INST"))
742
                            {
743
                                int count = Convert.ToInt32(tf.ControlPoints.Length * 0.5);
744
                                for (int i = 0; i < count - 1; ++i)
745
                                {
746
                                    AddEntities.Add(
747
                                        new devDept.Eyeshot.Entities.Line(
748
                                        new devDept.Geometry.Point3D(tf.ControlPoints[i, 0].X, tf.ControlPoints[i, 0].Y, 0),
749
                                        new devDept.Geometry.Point3D(tf.ControlPoints[i + 1, 0].X, tf.ControlPoints[i + 1, 0].Y, 0))
750
                                        {
751
                                            LayerName = Verification.AVEVALayer,
752
                                            LineWeight = 3.0f,
753
                                            LineTypeMethod = colorMethodType.byEntity,
754
                                            Color = Verification.AVEVAColor,
755
                                            ColorMethod = colorMethodType.byEntity
756
                                        }
757
                                    );
758
                                }
759
                            }
760
                            else if (ent is LinearPath lp)
761
                            {
762
                                int count = Convert.ToInt32(lp.Vertices.Length);
763
                                for (int i = 0; i < count - 1; ++i)
764
                                {
765
                                    AddEntities.Add(new devDept.Eyeshot.Entities.Line(lp.Vertices[i], lp.Vertices[i + 1])
766
                                    {
767
                                        LayerName = Verification.AVEVALayer,
768
                                        LineWeight = lp.LineWeight,
769
                                        Color = Verification.AVEVAColor,
770
                                        LineTypeMethod = colorMethodType.byEntity
771
                                    });
772
                                }
773

    
774
                                #region 밑에서 제거하기 위해 레이어를 AVEVALayer로 바꿔준다.
775
                                lp.LayerName = Verification.AVEVALayer;
776
                                #endregion
777
                            }
778
                            #endregion
779
                            else if (ent is BlockReference blkref)
780
                            {
781
                                if (blkref.BlockName != "LBRK" && blkref.BlockName != "PSNODE" && blkref.BlockName != "PENODE")
782
                                {
783
                                    AddEntities.AddRange(ExplodeBlockReference(ra.Blocks, blkref, Verification.AVEVALayer, Verification.AVEVAColor));
784
                                }
785
                            }
786

    
787
                            ent.Color = Verification.AVEVAColor;
788
                            ent.ColorMethod = colorMethodType.byEntity;
789
                            if (!Forms.ExceptLayer.ExceptLayers.Exists(x => x.Name.ToUpper() == ent.LayerName.ToUpper()))
790
                            {
791
                                ent.LayerName = Verification.AVEVALayer;
792
                            }
793
                        }
794
                        ra.AddToScene(design);
795
                    }
796

    
797
                    #region 불필요한 블럭들은 제거
798
                    design.Entities.RemoveAll(x => x is BlockReference);
799
                    #endregion
800

    
801
                    #region 블럭을 깸
802
                    design.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList().ForEach(x =>
803
                    {
804
                        if(x is BlockReference blkref)
805
                        {
806
                            AddEntities.AddRange(ExplodeBlockReference(design.Blocks, blkref, Verification.AVEVALayer, Verification.AVEVAColor));
807
                        }
808
                    });
809
                    design.Entities.RemoveAll(x =>
810
                    ((x is Mesh || x is TabulatedSurface) && (x.LayerName == Verification.AVEVALayer)) ||
811
                    (x is LinearPath && x.LayerName == Verification.AVEVALayer) || (x is BlockReference) ||
812
                    Forms.ExceptLayer.ExceptLayers.Exists(y => y.Name.ToUpper() == x.LayerName.ToUpper() && !y.Visible));
813
                    design.Entities.AddRange(AddEntities);
814
                    #endregion
815

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

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

    
822
                    design.SetView(viewType.Top);
823
                    design.ZoomFit();
824
                    design.Invalidate();
825
                }
826
            }
827

    
828
            string dwgExtension = ".dwg";
829
            string ID2DrawingFolder = Program.AutoCADFolder;
830
            string dwgFilePath = System.IO.Path.Combine(ID2DrawingFolder, $"{doc.DocumentNo}{dwgExtension}");
831
            if (!ResultOnly) ShowAutoCADFile(dwgFilePath, this.designAutoCAD);
832
            ShowAutoCADFile(dwgFilePath, this.designCompare);
833

    
834
            string AVEVAPIDFolder = Program.AVEVAPIDFolder;
835
            string AVEVAPIDFilePath = string.Empty;
836
            if (AVEVAPIDFolder != null)
837
            {
838
                AVEVAPIDFilePath = System.IO.Path.Combine(AVEVAPIDFolder, $"{doc.DocumentNo}{dwgExtension}");
839
                if (!ResultOnly) ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designAVEVA);
840
                ShowAVEVAPIDFile(AVEVAPIDFilePath, this.designCompare, false);
841
            }
842

    
843
            if (System.IO.File.Exists(dwgFilePath) && System.IO.File.Exists(AVEVAPIDFilePath))
844
            {
845
                var AutoCADEntities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AutoCADLayer).ToList();
846
                var AVEVAtities = this.designCompare.Entities.Where(x => x.LayerName == Verification.AVEVALayer).ToList();
847
                CompareAndMark(this.designCompare, AutoCADEntities, this.designCompare, AVEVAtities);
848
                this.designCompare.Entities.ForEach(x => 
849
                {
850
                    if (x.LayerName != Verification.AVEVALayer && x.LayerName != Verification.AutoCADLayer &&
851
                    x.LayerName != Verification.RevCloudLayer) x.LayerName = Verification.AutoCADLayer;
852
                });
853
            }
854

    
855
            #region 레이어 설정 적용
856
            var layer = this.designCompare.Layers.FirstOrDefault(x => x.Name.ToUpper() == Verification.RevCloudLayer.ToUpper());
857
            if (layer != null) layer.Visible = this.radCheckBoxRevCloud.Checked;
858

    
859
            layer = this.designCompare.Layers.FirstOrDefault(x => x.Name.ToUpper() == Verification.AVEVALayer.ToUpper());
860
            if (layer != null) layer.Visible = this.radCheckBoxAVEVA.Checked;
861

    
862
            layer = this.designCompare.Layers.FirstOrDefault(x => x.Name.ToUpper() == Verification.AutoCADLayer.ToUpper());
863
            if (layer != null) layer.Visible = this.radCheckBoxAutoCAD.Checked;
864

    
865
            this.designCompare.Invalidate();
866
            #endregion
867
        }
868

    
869
        /// <summary>
870
        /// 주어진 두 엔터티 리스트를 비교하여 틀린 엔터티의 색상을 설정한 색상으로 변경한다.
871
        /// </summary>
872
        /// <param name="entList1"></param>
873
        /// <param name="entList2"></param>
874
        private void CompareAndMark(Design design1, IList<Entity> AutoCADEntities, Design design2, IList<Entity> AVEVAEntities)
875
        {
876
            var DiffRegions = new List<devDept.Eyeshot.OrientedBoundingRect>();
877

    
878
            bool[] equalEntitiesInV2 = new bool[AVEVAEntities.Count];
879
            var EqualIndices = new List<int>();
880

    
881
            /// 서로 검사 가능한 타입인지 확인한다.
882
            bool CheckType(Entity ent1, Entity ent2)
883
            {
884
                return ent1.GetType() == ent2.GetType() ||
885
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Text) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText)) ||
886
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
887
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Line) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.TabulatedSurface)) ||
888
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
889
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText));
890
            }
891

    
892
            try
893
            {
894
                for (int i = 0; i < AutoCADEntities.Count(); i++)
895
                {
896
                    Entity entVp1 = AutoCADEntities[i];
897
                    EqualIndices.Clear();
898

    
899
                    for (int j = 0; j < AVEVAEntities.Count(); j++)
900
                    {
901
                        Entity entVp2 = AVEVAEntities[j];
902

    
903
                        if (entVp2 is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE")) continue;
904
                        if (!equalEntitiesInV2[j] && CheckType(entVp1, entVp2) && 
905
                            CompareIfEqual(design1, entVp1, design2, entVp2))
906
                        {
907
                            EqualIndices.Add(j);
908
                        }
909
                    }
910

    
911
                    #region 임계값 안에 들어오는 항목이 여러개 있을 경우 가장 가까운 항목을 유사 항목으로 선택한다.
912
                    if (EqualIndices.Any())
913
                    {
914
                        var ordered = EqualIndices.ConvertAll(x => AVEVAEntities[x]).OrderBy(x =>
915
                        {
916
                            return x.BoxMin.DistanceTo(entVp1.BoxMin);
917
                        });
918

    
919
                        int idx = AVEVAEntities.ToList().FindIndex(x => x == ordered.First());
920
                        equalEntitiesInV2[idx] = true;
921
                    }
922
                    #endregion
923

    
924
                    if (!EqualIndices.Any())
925
                    {
926
                        ColorEntity(design1, AutoCADEntities[i], Verification.DiffColor, colorMethodType.byEntity, false);
927

    
928
                        #region 틀린 엔터티의 BoundingBox를 구함
929
                        var origin = new devDept.Geometry.Point2D(entVp1.BoxMin.X - 1, entVp1.BoxMin.Y - 1);
930
                        double width = entVp1.BoxMax.X - entVp1.BoxMin.X;
931
                        double height = entVp1.BoxMax.Y - entVp1.BoxMin.Y;
932
                        if (Math.Abs(width) != double.PositiveInfinity && Math.Abs(height) != double.PositiveInfinity)
933
                        {
934
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
935
                            DiffRegions.Add(rect);
936
                        }
937
                        #endregion
938
                    }
939
                }
940

    
941
                for (int j = 0; j < AVEVAEntities.Count; j++)
942
                {
943
                    if (!equalEntitiesInV2[j])
944
                    {
945
                        ColorEntity(design2, AVEVAEntities[j], Verification.DiffColor, colorMethodType.byEntity, false);
946

    
947
                        #region 틀린 엔터티의 BoundingBox를 구함 
948
                        var origin = new devDept.Geometry.Point2D(AVEVAEntities[j].BoxMin.X - 1, AVEVAEntities[j].BoxMin.Y - 1);
949
                        double width = AVEVAEntities[j].BoxMax.X - AVEVAEntities[j].BoxMin.X;
950
                        double height = AVEVAEntities[j].BoxMax.Y - AVEVAEntities[j].BoxMin.Y;
951
                        if (Math.Abs(width) != double.PositiveInfinity && Math.Abs(height) != double.PositiveInfinity)
952
                        {
953
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
954
                            DiffRegions.Add(rect);
955
                        }
956
                        #endregion
957
                    }
958
                }
959

    
960
                #region 인접한 영역을 하나로 합친다.
961
                var queue = new List<devDept.Eyeshot.OrientedBoundingRect>(DiffRegions);
962
                DiffRegions.Clear();
963
                while (queue.Any())
964
                {
965
                    var first = queue[0];
966
                    var FirstMin = first.GetOrigin();
967
                    var FirstMax = FirstMin + first.GetAxis()[0] * first.Size.X + first.GetAxis()[1] * first.Size.Y;
968

    
969
                    queue.Remove(first);
970
                    bool overlap = false;
971
                    for (int i = 0; i < queue.Count; ++i)
972
                    {
973
                        var second = queue[i];
974
                        overlap = devDept.Eyeshot.OrientedBoundingRect.DoOverlapOrTouch(first, second);
975
                        if (overlap)
976
                        {
977
                            var SecondMin = second.GetOrigin();
978
                            var SecondMax = SecondMin + second.GetAxis()[0] * second.Size.X + second.GetAxis()[1] * second.Size.Y;
979

    
980
                            var min = new devDept.Geometry.Point2D(Math.Min(FirstMin.X, SecondMin.X), Math.Min(FirstMin.Y, SecondMin.Y));
981
                            var max = new devDept.Geometry.Point2D(Math.Max(FirstMax.X, SecondMax.X), Math.Max(FirstMax.Y, SecondMax.Y));
982
                            double width = max.X - min.X;
983
                            double height = max.Y - min.Y;
984

    
985
                            #region 두 영역을 합친다.(작업 완료된 영역도 다시 queue에 넣는다.)
986
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(min, width, height);
987
                            queue.Add(rect);
988
                            queue.AddRange(DiffRegions);
989
                            DiffRegions.Clear();
990
                            queue.Remove(second);
991
                            #endregion
992
                            break;
993
                        }
994
                    }
995

    
996
                    if (!overlap) DiffRegions.Add(first);
997
                }
998
                #endregion
999

    
1000
                if (!design2.Layers.Contains(Verification.RevCloudLayer))
1001
                    design2.Layers.Add(Verification.RevCloudLayer.ToUpper(), Verification.RevCloudColor);
1002
                DiffRegions.ForEach(x => DrawRevCloud(design2, x));
1003
            }
1004
            catch(Exception ex)
1005
            {
1006
                Console.Write($"Error : {ex.Message}");
1007
            }
1008
        }
1009

    
1010
        /// <summary>
1011
        /// Revision mark를 그린다.
1012
        /// </summary>
1013
        /// <param name="design"></param>
1014
        /// <param name="obr"></param>
1015
        private void DrawRevCloud(Design design, devDept.Eyeshot.OrientedBoundingRect obr)
1016
        {
1017
            IList<IGCurve> DrawRevCloudLine(devDept.Geometry.Point2D start, devDept.Geometry.Point2D end)
1018
            {
1019
                var res = new List<IGCurve>();
1020

    
1021
                var AxisX = new devDept.Geometry.Vector3D(end.X - start.X, end.Y - start.Y);
1022
                AxisX.Normalize();
1023
                var AxisY = devDept.Geometry.Vector3D.Cross(devDept.Geometry.Vector3D.AxisZ, AxisX);
1024

    
1025
                double step = 10;
1026
                double dist = start.DistanceTo(end);
1027
                int count = Convert.ToInt32(dist / step);
1028
                if (count == 0 && dist > 0)
1029
                {
1030
                    var tmp = (start + end) * 0.5;
1031

    
1032
                    var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
1033
                    var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
1034
                    GArc arc = new GArc(plane, center, start.DistanceTo(end) * 0.5, Math.PI, Math.PI * 2);
1035
                    res.Add(arc);
1036
                }
1037
                else
1038
                {
1039
                    for (int i = 0; i < count; ++i)
1040
                    {
1041
                        var _start = (start + AxisX * i * step);
1042
                        var _end = (start + AxisX * (i + 1) * step);
1043
                        if (i == count - 1) _end = end;
1044
                        var tmp = (_start + _end) * 0.5;
1045

    
1046
                        var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
1047
                        var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
1048
                        GArc arc = new GArc(plane, center, _start.DistanceTo(_end) * 0.5, Math.PI, Math.PI * 2);
1049
                        res.Add(arc);
1050
                    }
1051
                }
1052

    
1053
                return res;
1054
            }
1055

    
1056
            GCompositeCurve profile = new GCompositeCurve();
1057

    
1058
            var vertices = obr.GetVertices();
1059
            for(int i = 0;i < vertices.Length;++i)
1060
            {
1061
                var curves = DrawRevCloudLine(vertices[i], vertices[(i + 1) % vertices.Length]);
1062
                profile.CurveList.AddRange(curves);
1063
            }
1064

    
1065
            var revcloud = new devDept.Eyeshot.Entities.CompositeCurve(profile);
1066
            revcloud.LayerName = Verification.RevCloudLayer;
1067
            revcloud.Color = Verification.RevCloudColor;
1068
            revcloud.ColorMethod = colorMethodType.byEntity;
1069
            revcloud.LineWeight = 3;
1070
            revcloud.LineWeightMethod = colorMethodType.byEntity;
1071
            design.Entities.Add(revcloud);
1072
        }
1073

    
1074
        /// <summary>
1075
        /// 주어진 두 엔터티를 비교한다.
1076
        /// </summary>
1077
        /// <param name="entVp1"></param>
1078
        /// <param name="entVp2"></param>
1079
        /// <returns></returns>
1080
        private bool CompareIfEqual(Design design1, Entity entVp1, Design design2, Entity entVp2)
1081
        {
1082
            return AreEqual(design1, entVp1, design2, entVp2);
1083
        }
1084

    
1085
        private bool CompareGEntityIfEqual(GEntity entVp1, GEntity entVp2)
1086
        {
1087
            return AreGEntityEqual(entVp1, entVp2);
1088
        }
1089

    
1090
        /// <summary>
1091
        /// 그래픽적으로 두 엔터티가 유사한지 검사한다.
1092
        /// </summary>
1093
        /// <param name="design1"></param>
1094
        /// <param name="ent1"></param>
1095
        /// <param name="design2"></param>
1096
        /// <param name="ent2"></param>
1097
        /// <returns></returns>
1098
        private bool AreEqual(Design design1, Entity ent1, Design design2, Entity ent2)
1099
        {
1100
            if (ent1 is CompositeCurve cc1 && ent2 is CompositeCurve cc2)
1101
            {
1102
                if (cc1.CurveList.Count == cc2.CurveList.Count)
1103
                {
1104
                    int equalCurvesInListCount = 0;
1105
                    foreach (var entC in cc1.CurveList)
1106
                    {
1107
                        foreach (var entC2 in cc2.CurveList)
1108
                        {
1109
                            if (entC.GetType() == entC2.GetType())
1110
                            {
1111
                                if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
1112
                                {
1113
                                    equalCurvesInListCount++;
1114
                                    break;
1115
                                }
1116
                                else if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
1117
                                {
1118
                                    equalCurvesInListCount++;
1119
                                    break;
1120
                                }
1121
                            }
1122
                        }
1123
                    }
1124

    
1125
                    if (cc1.CurveList.Count == equalCurvesInListCount)
1126
                    {
1127
                        return true;
1128
                    }
1129
                }
1130
            }
1131
            else if (ent1 is LinearPath lp1 && ent2 is LinearPath lp2)
1132
            {
1133
                if (lp1.Vertices.Length == lp2.Vertices.Length)
1134
                {
1135
                    for (int i = 0; i < lp1.Vertices.Length; i++)
1136
                    {
1137
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
1138
                            return false;
1139
                    }
1140

    
1141
                    return true;
1142
                }
1143
            }
1144
            else if (ent1 is PlanarEntity && ent2 is PlanarEntity)
1145
            {
1146
                if (ent1 is Arc arc1 && ent2 is Arc arc2)
1147
                {
1148
                    if (
1149
                        arc1.Center.DistanceTo(arc2.Center) <= Verification.Tolerance &&
1150
                        Math.Abs(arc1.Radius - arc2.Radius) <= Verification.Tolerance &&
1151
                        Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Verification.Tolerance &&
1152
                        Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Verification.Tolerance
1153
                        )
1154
                    {
1155
                        return true;
1156
                    }
1157
                }
1158
                else if (ent1 is Circle c1 && ent2 is Circle c2)
1159
                {
1160
                    if (
1161
                        c1.Center.DistanceTo(c2.Center) <= Verification.Tolerance &&
1162
                        Math.Abs(c1.Radius - c2.Radius) <= Verification.Tolerance
1163
                        )
1164
                    {
1165
                        return true;
1166
                    }
1167
                }
1168
                else if (ent1 is EllipticalArc e1 && ent2 is EllipticalArc e2)
1169
                {
1170
                    if (
1171
                        e1.Center.DistanceTo(e2.Center) <= Verification.Tolerance &&
1172
                        Math.Abs(e1.RadiusX - e2.RadiusX) <= Verification.Tolerance &&
1173
                        Math.Abs(e1.RadiusY - e2.RadiusY) <= Verification.Tolerance &&
1174
                        Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Verification.Tolerance &&
1175
                        Math.Abs(e1.Domain.High - e2.Domain.High) <= Verification.Tolerance
1176
                    )
1177
                    {
1178
                        return true;
1179
                    }
1180
                }
1181
                else if (ent1 is Ellipse el1 && ent2 is Ellipse el2)
1182
                {
1183
                    if (
1184
                        el1.Center.DistanceTo(el2.Center) <= Verification.Tolerance &&
1185
                        Math.Abs(el1.RadiusX - el2.RadiusX) <= Verification.Tolerance &&
1186
                        Math.Abs(el1.RadiusY - el2.RadiusY) <= Verification.Tolerance
1187
                    )
1188
                    {
1189
                        return true;
1190
                    }
1191
                }
1192
                #region 해치는 중점만 비교
1193
                else if (ent1 is Hatch hatch1 && ent2 is Hatch hatch2)
1194
                {
1195
                    var center1 = (hatch1.BoxMin + hatch1.BoxMax) * 0.5;
1196
                    center1.Z = 0;
1197
                    var center2 = (hatch2.BoxMin + hatch2.BoxMax) * 0.5;
1198
                    center2.Z = 0;
1199
                    return center1.DistanceTo(center2) < Verification.Tolerance;
1200
                }
1201
                #endregion
1202
                else if (ent1 is Text)
1203
                {
1204
                    if (ent1 is Dimension dim1 && ent2 is Dimension dim2)
1205
                    {
1206
                        if (
1207
                            dim1.InsertionPoint.DistanceTo(dim2.InsertionPoint) <= Verification.Tolerance &&
1208
                            dim1.DimLinePosition.DistanceTo(dim2.DimLinePosition) <= Verification.Tolerance
1209
                            )
1210
                        {
1211
                            if (ent1 is AngularDim ad1 && ent2 is AngularDim ad2)
1212
                            {
1213
                                if (
1214
                                    ad1.ExtLine1.DistanceTo(ad2.ExtLine1) <= Verification.Tolerance &&
1215
                                    ad1.ExtLine2.DistanceTo(ad2.ExtLine2) <= Verification.Tolerance &&
1216
                                    Math.Abs(ad1.StartAngle - ad2.StartAngle) <= Verification.Tolerance &&
1217
                                    Math.Abs(ad1.EndAngle - ad2.EndAngle) <= Verification.Tolerance &&
1218
                                    Math.Abs(ad1.Radius - ad2.Radius) <= Verification.Tolerance
1219
                                    )
1220
                                {
1221
                                    return true;
1222
                                }
1223
                            }
1224
                            else if (ent1 is LinearDim ld1 && ent2 is LinearDim ld2)
1225
                            {
1226
                                if (
1227
                                    ld1.ExtLine1.DistanceTo(ld2.ExtLine1) <= Verification.Tolerance &&
1228
                                    ld1.ExtLine2.DistanceTo(ld2.ExtLine2) <= Verification.Tolerance
1229
                                    )
1230
                                {
1231
                                    return true;
1232
                                }
1233
                            }
1234
                            else if (ent1 is DiametricDim dd1 && ent2 is DiametricDim dd2)
1235
                            {
1236
                                if (
1237
                                    Math.Abs(dd1.Distance - dd2.Distance) <= Verification.Tolerance &&
1238
                                    Math.Abs(dd1.Radius - dd2.Radius) <= Verification.Tolerance &&
1239
                                    Math.Abs(dd1.CenterMarkSize - dd2.CenterMarkSize) <= Verification.Tolerance
1240
                                )
1241
                                {
1242
                                    return true;
1243
                                }
1244
                            }
1245
                            else if (ent1 is RadialDim rd1 && ent2 is RadialDim rd2)
1246
                            {
1247
                                if (
1248
                                    Math.Abs(rd1.Radius - rd2.Radius) <= Verification.Tolerance &&
1249
                                    Math.Abs(rd1.CenterMarkSize - rd2.CenterMarkSize) <= Verification.Tolerance
1250
                                )
1251
                                {
1252
                                    return true;
1253
                                }
1254
                            }
1255
                            else if (ent1 is OrdinateDim od1 && ent2 is OrdinateDim od2)
1256
                            {
1257
                                if (
1258
                                    od1.DefiningPoint.DistanceTo(od2.DefiningPoint) <= Verification.Tolerance &&
1259
                                    od1.Origin.DistanceTo(od2.Origin) <= Verification.Tolerance &&
1260
                                    od1.LeaderEndPoint.DistanceTo(od2.LeaderEndPoint) <= Verification.Tolerance
1261
                                )
1262
                                {
1263
                                    return true;
1264
                                }
1265
                            }
1266
                            else
1267
                            {
1268
                                Console.Write("Type " + ent1.GetType() + " not implemented.");
1269
                                return true;
1270
                            }
1271
                        }
1272
                    }
1273

    
1274
                    else if (ent1 is devDept.Eyeshot.Entities.Attribute att1 && ent2 is devDept.Eyeshot.Entities.Attribute att2)
1275
                    {
1276
                        if (
1277
                            att1.Value == att2.Value &&
1278
                            att1.InsertionPoint.DistanceTo(att2.InsertionPoint) <= Verification.Tolerance
1279
                            )
1280
                        {
1281
                            return true;
1282
                        }
1283
                    }
1284
                    else
1285
                    {
1286
                        Text tx1 = (Text)ent1;
1287
                        Text tx2 = (Text)ent2;
1288

    
1289
                        #region 대소문자, 공백을 무시하여 비교
1290
                        string string1 = tx1.TextString.Trim().ToUpper();
1291
                        string string2 = tx2.TextString.Trim().ToUpper();
1292
                        string1 = System.Text.RegularExpressions.Regex.Replace(string1, @"\s+", "");
1293
                        string2 = System.Text.RegularExpressions.Regex.Replace(string2, @"\s+", "");
1294
                        if (
1295
                            tx1.BoxMin.DistanceTo(tx2.BoxMin) <= Verification.Tolerance &&
1296
                            string1 == string2 &&
1297
                            Math.Abs(tx1.WidthFactor - tx2.WidthFactor) <= Verification.Tolerance &&
1298
                            Math.Abs(tx1.Height - tx2.Height) <= Verification.Tolerance
1299
                            )
1300
                        {
1301
                            return true;
1302
                        }
1303
                        #endregion
1304
                    }
1305
                }
1306
            }
1307
            else if (ent1 is Line line1 && ent2 is Line line2)
1308
            {
1309
                var dir1 = line1.Direction;
1310
                dir1.Normalize();
1311
                var dir2 = line2.Direction;
1312
                dir2.Normalize();
1313
                if (devDept.Geometry.Vector3D.AreParallel(dir1, dir2, 0.1) &&
1314
                    Math.Abs(line1.Length() - line2.Length()) <= line1.Length() * LengthToleranceRatio &&
1315
                    line1.MidPoint.DistanceTo(line2.MidPoint) <= Verification.Tolerance
1316
                )
1317
                {
1318
                    return true;
1319
                }
1320
            }
1321
            else if (ent1 is Line && ent2 is devDept.Eyeshot.Entities.TabulatedSurface lwpolyline && lwpolyline.ControlPoints.Length == 4)
1322
            {
1323
                line1 = ent1 as Line;
1324
                var start = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[0, 0].X, lwpolyline.ControlPoints[0, 0].Y, 0);
1325
                var end = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[1, 0].X, lwpolyline.ControlPoints[1, 0].Y, 0);
1326
                var vec = new devDept.Geometry.Vector3D(start, end);
1327
                vec.Normalize();
1328
                var dir = line1.Direction.Clone() as devDept.Geometry.Vector3D;
1329
                dir.Normalize();
1330

    
1331
                if (
1332
                    devDept.Geometry.Vector3D.AreParallel(dir, vec) &&
1333
                    line1.StartPoint.DistanceTo(start) <= Verification.Tolerance &&
1334
                    line1.EndPoint.DistanceTo(end) <= Verification.Tolerance
1335
                )
1336
                {
1337
                    return true;
1338
                }
1339
            }
1340
            else if (ent1 is devDept.Eyeshot.Entities.Point point1 && ent2 is devDept.Eyeshot.Entities.Point point2)
1341
            {
1342
                if (point1.Position.DistanceTo(point2.Position) <= Verification.Tolerance)
1343
                {
1344
                    return true;
1345
                }
1346
            }
1347
            else if (ent1 is Curve cu1 && ent2 is Curve cu2)
1348
            {
1349
                if (
1350
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1351
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1352
                    cu1.Degree == cu2.Degree
1353
                    )
1354
                {
1355
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1356
                    {
1357
                        if (cu1.ControlPoints[k].DistanceTo(cu2.ControlPoints[k]) > Verification.Tolerance)
1358
                        {
1359
                            return false;
1360
                        }
1361
                    }
1362

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

    
1371
                    return true;
1372
                }
1373
            }
1374
            else if (ent1 is Mesh m1 && ent2 is Mesh m2 && m1.Vertices.Count() == m2.Vertices.Count())
1375
            {
1376
                for (int i = 0; i < m1.Vertices.Count(); ++i)
1377
                {
1378
                    if (m1.Vertices[i].DistanceTo(m2.Vertices[i]) > Verification.Tolerance) return false;
1379
                }
1380

    
1381
                return true;
1382
            }
1383
            else if (ent1 is BlockReference blkref1 && ent2 is BlockReference blkref2)
1384
            {
1385
                int equalCurvesInEntityList = 0;
1386

    
1387
                #region Point, Attribute, Text 제거 및 LinePath를 라인으로 분리
1388
                var entities1 = blkref1.Explode(design1.Blocks).Where(x => x.LayerName != "AS_PORT" && !(x is devDept.Eyeshot.Entities.Point) &&
1389
                !(x is devDept.Eyeshot.Entities.Attribute) && !(x is devDept.Eyeshot.Entities.Text)).ToList();
1390
                var coll1 = new List<Entity>();
1391
                entities1.ForEach(x =>
1392
                {
1393
                    if (x is LinearPath lp)
1394
                    {
1395
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1396
                        {
1397
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1398
                            coll1.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1399
                        }
1400
                    }
1401
                    else
1402
                    {
1403
                        coll1.Add(x);
1404
                    }
1405
                });
1406
                #endregion
1407

    
1408
                #region Point 및 Nesting Block 제거 및 LinePath를 라인으로 분리
1409
                var entities2 = blkref2.Explode(design2.Blocks).Where(x => 
1410
                !(x is devDept.Eyeshot.Entities.BlockReference blkref && blkref.BlockName == "PORT") && !(x is devDept.Eyeshot.Entities.Point)).ToList();
1411
                var coll2 = new List<Entity>();
1412
                entities2.ForEach(x =>
1413
                {
1414
                    if (x is LinearPath lp)
1415
                    {
1416
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
1417
                        {
1418
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
1419
                            coll2.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
1420
                        }
1421
                    }
1422
                    else if (x is devDept.Eyeshot.Entities.Attribute attr)
1423
                    {
1424
                        if (!attr.Invisible) coll2.Add(attr);
1425
                    }
1426
                    else if (x.GetType().Name == "AttributeReferenceData")
1427
                    {
1428
                    }
1429
                    else
1430
                    {
1431
                        coll2.Add(x);
1432
                    }
1433
                });
1434
                #endregion
1435

    
1436
                if (coll1.Count != coll2.Count) return false;
1437

    
1438
                foreach (var entC in coll1)
1439
                {
1440
                    foreach (var entC2 in coll2)
1441
                    {
1442
                        if (entC.GetType() == entC2.GetType())
1443
                        {
1444
                            if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
1445
                            {
1446
                                equalCurvesInEntityList++;
1447
                                break;
1448
                            }
1449
                        }
1450
                    }
1451
                }
1452

    
1453
                if (coll1.Count == equalCurvesInEntityList)
1454
                {
1455
                    return true;
1456
                }
1457
            }
1458
            else
1459
            {
1460
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1461
                return false;
1462
            }
1463

    
1464
            return false;
1465
        }
1466

    
1467
        private bool AreGEntityEqual(GEntity ent1, GEntity ent2)
1468
        {
1469
            if (ent1 is GCompositeCurve cc1 && ent2 is GCompositeCurve cc2)
1470
            {
1471
                if (cc1.CurveList.Count == cc2.CurveList.Count)
1472
                {
1473
                    int equalCurvesInListCount = 0;
1474
                    foreach (var entC in cc1.CurveList)
1475
                    {
1476
                        foreach (var entC2 in cc2.CurveList)
1477
                        {
1478
                            if (entC.GetType() == entC2.GetType())
1479
                            {
1480
                                if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
1481
                                {
1482
                                    equalCurvesInListCount++;
1483
                                    break;
1484
                                }
1485
                            }
1486
                        }
1487
                    }
1488

    
1489
                    if (cc1.CurveList.Count == equalCurvesInListCount)
1490
                    {
1491
                        return true;
1492
                    }
1493
                }
1494
            }
1495
            else if (ent1 is GLinearPath lp1 && ent2 is GLinearPath lp2)
1496
            {
1497
                if (lp1.Vertices.Length == lp2.Vertices.Length)
1498
                {
1499
                    for (int i = 0; i < lp1.Vertices.Length; i++)
1500
                    {
1501
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Verification.Tolerance)
1502
                            return false;
1503
                    }
1504
                    return true;
1505
                }
1506
            }
1507

    
1508
            else if (ent1 is GPlanarEntity pe1 && ent2 is GPlanarEntity pe2)
1509
            {
1510
                if (
1511
                    pe1.Plane.AxisZ == pe2.Plane.AxisZ &&
1512
                    pe1.Plane.AxisX == pe2.Plane.AxisX
1513
                    )
1514
                {
1515
                    if (ent1 is GArc arc1 && ent2 is GArc arc2)
1516
                    {
1517
                        if (
1518
                            arc1.Center.DistanceTo(arc2.Center) <= Verification.Tolerance &&
1519
                            Math.Abs(arc1.Radius - arc2.Radius) <= Verification.Tolerance &&
1520
                            Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Verification.Tolerance &&
1521
                            Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Verification.Tolerance
1522
                            )
1523
                        {
1524
                            return true;
1525
                        }
1526
                    }
1527
                    else if (ent1 is GCircle c1 && ent2 is GCircle c2)
1528
                    {
1529
                        if (c1.Center.DistanceTo(c2.Center) <= Verification.Tolerance && 
1530
                            Math.Abs(c1.Radius - c2.Radius) <= Verification.Tolerance)
1531
                        {
1532
                            return true;
1533
                        }
1534
                    }
1535
                    else if (ent1 is GEllipticalArc e1 && ent2 is GEllipticalArc e2)
1536
                    {
1537
                        if (
1538
                            e1.Center.DistanceTo(e2.Center) <= Verification.Tolerance &&
1539
                            Math.Abs(e1.RadiusX - e2.RadiusX) <= Verification.Tolerance &&
1540
                            Math.Abs(e1.RadiusY - e2.RadiusY) <= Verification.Tolerance &&
1541
                            Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Verification.Tolerance &&
1542
                            Math.Abs(e1.Domain.High - e2.Domain.High) <= Verification.Tolerance
1543
                        )
1544
                        {
1545
                            return true;
1546
                        }
1547
                    }
1548
                    else if (ent1 is GEllipse el1 && ent2 is GEllipse el2)
1549
                    {
1550
                        if (
1551
                            el1.Center.DistanceTo(el2.Center) <= Verification.Tolerance &&
1552
                            Math.Abs(el1.RadiusX - el2.RadiusX) <= Verification.Tolerance &&
1553
                            Math.Abs(el1.RadiusY - el2.RadiusY) <= Verification.Tolerance
1554
                        )
1555
                        {
1556
                            return true;
1557
                        }
1558
                    }
1559
                    else
1560
                    {
1561
                        Console.Write("Type " + ent1.GetType() + " not implemented.");
1562
                        return true;
1563
                    }
1564
                }
1565
            }
1566

    
1567
            else if (ent1 is GLine line1 && ent2 is GLine line2)
1568
            {
1569
                if (line1.StartPoint.DistanceTo(line2.StartPoint) <= Verification.Tolerance && 
1570
                    line1.EndPoint.DistanceTo(line2.EndPoint) <= Verification.Tolerance
1571
                )
1572
                {
1573
                    return true;
1574
                }
1575
            }
1576
#if NURBS
1577
            else if (ent1 is Curve)
1578
            {
1579
                Curve cu1 = (Curve)ent1;
1580
                Curve cu2 = (Curve)ent2;
1581

    
1582
                if (
1583
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
1584
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
1585
                    cu1.Degree == cu2.Degree
1586
                    )
1587
                {
1588
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
1589
                    {
1590
                        if (cu1.ControlPoints[k] != cu2.ControlPoints[k])
1591
                        {
1592
                            return false;
1593
                        }
1594
                    }
1595

    
1596
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
1597
                    {
1598
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
1599
                        {
1600
                            return false;
1601
                        }
1602
                    }
1603

    
1604
                    return true;
1605
                }
1606
            }
1607
#endif
1608

    
1609
            else
1610
            {
1611
                Console.Write("Type " + ent1.GetType() + " not implemented.");
1612
                return true;
1613
            }
1614
            return false;
1615
        }
1616

    
1617
        #region Camera Sync
1618
        private void CameraChanged(object sender, devDept.Eyeshot.Workspace.CameraMoveEventArgs e)
1619
        {
1620
            if (sender == this.designAutoCAD)
1621
            {
1622
                SyncCamera(this.designAutoCAD, this.designAVEVA);
1623
                SyncCamera(this.designAutoCAD, this.designCompare);
1624
            }
1625
            else if (sender == this.designAVEVA)
1626
            {
1627
                SyncCamera(this.designAVEVA, this.designAutoCAD);
1628
                SyncCamera(this.designAVEVA, this.designCompare);
1629
            }
1630
            else
1631
            {
1632
                SyncCamera(this.designCompare, this.designAutoCAD);
1633
                SyncCamera(this.designCompare, this.designAVEVA);
1634
            }
1635
        }
1636

    
1637
        private void SyncCamera(Design designMovedCamera, Design designCameraToMove)
1638
        {
1639
            Camera savedCamera;
1640
            designMovedCamera.SaveView(out savedCamera);
1641

    
1642
            // restores the camera to the other model
1643
            designCameraToMove.RestoreView(savedCamera);
1644
            designCameraToMove.AdjustNearAndFarPlanes();
1645
            designCameraToMove.Invalidate();
1646
        }
1647
        #endregion
1648
    }
1649
}
클립보드 이미지 추가 (최대 크기: 500 MB)