프로젝트

일반

사용자정보

통계
| 개정판:

hytos / ID2.Manager / ID2.Manager.Compare / Classes / CompareModelWorkUnit.cs @ 67cfe4dc

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

1 54be6611 humkyung
using devDept.Eyeshot;
2
using devDept.Eyeshot.Entities;
3
using devDept.Geometry.Entities;
4
using devDept.Eyeshot.Translators;
5
using System;
6
using System.Collections.Generic;
7
using System.ComponentModel;
8
using System.Linq;
9
using System.Text;
10
using System.Threading.Tasks;
11
using devDept.Geometry;
12
using System.Windows.Forms;
13
using Telerik.WinControls;
14
using System.Drawing;
15
using System.Numerics;
16
using System.IO;
17 1620ca9c humkyung
using Xtractor.Viewer;
18 54be6611 humkyung
19
namespace ID2.Manager.Classes
20
{
21
    public class CompareModelWorkUnit : devDept.WorkUnit
22
    {
23
        private static readonly int SLICES = 16;
24
        private static readonly double TOLER = 1;
25
26
        System.ComponentModel.BackgroundWorker _worker;
27 1620ca9c humkyung
28 54be6611 humkyung
        private Workspace _workspace;
29
        private List<Entity> _AutoCADEntities { get; } = new List<Entity>();
30
        private List<Entity> _AVEVAEntities { get; } = new List<Entity>();
31
        public double Tolerance { get; set; } = 0;
32
        public double LengthToleranceRatio { get; set; } = 0;
33
34
        public string AutoCADDiffLayer { get; set; }
35
        public string AVEVADiffLayer { get; set; }
36
        public System.Drawing.Color DiffColor { get; set; }
37
38
        public string RevCloudLayer { get; set; }
39
        public System.Drawing.Color RevCloudColor { get; set; }
40
41 353b7f9f humkyung
        public List<Forms.ExceptLayer.SpecialCharacter> SpecialCharacters = new List<Forms.ExceptLayer.SpecialCharacter>();
42
        public bool Casesensitive { get; set; } = true;
43
44 54be6611 humkyung
        public CompareModelWorkUnit(Workspace workspace, List<Entity> AutoCADEntities, List<Entity> AVEVAtities)
45
        {
46
            _workspace = workspace;
47
            _AutoCADEntities.AddRange(AutoCADEntities);
48
            _AVEVAEntities.AddRange(AVEVAtities);
49
        }
50
51
        public override void DoWork(System.ComponentModel.BackgroundWorker worker, System.ComponentModel.DoWorkEventArgs doWorkEventArgs)
52
        {
53
            var DiffRegions = new List<devDept.Eyeshot.OrientedBoundingRect>();
54
55
            bool[] equalEntitiesInV2 = new bool[_AVEVAEntities.Count];
56
            var EqualIndices = new List<int>();
57
58
            /// 서로 검사 가능한 타입인지 확인한다.
59
            bool CheckType(Entity ent1, Entity ent2)
60
            {
61
                return ent1.GetType() == ent2.GetType() ||
62
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Text) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText)) ||
63
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
64
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Line) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.TabulatedSurface)) ||
65
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
66
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText));
67
            }
68
69
            try
