프로젝트

일반

사용자정보

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

hytos / ID2.Manager / ID2.Manager.Compare / Classes / CompareModelWorkUnit.cs @ dfb9a03c

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