70
            {
71 1620ca9c humkyung
                for (int i = 0; i < _AutoCADEntities.Count; i++)
72 54be6611 humkyung
                {
73
                    Entity entVp1 = _AutoCADEntities[i];
74
                    EqualIndices.Clear();
75
76 1620ca9c humkyung
                    for (int j = 0; j < _AVEVAEntities.Count; j++)
77 54be6611 humkyung
                    {
78
                        Entity entVp2 = _AVEVAEntities[j];
79
80
                        if (entVp2 is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE")) continue;
81
                        if (!equalEntitiesInV2[j] && CheckType(entVp1, entVp2) &&
82
                            CompareIfEqual(_workspace, entVp1, _workspace, entVp2))
83
                        {
84
                            EqualIndices.Add(j);
85
                        }
86
                    }
87
88
                    #region 임계값 안에 들어오는 항목이 여러개 있을 경우 가장 가까운 항목을 유사 항목으로 선택한다.
89
                    if (EqualIndices.Any())
90
                    {
91
                        var ordered = EqualIndices.ConvertAll(x => _AVEVAEntities[x]).OrderBy(x =>
92
                        {
93
                            return x.BoxMin.DistanceTo(entVp1.BoxMin);
94
                        });
95
96
                        int idx = _AVEVAEntities.ToList().FindIndex(x => x == ordered.First());
97
                        equalEntitiesInV2[idx] = true;
98
                    }
99
                    #endregion
100
101
                    if (!EqualIndices.Any())
102
                    {
103
                        _AutoCADEntities[i].LayerName = AutoCADDiffLayer;
104
                        ColorEntity(_workspace, _AutoCADEntities[i], DiffColor, colorMethodType.byEntity, false);
105
106
                        #region 틀린 엔터티의 BoundingBox를 구함
107
                        var origin = new devDept.Geometry.Point2D(entVp1.BoxMin.X - 1, entVp1.BoxMin.Y - 1);
108
                        double width = entVp1.BoxMax.X - entVp1.BoxMin.X;
109
                        double height = entVp1.BoxMax.Y - entVp1.BoxMin.Y;
110
                        if (Math.Abs(width) != double.PositiveInfinity && Math.Abs(height) != double.PositiveInfinity)
111
                        {
112
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
113
                            DiffRegions.Add(rect);
114
                        }
115
                        #endregion
116
                    }
117
118
                    UpdateProgress(i, _AutoCADEntities.Count, "Comparing....", worker);
119
                }
120
121
                for (int j = 0; j < _AVEVAEntities.Count; j++)
122
                {
123
                    if (!equalEntitiesInV2[j])
124
                    {
125
                        _AVEVAEntities[j].LayerName = AVEVADiffLayer;
126
                        ColorEntity(_workspace, _AVEVAEntities[j], DiffColor, colorMethodType.byEntity, false);
127
128
                        #region 틀린 엔터티의 BoundingBox를 구함 
129
                        var origin = new devDept.Geometry.Point2D(_AVEVAEntities[j].BoxMin.X - 1, _AVEVAEntities[j].BoxMin.Y - 1);
130
                        double width = _AVEVAEntities[j].BoxMax.X - _AVEVAEntities[j].BoxMin.X;
131
                        double height = _AVEVAEntities[j].BoxMax.Y - _AVEVAEntities[j].BoxMin.Y;
132
                        if (Math.Abs(width) != double.PositiveInfinity && Math.Abs(height) != double.PositiveInfinity)
133
                        {
134
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
135
                            DiffRegions.Add(rect);
136
                        }
137
                        #endregion
138
                    }
139
                }
140
141
                #region 인접한 영역을 하나로 합친다.
142
                var queue = new List<devDept.Eyeshot.OrientedBoundingRect>(DiffRegions);
143
                DiffRegions.Clear();
144
                while (queue.Any())
145
                {
146
                    var first = queue[0];
147
                    var FirstMin = first.GetOrigin();
148
                    var FirstMax = FirstMin + first.GetAxis()[0] * first.Size.X + first.GetAxis()[1] * first.Size.Y;
149
150
                    queue.Remove(first);
151
                    bool overlap = false;
152
                    for (int i = 0; i < queue.Count; ++i)
153
                    {
154
                        var second = queue[i];
155
                        overlap = devDept.Eyeshot.OrientedBoundingRect.DoOverlapOrTouch(first, second);
156
                        if (overlap)
157
                        {
158
                            var SecondMin = second.GetOrigin();
159
                            var SecondMax = SecondMin + second.GetAxis()[0] * second.Size.X + second.GetAxis()[1] * second.Size.Y;
160
161
                            var min = new devDept.Geometry.Point2D(Math.Min(FirstMin.X, SecondMin.X), Math.Min(FirstMin.Y, SecondMin.Y));
162
                            var max = new devDept.Geometry.Point2D(Math.Max(FirstMax.X, SecondMax.X), Math.Max(FirstMax.Y, SecondMax.Y));
163
                            double width = max.X - min.X;
164
                            double height = max.Y - min.Y;
165
166
                            #region 두 영역을 합친다.(작업 완료된 영역도 다시 queue에 넣는다.)
167
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(min, width, height);
168
                            queue.Add(rect);
169
                            queue.AddRange(DiffRegions);
170
                            DiffRegions.Clear();
171
                            queue.Remove(second);
172
                            #endregion
173
                            break;
174
                        }
175
                    }
176
177
                    if (!overlap) DiffRegions.Add(first);
178
                }
179
                #endregion
180
181
                _workspace.Invoke(new Action(() =>
182
                {
183
                    if (!_workspace.Layers.Contains(RevCloudLayer))
184
                        _workspace.Layers.Add(RevCloudLayer.ToUpper(), RevCloudColor);
185
                    DiffRegions.ForEach(x => DrawRevCloud(_workspace, x));
186
                }));
187
            }
188
            catch (Exception ex)
189
            {
190
                Console.Write($"Error : {ex.Message}");
191
            }
192
        }
193
194
        /// <summary>
195
        /// 주어진 두 엔터티를 비교한다.
196
        /// </summary>
197
        /// <param name="entVp1"></param>
198
        /// <param name="entVp2"></param>
199
        /// <returns></returns>
200
        private bool CompareIfEqual(Workspace design1, Entity entVp1, Workspace design2, Entity entVp2)
201
        {
202
            return AreEqual(design1, entVp1, design2, entVp2);
203
        }
204
205
        private bool CompareGEntityIfEqual(GEntity entVp1, GEntity entVp2)
206
        {
207
            return AreGEntityEqual(entVp1, entVp2);
208
        }
209
210
        private bool AreGEntityEqual(GEntity ent1, GEntity ent2)
211
        {
212
            if (ent1 is GCompositeCurve cc1 && ent2 is GCompositeCurve cc2)
213
            {
214
                if (cc1.CurveList.Count == cc2.CurveList.Count)
215
                {
216
                    int equalCurvesInListCount = 0;
217
                    foreach (var entC in cc1.CurveList)
218
                    {
219
                        foreach (var entC2 in cc2.CurveList)
220
                        {
221
                            if (entC.GetType() == entC2.GetType())
222
                            {
223
                                if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
224
                                {
225
                                    equalCurvesInListCount++;
226
                                    break;
227
                                }
228
                            }
229
                        }
230
                    }
231
232
                    if (cc1.CurveList.Count == equalCurvesInListCount)
233
                    {
234
                        return true;
235
                    }
236
                }
237
            }
238
            else if (ent1 is GLinearPath lp1 && ent2 is GLinearPath lp2)
239
            {
240
                if (lp1.Vertices.Length == lp2.Vertices.Length)
241
                {
242
                    for (int i = 0; i < lp1.Vertices.Length; i++)
243
                    {
244
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Tolerance)
245
                            return false;
246
                    }
247
                    return true;
248
                }
249
            }
250
251
            else if (ent1 is GPlanarEntity pe1 && ent2 is GPlanarEntity pe2)
252
            {
253
                if (
254
                    pe1.Plane.AxisZ == pe2.Plane.AxisZ &&
255
                    pe1.Plane.AxisX == pe2.Plane.AxisX
256
                    )
257
                {
258
                    if (ent1 is GArc arc1 && ent2 is GArc arc2)
259
                    {
260
                        if (
261
                            arc1.Center.DistanceTo(arc2.Center) <= Tolerance &&
262
                            Math.Abs(arc1.Radius - arc2.Radius) <= Tolerance &&
263
                            Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Tolerance &&
264
                            Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Tolerance
265
                            )
266
                        {
267
                            return true;
268
                        }
269
                    }
270
                    else if (ent1 is GCircle c1 && ent2 is GCircle c2)
271
                    {
272
                        if (c1.Center.DistanceTo(c2.Center) <= Tolerance &&
273
                            Math.Abs(c1.Radius - c2.Radius) <= Tolerance)
274
                        {
275
                            return true;
276
                        }
277
                    }
278
                    else if (ent1 is GEllipticalArc e1 && ent2 is GEllipticalArc e2)
279
                    {
280
                        if (
281
                            e1.Center.DistanceTo(e2.Center) <= Tolerance &&
282
                            Math.Abs(e1.RadiusX - e2.RadiusX) <= Tolerance &&
283
                            Math.Abs(e1.RadiusY - e2.RadiusY) <= Tolerance &&
284
                            Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Tolerance &&
285
                            Math.Abs(e1.Domain.High - e2.Domain.High) <= Tolerance
286
                        )
287
                        {
288
                            return true;
289
                        }
290
                    }
291
                    else if (ent1 is GEllipse el1 && ent2 is GEllipse el2)
292
                    {
293
                        if (
294
                            el1.Center.DistanceTo(el2.Center) <= Tolerance &&
295
                            Math.Abs(el1.RadiusX - el2.RadiusX) <= Tolerance &&
296
                            Math.Abs(el1.RadiusY - el2.RadiusY) <= Tolerance
297
                        )
298
                        {
299
                            return true;
300
                        }
301
                    }
302
                    else
303
                    {
304
                        Console.Write("Type " + ent1.GetType() + " not implemented.");
305
                        return true;
306
                    }
307
                }
308
            }
309
310
            else if (ent1 is GLine line1 && ent2 is GLine line2)
311
            {
312
                if (line1.StartPoint.DistanceTo(line2.StartPoint) <= Tolerance &&
313
                    line1.EndPoint.DistanceTo(line2.EndPoint) <= Tolerance
314
                )
315
                {
316
                    return true;
317
                }
318
            }
319
#if NURBS
320
            else if (ent1 is Curve)
321
            {
322
                Curve cu1 = (Curve)ent1;
323
                Curve cu2 = (Curve)ent2;
324
325
                if (
326
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
327
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
328
                    cu1.Degree == cu2.Degree
329
                    )
330
                {
331
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
332
                    {
333
                        if (cu1.ControlPoints[k] != cu2.ControlPoints[k])
334
                        {
335
                            return false;
336
                        }
337
                    }
338
339
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
340
                    {
341
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
342
                        {
343
                            return false;
344
                        }
345
                    }
346
347
                    return true;
348
                }
349
            }
350
#endif
351
352
            else
353
            {
354
                Console.Write("Type " + ent1.GetType() + " not implemented.");
355
                return true;
356
            }
357
            return false;
358
        }
359
360
        /// <summary>
361
        /// 그래픽적으로 두 엔터티가 유사한지 검사한다.
362
        /// </summary>
363
        /// <param name="design1"></param>
364
        /// <param name="ent1"></param>
365
        /// <param name="design2"></param>
366
        /// <param name="ent2"></param>
367
        /// <returns></returns>
368
        private bool AreEqual(Workspace design1, Entity ent1, Workspace design2, Entity ent2)
369
        {
370
            if (ent1 is CompositeCurve cc1 && ent2 is CompositeCurve cc2)
371
            {
372
                if (cc1.CurveList.Count == cc2.CurveList.Count)
373
                {
374
                    int equalCurvesInListCount = 0;
375
                    foreach (var entC in cc1.CurveList)
376
                    {
377
                        foreach (var entC2 in cc2.CurveList)
378
                        {
379
                            if (entC.GetType() == entC2.GetType())
380
                            {
381
                                if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
382
                                {
383
                                    equalCurvesInListCount++;
384
                                    break;
385
                                }
386
                                else if (entC is GEntity && entC2 is GEntity && CompareGEntityIfEqual(entC as GEntity, entC2 as GEntity))
387
                                {
388
                                    equalCurvesInListCount++;
389
                                    break;
390
                                }
391
                            }
392
                        }
393
                    }
394
395
                    if (cc1.CurveList.Count == equalCurvesInListCount)
396
                    {
397
                        return true;
398
                    }
399
                }
400
            }
401
            else if (ent1 is LinearPath lp1 && ent2 is LinearPath lp2)
402
            {
403
                if (lp1.Vertices.Length == lp2.Vertices.Length)
404
                {
405
                    for (int i = 0; i < lp1.Vertices.Length; i++)
406
                    {
407
                        if (lp1.Vertices[i].DistanceTo(lp2.Vertices[i]) > Tolerance)
408
                            return false;
409
                    }
410
411
                    return true;
412
                }
413
            }
414
            else if (ent1 is PlanarEntity && ent2 is PlanarEntity)
415
            {
416
                if (ent1 is Arc arc1 && ent2 is Arc arc2)
417
                {
418
                    if (
419
                        arc1.Center.DistanceTo(arc2.Center) <= Tolerance &&
420
                        Math.Abs(arc1.Radius - arc2.Radius) <= Tolerance &&
421
                        Math.Abs(arc1.Domain.Min - arc2.Domain.Min) <= Tolerance &&
422
                        Math.Abs(arc1.Domain.Max - arc2.Domain.Max) <= Tolerance
423
                        )
424
                    {
425
                        return true;
426
                    }
427
                }
428
                else if (ent1 is Circle c1 && ent2 is Circle c2)
429
                {
430
                    if (
431
                        c1.Center.DistanceTo(c2.Center) <= Tolerance &&
432
                        Math.Abs(c1.Radius - c2.Radius) <= Tolerance
433
                        )
434
                    {
435
                        return true;
436
                    }
437
                }
438
                else if (ent1 is EllipticalArc e1 && ent2 is EllipticalArc e2)
439
                {
440
                    if (
441
                        e1.Center.DistanceTo(e2.Center) <= Tolerance &&
442
                        Math.Abs(e1.RadiusX - e2.RadiusX) <= Tolerance &&
443
                        Math.Abs(e1.RadiusY - e2.RadiusY) <= Tolerance &&
444
                        Math.Abs(e1.Domain.Low - e2.Domain.Low) <= Tolerance &&
445
                        Math.Abs(e1.Domain.High - e2.Domain.High) <= Tolerance
446
                    )
447
                    {
448
                        return true;
449
                    }
450
                }
451
                else if (ent1 is Ellipse el1 && ent2 is Ellipse el2)
452
                {
453
                    if (
454
                        el1.Center.DistanceTo(el2.Center) <= Tolerance &&
455
                        Math.Abs(el1.RadiusX - el2.RadiusX) <= Tolerance &&
456
                        Math.Abs(el1.RadiusY - el2.RadiusY) <= Tolerance
457
                    )
458
                    {
459
                        return true;
460
                    }
461
                }
462
                #region 해치는 중점만 비교
463
                else if (ent1 is Hatch hatch1 && ent2 is Hatch hatch2)
464
                {
465
                    var center1 = (hatch1.BoxMin + hatch1.BoxMax) * 0.5;
466
                    center1.Z = 0;
467
                    var center2 = (hatch2.BoxMin + hatch2.BoxMax) * 0.5;
468
                    center2.Z = 0;
469
                    return center1.DistanceTo(center2) < Tolerance;
470
                }
471
                #endregion
472
                else if (ent1 is Text)
473
                {
474
                    if (ent1 is Dimension dim1 && ent2 is Dimension dim2)
475
                    {
476
                        if (
477
                            dim1.InsertionPoint.DistanceTo(dim2.InsertionPoint) <= Tolerance &&
478
                            dim1.DimLinePosition.DistanceTo(dim2.DimLinePosition) <= Tolerance
479
                            )
480
                        {
481
                            if (ent1 is AngularDim ad1 && ent2 is AngularDim ad2)
482
                            {
483
                                if (
484
                                    ad1.ExtLine1.DistanceTo(ad2.ExtLine1) <= Tolerance &&
485
                                    ad1.ExtLine2.DistanceTo(ad2.ExtLine2) <= Tolerance &&
486
                                    Math.Abs(ad1.StartAngle - ad2.StartAngle) <= Tolerance &&
487
                                    Math.Abs(ad1.EndAngle - ad2.EndAngle) <= Tolerance &&
488
                                    Math.Abs(ad1.Radius - ad2.Radius) <= Tolerance
489
                                    )
490
                                {
491
                                    return true;
492
                                }
493
                            }
494
                            else if (ent1 is LinearDim ld1 && ent2 is LinearDim ld2)
495
                            {
496
                                if (
497
                                    ld1.ExtLine1.DistanceTo(ld2.ExtLine1) <= Tolerance &&
498
                                    ld1.ExtLine2.DistanceTo(ld2.ExtLine2) <= Tolerance
499
                                    )
500
                                {
501
                                    return true;
502
                                }
503
                            }
504
                            else if (ent1 is DiametricDim dd1 && ent2 is DiametricDim dd2)
505
                            {
506
                                if (
507
                                    Math.Abs(dd1.Distance - dd2.Distance) <= Tolerance &&
508
                                    Math.Abs(dd1.Radius - dd2.Radius) <= Tolerance &&
509
                                    Math.Abs(dd1.CenterMarkSize - dd2.CenterMarkSize) <= Tolerance
510
                                )
511
                                {
512
                                    return true;
513
                                }
514
                            }
515
                            else if (ent1 is RadialDim rd1 && ent2 is RadialDim rd2)
516
                            {
517
                                if (
518
                                    Math.Abs(rd1.Radius - rd2.Radius) <= Tolerance &&
519
                                    Math.Abs(rd1.CenterMarkSize - rd2.CenterMarkSize) <= Tolerance
520
                                )
521
                                {
522
                                    return true;
523
                                }
524
                            }
525
                            else if (ent1 is OrdinateDim od1 && ent2 is OrdinateDim od2)
526
                            {
527
                                if (
528
                                    od1.DefiningPoint.DistanceTo(od2.DefiningPoint) <= Tolerance &&
529
                                    od1.Origin.DistanceTo(od2.Origin) <= Tolerance &&
530
                                    od1.LeaderEndPoint.DistanceTo(od2.LeaderEndPoint) <= Tolerance
531
                                )
532
                                {
533
                                    return true;
534
                                }
535
                            }
536
                            else
537
                            {
538
                                Console.Write("Type " + ent1.GetType() + " not implemented.");
539
                                return true;
540
                            }
541
                        }
542
                    }
543
544
                    else if (ent1 is devDept.Eyeshot.Entities.Attribute att1 && ent2 is devDept.Eyeshot.Entities.Attribute att2)
545
                    {
546
                        if (
547
                            att1.Value == att2.Value &&
548
                            att1.InsertionPoint.DistanceTo(att2.InsertionPoint) <= Tolerance
549
                            )
550
                        {
551
                            return true;
552
                        }
553
                    }
554
                    else
555
                    {
556 1620ca9c humkyung
                        Text tx1 = (Text)ent1;  /// AutoCAD Text
557
                        Text tx2 = (Text)ent2;  /// AVEVA Text
558 54be6611 humkyung
559
                        #region 공백을 무시하여 비교
560
                        string string1 = tx1.TextString.Trim();
561
                        string string2 = tx2.TextString.Trim();
562
                        string1 = System.Text.RegularExpressions.Regex.Replace(string1, @"\s+", "");
563
                        string2 = System.Text.RegularExpressions.Regex.Replace(string2, @"\s+", "");
564 353b7f9f humkyung
                        #endregion
565
                        #region 특수문자 처리
566
                        SpecialCharacters.ForAll(x => { string1 = string1.Replace(x.Special, x.Normal); });
567
                        SpecialCharacters.ForAll(x => { string2 = string2.Replace(x.Special, x.Normal); });
568
                        #endregion
569
                        if(!Casesensitive)
570
                        {
571
                            string1 = string1.ToUpper();
572
                            string2 = string2.ToUpper();
573
                        }
574
575 54be6611 humkyung
                        if (
576
                            tx1.BoxMin.DistanceTo(tx2.BoxMin) <= Tolerance &&
577
                            string1 == string2 &&
578
                            Math.Abs(tx1.WidthFactor - tx2.WidthFactor) <= Tolerance &&
579
                            Math.Abs(tx1.Height - tx2.Height) <= Tolerance
580
                            )
581
                        {
582
                            return true;
583
                        }
584
                    }
585
                }
586
            }
587
            else if (ent1 is Line line1 && ent2 is Line line2)
588
            {
589
                var dir1 = line1.Direction;
590
                dir1.Normalize();
591
                var dir2 = line2.Direction;
592
                dir2.Normalize();
593
                if (devDept.Geometry.Vector3D.AreParallel(dir1, dir2, 0.1) &&
594
                    Math.Abs(line1.Length() - line2.Length()) <= line1.Length() * LengthToleranceRatio &&
595
                    line1.MidPoint.DistanceTo(line2.MidPoint) <= Tolerance
596
                )
597
                {
598
                    return true;
599
                }
600
            }
601
            else if (ent1 is Line && ent2 is devDept.Eyeshot.Entities.TabulatedSurface lwpolyline && lwpolyline.ControlPoints.Length == 4)
602
            {
603
                line1 = ent1 as Line;
604
                var start = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[0, 0].X, lwpolyline.ControlPoints[0, 0].Y, 0);
605
                var end = new devDept.Geometry.Point3D(lwpolyline.ControlPoints[1, 0].X, lwpolyline.ControlPoints[1, 0].Y, 0);
606
                var vec = new devDept.Geometry.Vector3D(start, end);
607
                vec.Normalize();
608
                var dir = line1.Direction.Clone() as devDept.Geometry.Vector3D;
609
                dir.Normalize();
610
611
                if (
612
                    devDept.Geometry.Vector3D.AreParallel(dir, vec) &&
613
                    line1.StartPoint.DistanceTo(start) <= Tolerance &&
614
                    line1.EndPoint.DistanceTo(end) <= Tolerance
615
                )
616
                {
617
                    return true;
618
                }
619
            }
620
            else if (ent1 is devDept.Eyeshot.Entities.Point point1 && ent2 is devDept.Eyeshot.Entities.Point point2)
621
            {
622
                if (point1.Position.DistanceTo(point2.Position) <= Tolerance)
623
                {
624
                    return true;
625
                }
626
            }
627
            else if (ent1 is Curve cu1 && ent2 is Curve cu2)
628
            {
629
                if (
630
                    cu1.ControlPoints.Length == cu2.ControlPoints.Length &&
631
                    cu1.KnotVector.Length == cu2.KnotVector.Length &&
632
                    cu1.Degree == cu2.Degree
633
                    )
634
                {
635
                    for (int k = 0; k < cu1.ControlPoints.Length; k++)
636
                    {
637
                        if (cu1.ControlPoints[k].DistanceTo(cu2.ControlPoints[k]) > Tolerance)
638
                        {
639
                            return false;
640
                        }
641
                    }
642
643
                    for (int k = 0; k < cu1.KnotVector.Length; k++)
644
                    {
645
                        if (cu1.KnotVector[k] != cu2.KnotVector[k])
646
                        {
647
                            return false;
648
                        }
649
                    }
650
651
                    return true;
652
                }
653
            }
654
            else if (ent1 is Mesh m1 && ent2 is Mesh m2 && m1.Vertices.Count() == m2.Vertices.Count())
655
            {
656
                for (int i = 0; i < m1.Vertices.Count(); ++i)
657
                {
658
                    if (m1.Vertices[i].DistanceTo(m2.Vertices[i]) > Tolerance) return false;
659
                }
660
661
                return true;
662
            }
663
            else if (ent1 is BlockReference blkref1 && ent2 is BlockReference blkref2)
664
            {
665
                int equalCurvesInEntityList = 0;
666
667
                #region Point, Attribute, Text 제거 및 LinePath를 라인으로 분리
668
                var entities1 = blkref1.Explode(design1.Blocks).Where(x => x.LayerName != "AS_PORT" && !(x is devDept.Eyeshot.Entities.Point) &&
669
                !(x is devDept.Eyeshot.Entities.Attribute) && !(x is devDept.Eyeshot.Entities.Text)).ToList();
670
                var coll1 = new List<Entity>();
671
                entities1.ForEach(x =>
672
                {
673
                    if (x is LinearPath lp)
674
                    {
675
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
676
                        {
677
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
678
                            coll1.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
679
                        }
680
                    }
681
                    else
682
                    {
683
                        coll1.Add(x);
684
                    }
685
                });
686
                #endregion
687
688
                #region Point 및 Nesting Block 제거 및 LinePath를 라인으로 분리
689
                var entities2 = blkref2.Explode(design2.Blocks).Where(x =>
690
                !(x is devDept.Eyeshot.Entities.BlockReference blkref && blkref.BlockName == "PORT") && !(x is devDept.Eyeshot.Entities.Point)).ToList();
691
                var coll2 = new List<Entity>();
692
                entities2.ForEach(x =>
693
                {
694
                    if (x is LinearPath lp)
695
                    {
696
                        for (int i = 0; i < lp.Vertices.Length - 1; ++i)
697
                        {
698
                            if (lp.Vertices[i].DistanceTo(lp.Vertices[i + 1]) < 0.1) continue;
699
                            coll2.Add(new Line(lp.Vertices[i], lp.Vertices[i + 1]));
700
                        }
701
                    }
702
                    else if (x is devDept.Eyeshot.Entities.Attribute attr)
703
                    {
704
                        if (!attr.Invisible) coll2.Add(attr);
705
                    }
706
                    else if (x.GetType().Name == "AttributeReferenceData")
707
                    {
708
                    }
709
                    else
710
                    {
711
                        coll2.Add(x);
712
                    }
713
                });
714
                #endregion
715
716
                if (coll1.Count != coll2.Count) return false;
717
718
                foreach (var entC in coll1)
719
                {
720
                    foreach (var entC2 in coll2)
721
                    {
722
                        if (entC.GetType() == entC2.GetType())
723
                        {
724
                            if (entC is Entity && entC2 is Entity && CompareIfEqual(design1, entC as Entity, design2, entC2 as Entity))
725
                            {
726
                                equalCurvesInEntityList++;
727
                                break;
728
                            }
729
                        }
730
                    }
731
                }
732
733
                if (coll1.Count == equalCurvesInEntityList)
734
                {
735
                    return true;
736
                }
737
            }
738
            else
739
            {
740
                Console.Write("Type " + ent1.GetType() + " not implemented.");
741
                return false;
742
            }
743
744
            return false;
745
        }
746
747
        /// <summary>
748
        /// 엔터티들의 색상을 바꾼다.
749
        /// </summary>
750
        /// <param name="design"></param>
751
        /// <param name="list"></param>
752
        public void ColorEntities(Workspace design , IList<Entity> list, Color color, colorMethodType colorMethod = colorMethodType.byEntity, bool ChangeBlkColor = true)
753
        {
754
            foreach (Entity ent in list)
755
            {
756
                ColorEntity(design, ent, color, colorMethod, ChangeBlkColor);
757
            }
758
        }
759
760
        /// <summary>
761
        /// 엔터티의 색상을 변경한다.
762
        /// </summary>
763
        /// <param name="design"></param>
764
        /// <param name="entity"></param>
765
        /// <param name="color"></param>
766
        private void ColorEntity(Workspace design , Entity entity, Color color, colorMethodType colorMethod = colorMethodType.byEntity,
767
            bool ChangeBlkColor = true)
768
        {
769
            if (entity is BlockReference blkref)
770
            {
771
                _workspace.Invoke(new Action(() =>
772
                {
773
                    blkref.Color = color;
774
                    blkref.ColorMethod = colorMethod;
775
                }));
776
777
                if (ChangeBlkColor)
778
                {
779
                    var blk = design.Blocks.FirstOrDefault(x => x.Name == blkref.BlockName);
780
                    if (blk != null)
781
                    {
782
                        ColorEntities(design, blk.Entities, color, colorMethodType.byParent);
783
                        _workspace.Invoke(new Action(() =>
784
                        {
785
                            foreach (var attr in blkref.Attributes.Values)
786
                            {
787
                                attr.Color = color;
788
                                attr.ColorMethod = colorMethodType.byParent;
789
                            }
790
                        }));
791
                    }
792
                }
793
            }
794
            else
795
            {
796
                _workspace.Invoke(new Action(() =>
797
                {
798
                    entity.Color = color;
799
                    entity.ColorMethod = colorMethod;
800
                }));
801
            }
802
        }
803
804
        /// <summary>
805
        /// 주어진 두 엔터티 리스트를 비교하여 틀린 엔터티의 색상을 설정한 색상으로 변경한다.
806
        /// </summary>
807
        /// <param name="entList1"></param>
808
        /// <param name="entList2"></param>
809
        private void CompareAndMark(Design design1, IList<Entity> AutoCADEntities, Design design2, IList<Entity> AVEVAEntities)
810
        {
811
            var DiffRegions = new List<devDept.Eyeshot.OrientedBoundingRect>();
812
813
            bool[] equalEntitiesInV2 = new bool[AVEVAEntities.Count];
814
            var EqualIndices = new List<int>();
815
816
            /// 서로 검사 가능한 타입인지 확인한다.
817
            bool CheckType(Entity ent1, Entity ent2)
818
            {
819
                return ent1.GetType() == ent2.GetType() ||
820
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Text) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText)) ||
821
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
822
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Line) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.TabulatedSurface)) ||
823
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.Text)) ||
824
                    (ent1.GetType() == typeof(devDept.Eyeshot.Entities.Attribute) && ent2.GetType() == typeof(devDept.Eyeshot.Entities.MultilineText));
825
            }
826
827
            try
828
            {
829
                for (int i = 0; i < AutoCADEntities.Count(); i++)
830
                {
831
                    Entity entVp1 = AutoCADEntities[i];
832
                    EqualIndices.Clear();
833
834
                    for (int j = 0; j < AVEVAEntities.Count(); j++)
835
                    {
836
                        Entity entVp2 = AVEVAEntities[j];
837
838
                        if (entVp2 is BlockReference blkref && (blkref.BlockName == "PSNODE" || blkref.BlockName == "PENODE")) continue;
839
                        if (!equalEntitiesInV2[j] && CheckType(entVp1, entVp2) &&
840
                            CompareIfEqual(design1, entVp1, design2, entVp2))
841
                        {
842
                            EqualIndices.Add(j);
843
                        }
844
                    }
845
846
                    #region 임계값 안에 들어오는 항목이 여러개 있을 경우 가장 가까운 항목을 유사 항목으로 선택한다.
847
                    if (EqualIndices.Any())
848
                    {
849
                        var ordered = EqualIndices.ConvertAll(x => AVEVAEntities[x]).OrderBy(x =>
850
                        {
851
                            return x.BoxMin.DistanceTo(entVp1.BoxMin);
852
                        });
853
854
                        int idx = AVEVAEntities.ToList().FindIndex(x => x == ordered.First());
855
                        equalEntitiesInV2[idx] = true;
856
                    }
857
                    #endregion
858
859
                    if (!EqualIndices.Any())
860
                    {
861
                        AutoCADEntities[i].LayerName = AutoCADDiffLayer;
862
                        ColorEntity(design1, AutoCADEntities[i], DiffColor, colorMethodType.byEntity, false);
863
864
                        #region 틀린 엔터티의 BoundingBox를 구함
865
                        var origin = new devDept.Geometry.Point2D(entVp1.BoxMin.X - 1, entVp1.BoxMin.Y - 1);
866
                        double width = entVp1.BoxMax.X - entVp1.BoxMin.X;
867
                        double height = entVp1.BoxMax.Y - entVp1.BoxMin.Y;
868
                        if (Math.Abs(width) != double.PositiveInfinity && Math.Abs(height) != double.PositiveInfinity)
869
                        {
870
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
871
                            DiffRegions.Add(rect);
872
                        }
873
                        #endregion
874
                    }
875
                }
876
877
                for (int j = 0; j < AVEVAEntities.Count; j++)
878
                {
879
                    if (!equalEntitiesInV2[j])
880
                    {
881
                        AVEVAEntities[j].LayerName = AVEVADiffLayer;
882
                        ColorEntity(design2, AVEVAEntities[j], DiffColor, colorMethodType.byEntity, false);
883
884
                        #region 틀린 엔터티의 BoundingBox를 구함 
885
                        var origin = new devDept.Geometry.Point2D(AVEVAEntities[j].BoxMin.X - 1, AVEVAEntities[j].BoxMin.Y - 1);
886
                        double width = AVEVAEntities[j].BoxMax.X - AVEVAEntities[j].BoxMin.X;
887
                        double height = AVEVAEntities[j].BoxMax.Y - AVEVAEntities[j].BoxMin.Y;
888
                        if (Math.Abs(width) != double.PositiveInfinity && Math.Abs(height) != double.PositiveInfinity)
889
                        {
890
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(origin, width + 2, height + 2);
891
                            DiffRegions.Add(rect);
892
                        }
893
                        #endregion
894
                    }
895
                }
896
897
                #region 인접한 영역을 하나로 합친다.
898
                var queue = new List<devDept.Eyeshot.OrientedBoundingRect>(DiffRegions);
899
                DiffRegions.Clear();
900
                while (queue.Any())
901
                {
902
                    var first = queue[0];
903
                    var FirstMin = first.GetOrigin();
904
                    var FirstMax = FirstMin + first.GetAxis()[0] * first.Size.X + first.GetAxis()[1] * first.Size.Y;
905
906
                    queue.Remove(first);
907
                    bool overlap = false;
908
                    for (int i = 0; i < queue.Count; ++i)
909
                    {
910
                        var second = queue[i];
911
                        overlap = devDept.Eyeshot.OrientedBoundingRect.DoOverlapOrTouch(first, second);
912
                        if (overlap)
913
                        {
914
                            var SecondMin = second.GetOrigin();
915
                            var SecondMax = SecondMin + second.GetAxis()[0] * second.Size.X + second.GetAxis()[1] * second.Size.Y;
916
917
                            var min = new devDept.Geometry.Point2D(Math.Min(FirstMin.X, SecondMin.X), Math.Min(FirstMin.Y, SecondMin.Y));
918
                            var max = new devDept.Geometry.Point2D(Math.Max(FirstMax.X, SecondMax.X), Math.Max(FirstMax.Y, SecondMax.Y));
919
                            double width = max.X - min.X;
920
                            double height = max.Y - min.Y;
921
922
                            #region 두 영역을 합친다.(작업 완료된 영역도 다시 queue에 넣는다.)
923
                            var rect = new devDept.Eyeshot.OrientedBoundingRect(min, width, height);
924
                            queue.Add(rect);
925
                            queue.AddRange(DiffRegions);
926
                            DiffRegions.Clear();
927
                            queue.Remove(second);
928
                            #endregion
929
                            break;
930
                        }
931
                    }
932
933
                    if (!overlap) DiffRegions.Add(first);
934
                }
935
                #endregion
936
937
                if (!design2.Layers.Contains(RevCloudLayer))
938
                    design2.Layers.Add(RevCloudLayer.ToUpper(), RevCloudColor);
939
                DiffRegions.ForEach(x => DrawRevCloud(design2, x));
940
            }
941
            catch (Exception ex)
942
            {
943
                Console.Write($"Error : {ex.Message}");
944
            }
945
        }
946
947
        /// <summary>
948
        /// Revision mark를 그린다.
949
        /// </summary>
950
        /// <param name="design"></param>
951
        /// <param name="obr"></param>
952
        private void DrawRevCloud(Workspace design , devDept.Eyeshot.OrientedBoundingRect obr)
953
        {
954
            IList<IGCurve> DrawRevCloudLine(devDept.Geometry.Point2D start, devDept.Geometry.Point2D end)
955
            {
956
                var res = new List<IGCurve>();
957
958
                var AxisX = new devDept.Geometry.Vector3D(end.X - start.X, end.Y - start.Y);
959
                AxisX.Normalize();
960
                var AxisY = devDept.Geometry.Vector3D.Cross(devDept.Geometry.Vector3D.AxisZ, AxisX);
961
962
                double step = 10;
963
                double dist = start.DistanceTo(end);
964
                int count = Convert.ToInt32(dist / step);
965
                if (count == 0 && dist > 0)
966
                {
967
                    var tmp = (start + end) * 0.5;
968
969
                    var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
970
                    var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
971
                    GArc arc = new GArc(plane, center, start.DistanceTo(end) * 0.5, Math.PI, Math.PI * 2);
972
                    res.Add(arc);
973
                }
974
                else
975
                {
976
                    for (int i = 0; i < count; ++i)
977
                    {
978
                        var _start = (start + AxisX * i * step);
979
                        var _end = (start + AxisX * (i + 1) * step);
980
                        if (i == count - 1) _end = end;
981
                        var tmp = (_start + _end) * 0.5;
982
983
                        var center = new devDept.Geometry.Point3D(tmp.X, tmp.Y, 0);
984
                        var plane = new devDept.Geometry.Plane(center, AxisX, AxisY);
985
                        GArc arc = new GArc(plane, center, _start.DistanceTo(_end) * 0.5, Math.PI, Math.PI * 2);
986
                        res.Add(arc);
987
                    }
988
                }
989
990
                return res;
991
            }
992
993
            GCompositeCurve profile = new GCompositeCurve();
994
995
            var vertices = obr.GetVertices();
996
            for (int i = 0; i < vertices.Length; ++i)
997
            {
998
                var curves = DrawRevCloudLine(vertices[i], vertices[(i + 1) % vertices.Length]);
999
                profile.CurveList.AddRange(curves);
1000
            }
1001
1002
            var revcloud = new devDept.Eyeshot.Entities.CompositeCurve(profile);
1003
            revcloud.LayerName = RevCloudLayer;
1004
            revcloud.Color = RevCloudColor;
1005
            revcloud.ColorMethod = colorMethodType.byEntity;
1006
            revcloud.LineWeight = 3;
1007
            revcloud.LineWeightMethod = colorMethodType.byEntity;
1008
            design.Entities.Add(revcloud);
1009
        }
1010
1011
        /// <summary>
1012
        /// 작업 완료
1013
        /// </summary>
1014
        /// <param name="sender"></param>
1015
        public override void WorkCompleted(object sender)
1016
        {
1017
            var mymodel = (sender as Workspace);
1018
1019
            try
1020
            {
1021
            }
1022
            catch (Exception ex)
1023
            {
1024
            }
1025
            finally
1026
            {
1027
                mymodel.ZoomFit();
1028
                mymodel.Invalidate();
1029
            }
1030
1031
            base.WorkCompleted(sender);
1032
        }
1033
1034
        public override void WorkFailed(object sender)
1035
        {
1036
            RadMessageBox.Show("Failed");
1037
            base.WorkFailed(sender);
1038
        }
1039
    }
1040
}
클립보드 이미지 추가 (최대 크기: 500 MB)