프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / SPPIDConverter / AutoModeling.cs @ c01ce90b

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

1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
6
using Llama;
7
using Plaice;
8
using Ingr.RAD2D.Interop.RAD2D;
9
using Ingr.RAD2D.Internal;
10
using Ingr.RAD2D.Helper;
11
using Converter.BaseModel;
12
using Converter.SPPID.Model;
13
using Converter.SPPID.Properties;
14
using Converter.SPPID.Util;
15
using Converter.SPPID.DB;
16
using Ingr.RAD2D.MacroControls.CmdCtrl;
17
using Ingr.RAD2D;
18
using System.Windows;
19
using System.Threading;
20
using System.Drawing;
21
using Microsoft.VisualBasic;
22
using Newtonsoft.Json;
23

    
24
using DevExpress.XtraSplashScreen;
25
namespace Converter.SPPID
26
{
27
    public class AutoModeling
28
    {
29
        Placement _placement;
30
        LMADataSource dataSource;
31
        dynamic newDrawing;
32
        dynamic application;
33
        Ingr.RAD2D.Application radApp;
34
        SPPID_Document document;
35
        ETCSetting _ETCSetting;
36

    
37
        public string DocumentLabelText { get; set; }
38

    
39
        int CurrentCount;
40
        List <Tuple<string, Line, Line>> BranchLines = new List<Tuple<string, Line, Line>>();
41

    
42
        public AutoModeling(SPPID_Document document, dynamic application, Ingr.RAD2D.Application radApp)
43
        {
44
            this.document = document;
45
            this.application = application;
46
            this.radApp = radApp;
47
            this._ETCSetting = ETCSetting.GetInstance();
48
        }
49

    
50
        private int ClacProgressCount()
51
        {
52
            int EquipCount = 0;
53
            int SymbolCount = 0;
54
            int LineCount = 0;
55
            int NoteCount = 0;
56
            int TextCount = 0;
57
            int EndBreakCount = 0;
58
            int LineNumberCount = 0;
59

    
60
            EquipCount = document.Equipments.Count;
61
            SymbolCount = document.SYMBOLS.Count;
62
            SymbolCount = SymbolCount * 3;
63
            
64
            foreach (LineNumber lineNumber in document.LINENUMBERS)
65
                foreach (LineRun run in lineNumber.RUNS)
66
                    foreach (var item in run.RUNITEMS)
67
                        if (item.GetType() == typeof(Line))
68
                            LineCount++;
69
            foreach (TrimLine trimLine in document.TRIMLINES)
70
                foreach (LineRun run in trimLine.RUNS)
71
                    foreach (var item in run.RUNITEMS)
72
                        if (item.GetType() == typeof(Line))
73
                            LineCount++;
74

    
75
            LineCount = LineCount * 2;
76
            NoteCount = document.NOTES.Count;
77
            TextCount = document.TEXTINFOS.Count;
78
            EndBreakCount = document.EndBreaks.Count;
79
            LineNumberCount = document.LINENUMBERS.Count;
80
            LineNumberCount = LineNumberCount * 2;
81

    
82
            return EquipCount + SymbolCount + LineCount + NoteCount + TextCount + EndBreakCount;
83
        }
84

    
85
        /// <summary>
86
        /// 도면 단위당 실행되는 메서드
87
        /// </summary>
88
        public void Run()
89
        {
90
            try
91
            {
92
                _placement = new Placement();
93
                dataSource = _placement.PIDDataSource;
94

    
95
                CreateDocument();
96

    
97
                if (DocumentCoordinateCorrection())
98
                {
99
                    int AllCount = ClacProgressCount();
100

    
101
                    SplashScreenManager.ShowForm(typeof(SPPIDSplashScreen), true, true);
102
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetAllStep, AllCount);
103
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetDocumentName, DocumentLabelText);
104

    
105
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Group Symbol Modeling");
106
                    List<List<Symbol>> symbolGroups = SPPIDUtil.GetThreeConnectedSymbolGroup(document);
107
                    foreach (List<Symbol> symbolGroup in symbolGroups)
108
                        SymbolModelingByThreeSymbolGroup(symbolGroup);
109

    
110
                    // Equipment Modeling
111
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Equipments Modeling");
112
                    foreach (Equipment equipment in document.Equipments)
113
                        EquipmentModeling(equipment);
114

    
115
                    // LineRun Symbol Modeling
116
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Symbols Modeling");
117
                    foreach (LineNumber lineNumber in document.LINENUMBERS)
118
                        foreach (LineRun run in lineNumber.RUNS)
119
                            SymbolModelingByRun(run);
120
                    // TrimLineRun Symbol Modeling
121
                    foreach (TrimLine trimLine in document.TRIMLINES)
122
                        foreach (LineRun run in trimLine.RUNS)
123
                            SymbolModelingByRun(run);
124

    
125
                    // LineRun Line Modeling
126
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Lines Modeling");
127
                    foreach (LineNumber lineNumber in document.LINENUMBERS)
128
                        foreach (LineRun run in lineNumber.RUNS)
129
                            LineModelingByRun(run);
130
                    // TrimLineRun Line Modeling
131
                    foreach (TrimLine trimLine in document.TRIMLINES)
132
                        foreach (LineRun run in trimLine.RUNS)
133
                            LineModelingByRun(run);
134

    
135
                    // Branch Line Modeling
136
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Branch Lines Modeling");
137
                    foreach (var item in BranchLines)
138
                        BranchLineModeling(item);
139

    
140
                    // EndBreak Modeling
141
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "EndBreaks Modeling");
142
                    foreach (var item in document.EndBreaks)
143
                        EndBreakModeling(item);
144

    
145
                    // LineNumber Modeling
146
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "LineNumbers Modeling");
147
                    foreach (var item in document.LINENUMBERS)
148
                        LineNumberModeling(item);
149

    
150
                    // LineNumber Modeling
151
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Flow Mark Modeling");
152
                    foreach (var item in document.LINES)
153
                        FlowMarkModeling(item);
154

    
155
                    // Note Modeling
156
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Notes Modeling");
157
                    foreach (var item in document.NOTES)
158
                        NoteModeling(item);
159

    
160
                    // Text Modeling
161
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Texts Modeling");
162
                    foreach (var item in document.TEXTINFOS)
163
                        TextModeling(item);
164

    
165
                    // LineRun Line Join
166
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Join LineRuns");
167
                    foreach (LineNumber lineNumber in document.LINENUMBERS)
168
                        foreach (LineRun run in lineNumber.RUNS)
169
                            JoinRunLine(run);
170
                    // TrimLineRun Line Join
171
                    foreach (TrimLine trimLine in document.TRIMLINES)
172
                        foreach (LineRun run in trimLine.RUNS)
173
                            JoinRunLine(run);
174

    
175
                    // Input LineNumber Attribute
176
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Set Lines Attribute");
177
                    foreach (var item in document.LINENUMBERS)
178
                        InputLineNumberAttribute(item);
179

    
180
                    // Input Symbol Attribute
181
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Set Symbols Attribute");
182
                    foreach (var item in document.SYMBOLS)
183
                        InputSymbolAttribute(item, item.ATTRIBUTES);
184

    
185
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Labels Modeling");
186
                    foreach (var item in document.SYMBOLS)
187
                        LabelSymbolModeling(item);
188

    
189
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, AllCount);
190
                }
191
            }
192
            catch (Exception ex)
193
            {
194
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
195
            }
196
            finally
197
            {
198
                application.ActiveWindow.Fit();
199

    
200
                if (radApp.ActiveDocument != null)
201
                {
202
                    //radApp.ActiveDocument.Save();
203
                    //radApp.ActiveDocument.SaveOnClose = false;
204
                    //radApp.ActiveDocument.Close(false);
205

    
206
                    ReleaseCOMObjects(newDrawing);
207
                }
208

    
209
                ReleaseCOMObjects(dataSource);
210
                ReleaseCOMObjects(_placement);
211

    
212
                //SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.ClearParent, null);
213
                SplashScreenManager.CloseForm(false);
214
            }
215
        }
216

    
217
        /// <summary>
218
        /// 도면 생성 메서드
219
        /// </summary>
220
        private void CreateDocument()
221
        {
222
            string drawingName = document.DrawingName;
223
            string drawingNumber = document.DrawingNumber;
224

    
225
            GetDrawingNameAndNumber(ref drawingName, ref drawingNumber);
226

    
227
            newDrawing = application.Drawings.Add(document.Unit, document.Template, drawingNumber, drawingName);
228
            application.ActiveWindow.Fit();
229
            Thread.Sleep(1000);
230
            application.ActiveWindow.Zoom = 2000;
231
            Thread.Sleep(2000);
232

    
233
            
234
        }
235

    
236
        private void GetDrawingNameAndNumber(ref string drawingName, ref string drawingNumber)
237
        {
238
            LMDrawings drawings = new LMDrawings();
239
            drawings.Collect(dataSource);
240

    
241
            List<string> drawingNameList = new List<string>();
242
            List<string> drawingNumberList = new List<string>();
243

    
244
            foreach (LMDrawing item in drawings)
245
            {
246
                drawingNameList.Add(item.Attributes["Name"].get_Value().ToString());
247
                drawingNumberList.Add(item.Attributes["DrawingNumber"].get_Value().ToString());
248
            }
249

    
250
            int nameLength = drawingName.Length;
251
            while (drawingNameList.Contains(drawingName))
252
            {
253
                if (nameLength == drawingName.Length)
254
                    drawingName += "-1";
255
                else
256
                {
257
                    int index = Convert.ToInt32(drawingName.Remove(0, nameLength + 1));
258
                    drawingName = drawingName.Substring(0, nameLength + 1);
259
                    drawingName += ++index;
260
                }
261
            }
262

    
263
            int numberLength = drawingNumber.Length;
264
            while (drawingNameList.Contains(drawingNumber))
265
            {
266
                if (numberLength == drawingNumber.Length)
267
                    drawingNumber += "-1";
268
                else
269
                {
270
                    int index = Convert.ToInt32(drawingNumber.Remove(0, numberLength + 1));
271
                    drawingNumber = drawingNumber.Substring(0, numberLength + 1);
272
                    drawingNumber += ++index;
273
                }
274
            }
275

    
276
            ReleaseCOMObjects(drawings);
277
        }
278

    
279
        /// <summary>
280
        /// 도면 크기 구하는 메서드
281
        /// </summary>
282
        /// <returns></returns>
283
        private bool DocumentCoordinateCorrection()
284
        {
285
            double maxX = 0;
286
            double maxY = 0;
287
            foreach (object drawingObj in radApp.ActiveDocument.ActiveSheet.DrawingObjects)
288
            {
289
                Ingr.RAD2D.SmartFrame2d smartFrame2d = drawingObj as Ingr.RAD2D.SmartFrame2d;
290
                if (smartFrame2d != null)
291
                {
292
                    double x1 = 0;
293
                    double x2 = 0;
294
                    double y1 = 0;
295
                    double y2 = 0;
296
                    smartFrame2d.Range(out x1, out y1, out x2, out y2);
297
                    maxX = Math.Max(x2, maxX);
298
                    maxY = Math.Max(y2, maxY);
299
                }
300
            }
301
            if (maxX != 0 && maxY != 0)
302
            {
303
                document.SetSPPIDLocation(maxX, maxY);
304
                document.CoordinateCorrection();
305
                return true;
306
            }
307
            else
308
                return false;
309
        }
310

    
311
        /// <summary>
312
        /// 라인을 Run 단위로 모델링하는 진입 메서드
313
        /// </summary>
314
        /// <param name="run"></param>
315
        private void LineModelingByRun(LineRun run)
316
        {
317
            Line prevLine = null;
318
            List<Line> lines = new List<Line>();
319
            foreach (var item in run.RUNITEMS)
320
            {
321
                // Line일 경우
322
                if (item.GetType() == typeof(Line))
323
                {
324
                    Line line = item as Line;
325
                    if (prevLine == null)
326
                        lines.Add(line);
327
                    else if (prevLine != null)
328
                    {
329
                        if (prevLine.SPPID.MAPPINGNAME == line.SPPID.MAPPINGNAME)
330
                            lines.Add(line);
331
                        else
332
                        {
333
                            if (lines.Count > 0)
334
                            {
335
                                LineModeling(lines);
336
                                lines.Clear();
337
                            }
338
                            lines.Add(line);
339
                        }
340
                    }
341

    
342
                    prevLine = line;
343

    
344
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
345
                }
346
                // Symbol 일 경우
347
                else if (item.GetType() == typeof(Symbol))
348
                {
349
                    if (lines.Count > 0)
350
                    {
351
                        LineModeling(lines);
352
                        lines.Clear();
353
                    }
354
                }
355
            }
356

    
357
            if (lines.Count > 0)
358
                LineModeling(lines);
359
        }
360

    
361
        /// <summary>
362
        /// 심볼을 Run 단위로 모델링하는 진입 메서드
363
        /// </summary>
364
        /// <param name="run"></param>
365
        private void SymbolModelingByRun(LineRun run)
366
        {
367
            // 양끝 Symbol 검사 후 Line이 나올때까지만 Symbol Modeling
368
            if (run.RUNITEMS.Count > 0)
369
            {
370
                if (run.RUNITEMS[0].GetType() == typeof(Symbol))
371
                    SymbolModelingByRunStart(run.RUNITEMS[0] as Symbol, run);
372

    
373
                if (run.RUNITEMS[run.RUNITEMS.Count - 1].GetType() == typeof(Symbol))
374
                    SymbolModelingByRunEnd(run.RUNITEMS[run.RUNITEMS.Count - 1] as Symbol, run);
375
            }
376

    
377
            Symbol targetSymbol = null;
378
            foreach (var item in run.RUNITEMS)
379
            {
380
                if (item.GetType() == typeof(Symbol))
381
                {
382
                    Symbol symbol = item as Symbol;
383
                    SymbolModeling(symbol, targetSymbol);
384
                    targetSymbol = symbol;
385
                }
386
                else
387
                {
388
                    targetSymbol = null;
389
                }
390
            }
391
        }
392

    
393
        /// <summary>
394
        /// Run에 있는 심볼을 모델링하는데 기준이 Run의 시작점
395
        /// </summary>
396
        /// <param name="symbol"></param>
397
        /// <param name="run"></param>
398
        private void SymbolModelingByRunStart(Symbol symbol, LineRun run)
399
        {
400
            foreach (var connector in symbol.CONNECTORS)
401
            {
402
                object targetItem = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM);
403
                if (targetItem != null &&
404
                    (targetItem.GetType() == typeof(Symbol) || targetItem.GetType() == typeof(Equipment)) &&
405
                    !IsSameLineRun(symbol, targetItem))
406
                {
407
                    SymbolModeling(symbol, targetItem as Symbol);
408
                    for (int i = 1; i < run.RUNITEMS.Count; i++)
409
                    {
410
                        object item = run.RUNITEMS[i];
411
                        if (item.GetType() == typeof(Symbol))
412
                            SymbolModeling(item as Symbol, run.RUNITEMS[i - 1] as Symbol);
413
                        else
414
                            break;
415
                    }
416
                    break;
417
                }
418
            }
419

    
420

    
421
        }
422

    
423
        /// <summary>
424
        /// Run에 있는 심볼을 모델링하는데 기준이 Run의 끝점
425
        /// </summary>
426
        /// <param name="symbol"></param>
427
        /// <param name="run"></param>
428
        private void SymbolModelingByRunEnd(Symbol symbol, LineRun run)
429
        {
430
            foreach (var connector in symbol.CONNECTORS)
431
            {
432
                object targetItem = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM);
433
                if (targetItem != null &&
434
                    (targetItem.GetType() == typeof(Symbol) || targetItem.GetType() == typeof(Equipment)) &&
435
                    !IsSameLineRun(symbol, targetItem))
436
                {
437
                    SymbolModeling(symbol, targetItem as Symbol);
438
                    for (int i = run.RUNITEMS.Count - 2; i >= 0; i--)
439
                    {
440
                        object item = run.RUNITEMS[i];
441
                        if (item.GetType() == typeof(Symbol))
442
                            SymbolModeling(item as Symbol, run.RUNITEMS[i + 1] as Symbol);
443
                        else
444
                            break;
445
                    }
446
                    break;
447
                }
448
            }
449
        }
450

    
451
        /// <summary>
452
        /// 심볼을 실제로 Modeling 메서드
453
        /// </summary>
454
        /// <param name="symbol"></param>
455
        /// <param name="targetSymbol"></param>
456
        /// <param name="prevSymbol"></param>
457
        private void SymbolModeling(Symbol symbol, Symbol targetSymbol)
458
        {
459
            // OWNERSYMBOL Attribute, 값을 가지고 있을 경우
460
            BaseModel.Attribute itemAttribute = symbol.ATTRIBUTES.Find(attr => attr.ATTRIBUTE == "OWNERSYMBOL");
461
            if (itemAttribute != null && string.IsNullOrEmpty(itemAttribute.VALUE) && itemAttribute.VALUE != "None")
462
                return;
463
            // 이미 모델링 됐을 경우
464
            else if (!string.IsNullOrEmpty(symbol.SPPID.RepresentationId))
465
                return;
466

    
467
            LMSymbol _LMSymbol = null;
468

    
469
            string mappingPath = symbol.SPPID.MAPPINGNAME;
470
            double x = symbol.SPPID.ORIGINAL_X;
471
            double y = symbol.SPPID.ORIGINAL_Y;
472
            int mirror = 0;
473
            double angle = symbol.ANGLE;
474

    
475
            SPPIDUtil.ConvertGridPoint(ref x, ref y);
476

    
477
            // OPC 일경우 180도 일때 Mirror
478
            if (mappingPath.Contains("Piping OPC's") && angle == Math.PI)
479
                mirror = 1;
480

    
481
            if (targetSymbol != null && !string.IsNullOrEmpty(targetSymbol.SPPID.RepresentationId))
482
            {
483
                LMSymbol _TargetItem = dataSource.GetSymbol(targetSymbol.SPPID.RepresentationId);
484
                Connector connector = SPPIDUtil.FindSymbolConnectorByUID(document, symbol.UID, targetSymbol);
485
                if (connector != null)
486
                    GetTargetSymbolConnectorPoint(connector, targetSymbol, ref x, ref y);
487

    
488
                _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle, TargetItem: _TargetItem);
489
                ReleaseCOMObjects(_TargetItem);
490
            }
491
            else
492
                _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
493

    
494

    
495
            if (_LMSymbol != null)
496
            {
497
                _LMSymbol.Commit();
498
                symbol.SPPID.RepresentationId = _LMSymbol.AsLMRepresentation().Id;
499
                symbol.SPPID.GraphicOID = _LMSymbol.get_GraphicOID();
500

    
501
                foreach (var item in symbol.ChildSymbols)
502
                    CreateChildSymbol(item, _LMSymbol);
503
            }
504

    
505
            ReleaseCOMObjects(_LMSymbol);
506
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
507
        }
508

    
509
        /// <summary>
510
        /// ID2의 Symbol Width와 Height를 비교해서 상대적인 SPPID Connector좌표를 가져온다.
511
        /// </summary>
512
        /// <param name="targetConnector"></param>
513
        /// <param name="targetSymbol"></param>
514
        /// <param name="x"></param>
515
        /// <param name="y"></param>
516
        private void GetTargetSymbolConnectorPoint(Connector targetConnector, Symbol targetSymbol, ref double x, ref double y)
517
        {
518
            LMSymbol _TargetItem = dataSource.GetSymbol(targetSymbol.SPPID.RepresentationId);
519

    
520
            double[] range = null;
521
            List<double[]> points = new List<double[]>();
522
            GetSPPIDSymbolRangeAndConnectionPoints(targetSymbol, ref range, points);
523
            double x1 = range[0];
524
            double y1 = range[1];
525
            double x2 = range[2];
526
            double y2 = range[3];
527

    
528
            // Origin 기준 Connector의 위치차이
529
            double sceneX = 0;
530
            double sceneY = 0;
531
            SPPIDUtil.ConvertPointBystring(targetConnector.SCENECONNECTPOINT, ref sceneX, ref sceneY);
532
            double originX = 0;
533
            double originY = 0;
534
            SPPIDUtil.ConvertPointBystring(targetSymbol.ORIGINALPOINT, ref originX, ref originY);
535
            double gapX = originX - sceneX;
536
            double gapY = originY - sceneY;
537

    
538
            // SPPID Symbol과 ID2 심볼의 크기 차이
539
            double sizeWidth = 0;
540
            double sizeHeight = 0;
541
            SPPIDUtil.ConvertPointBystring(targetSymbol.SIZE, ref sizeWidth, ref sizeHeight);
542
            double percentX = (x2 - x1) / sizeWidth;
543
            double percentY = (y2 - y1) / sizeHeight;
544

    
545
            double SPPIDgapX = gapX * percentX;
546
            double SPPIDgapY = gapY * percentY;
547

    
548
            double[] SPPIDOriginPoint = new double[] { _TargetItem.get_XCoordinate() - SPPIDgapX, _TargetItem.get_YCoordinate() + SPPIDgapY };
549
            double distance = double.MaxValue;
550
            double[] resultPoint;
551
            foreach (var point in points)
552
            {
553
                double result = SPPIDUtil.CalcPointToPointdDistance(point[0], point[1], SPPIDOriginPoint[0], SPPIDOriginPoint[1]);
554
                if (distance > result)
555
                {
556
                    distance = result;
557
                    resultPoint = point;
558
                    x = point[0];
559
                    y = point[1];
560
                }
561
            }
562

    
563
            ReleaseCOMObjects(_TargetItem);
564
        }
565

    
566
        /// <summary>
567
        /// SPPID Symbol의 Range를 구한다.
568
        /// </summary>
569
        /// <param name="symbol"></param>
570
        /// <param name="range"></param>
571
        private void GetSPPIDSymbolRangeAndConnectionPoints(Symbol symbol, ref double[] range, List<double[]> points)
572
        {
573
            LMSymbol _TargetItem = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
574
            Ingr.RAD2D.Symbol2d symbol2d = radApp.ActiveDocument.ActiveSheet.DrawingObjects[_TargetItem.get_GraphicOID().ToString()];
575
            double x1 = 0;
576
            double y1 = 0;
577
            double x2 = 0;
578
            double y2 = 0;
579
            symbol2d.Range(out x1, out y1, out x2, out y2);
580
            range = new double[] { x1, y1, x2, y2 };
581

    
582
            for (int i = 1; i < int.MaxValue; i++)
583
            {
584
                double connX = 0;
585
                double connY = 0;
586
                if (_placement.PIDConnectPointLocation(_TargetItem, i, ref connX, ref connY))
587
                    points.Add(new double[] { connX, connY });
588
                else
589
                    break;
590
            }
591

    
592
            foreach (var childSymbol in symbol.ChildSymbols)
593
                GetSPPIDChildSymbolRange(childSymbol, ref range, points);
594

    
595
            ReleaseCOMObjects(_TargetItem);
596
        }
597

    
598
        /// <summary>
599
        /// Child Modeling 된 Symbol의 Range를 구한다.
600
        /// </summary>
601
        /// <param name="childSymbol"></param>
602
        /// <param name="range"></param>
603
        private void GetSPPIDChildSymbolRange(ChildSymbol childSymbol, ref double[] range, List<double[]> points)
604
        {
605
            LMSymbol _ChildSymbol = dataSource.GetSymbol(childSymbol.SPPID.RepresentationId);
606
            Ingr.RAD2D.Symbol2d symbol2d = radApp.ActiveDocument.ActiveSheet.DrawingObjects[_ChildSymbol.get_GraphicOID().ToString()];
607
            double x1 = 0;
608
            double y1 = 0;
609
            double x2 = 0;
610
            double y2 = 0;
611
            symbol2d.Range(out x1, out y1, out x2, out y2);
612
            range[0] = Math.Min(range[0], x1);
613
            range[1] = Math.Min(range[1], y1);
614
            range[2] = Math.Max(range[2], x2);
615
            range[3] = Math.Max(range[3], y2);
616

    
617
            for (int i = 1; i < int.MaxValue; i++)
618
            {
619
                double connX = 0;
620
                double connY = 0;
621
                if (_placement.PIDConnectPointLocation(_ChildSymbol, i, ref connX, ref connY))
622
                    points.Add(new double[] { connX, connY });
623
                else
624
                    break;
625
            }
626

    
627
            foreach (var loopChildSymbol in childSymbol.ChildSymbols)
628
                GetSPPIDChildSymbolRange(loopChildSymbol, ref range, points);
629

    
630
            ReleaseCOMObjects(_ChildSymbol);
631
        }
632

    
633
        /// <summary>
634
        /// Label Symbol Modeling
635
        /// </summary>
636
        /// <param name="symbol"></param>
637
        private void LabelSymbolModeling(Symbol symbol)
638
        {
639
            BaseModel.Attribute itemAttribute = symbol.ATTRIBUTES.Find(x => x.ATTRIBUTE == "OWNERSYMBOL");
640
            if (itemAttribute == null || string.IsNullOrEmpty(itemAttribute.VALUE))
641
                return;
642

    
643
            Array points = new double[] { 0, symbol.SPPID.ORIGINAL_X, symbol.SPPID.ORIGINAL_Y };
644
            
645
            string symbolUID = itemAttribute.VALUE;
646
            object targetItem = SPPIDUtil.FindObjectByUID(document, symbolUID);
647
            if (targetItem != null)
648
            {
649
                // Object 아이템이 Symbol일 경우 Equipment일 경우 
650
                string sRep = null;
651
                if (targetItem.GetType() == typeof(Symbol))
652
                    sRep = ((Symbol)targetItem).SPPID.RepresentationId;
653
                else if (targetItem.GetType() == typeof(Equipment))
654
                    sRep = ((Equipment)targetItem).SPPID.RepresentationId;
655

    
656
                if (!string.IsNullOrEmpty(sRep))
657
                {
658
                    // LEADER Line 검사
659
                    bool leaderLine = false;
660
                    SymbolMapping symbolMapping = document.SymbolMappings.Find(x => x.UID == symbol.DBUID);
661
                    if (symbolMapping != null)
662
                        leaderLine = symbolMapping.LEADERLINE;
663

    
664
                    // Target Symbol Item 가져오고 Label Modeling
665
                    LMSymbol _TargetItem = dataSource.GetSymbol(sRep);
666
                    LMLabelPersist _LMLabelPresist = _placement.PIDPlaceLabel(symbol.SPPID.MAPPINGNAME, ref points, Rotation: 0, LabeledItem: _TargetItem.AsLMRepresentation(), IsLeaderVisible: leaderLine);
667

    
668
                    //Leader 선 센터로
669
                    if (_LMLabelPresist != null)
670
                    {
671
                        // Target Item에 Label의 Attribute Input
672
                        InputSymbolAttribute(targetItem, symbol.ATTRIBUTES);
673

    
674
                        string OID = _LMLabelPresist.get_GraphicOID();
675
                        DependencyObject dependency = radApp.ActiveDocument.ActiveSheet.DrawingObjects[OID] as DependencyObject;
676
                        if (dependency != null)
677
                        {
678
                            bool result = false;
679
                            foreach (var attributes in dependency.AttributeSets)
680
                            {
681
                                foreach (var attribute in attributes)
682
                                {
683
                                    string name = attribute.Name;
684
                                    string value = attribute.GetValue().ToString();
685
                                    if (name == "DrawingItemType" && value == "LabelPersist")
686
                                    {
687
                                        foreach (DrawingObjectBase drawingObject in dependency.DrawingObjects)
688
                                        {
689
                                            if (drawingObject.Type == Ingr.RAD2D.ObjectType.igLineString2d)
690
                                            {
691
                                                Ingr.RAD2D.LineString2d lineString2D = drawingObject as Ingr.RAD2D.LineString2d;
692
                                                double prevX = _TargetItem.get_XCoordinate();
693
                                                double prevY = _TargetItem.get_YCoordinate();
694
                                                lineString2D.InsertVertex(lineString2D.VertexCount, prevX, prevY);
695
                                                lineString2D.RemoveVertex(lineString2D.VertexCount);
696
                                                result = true;
697
                                                break;
698
                                            }
699
                                        }
700
                                    }
701

    
702
                                    if (result)
703
                                        break;
704
                                }
705

    
706
                                if (result)
707
                                    break;
708
                            }
709
                        }
710

    
711
                        _LMLabelPresist.Commit();
712
                    }
713
                    
714
                    ReleaseCOMObjects(_TargetItem);
715
                    ReleaseCOMObjects(_LMLabelPresist);
716
                }
717
            }
718

    
719
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
720
        }
721

    
722
        /// <summary>
723
        /// Equipment를 실제로 Modeling 메서드
724
        /// </summary>
725
        /// <param name="equipment"></param>
726
        private void EquipmentModeling(Equipment equipment)
727
        {
728
            if (!string.IsNullOrEmpty(equipment.SPPID.RepresentationId))
729
                return;
730

    
731
            LMSymbol _LMSymbol = null;
732
            LMSymbol targetItem = null;
733
            string mappingPath = equipment.SPPID.MAPPINGNAME;
734
            double x = equipment.SPPID.ORIGINAL_X;
735
            double y = equipment.SPPID.ORIGINAL_Y;
736
            int mirror = 0;
737
            double angle = equipment.ANGLE;
738

    
739
            SPPIDUtil.ConvertGridPoint(ref x, ref y);
740

    
741
            Connector connector = equipment.CONNECTORS.Find(conn => !string.IsNullOrEmpty(conn.CONNECTEDITEM) && conn.CONNECTEDITEM != "None");
742
            if (connector != null)
743
            {
744
                Equipment connEquipment = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM) as Equipment;
745
                if (connEquipment != null)
746
                {
747
                    if (string.IsNullOrEmpty(connEquipment.SPPID.RepresentationId))
748
                        EquipmentModeling(connEquipment);
749

    
750
                    if (!string.IsNullOrEmpty(connEquipment.SPPID.RepresentationId))
751
                    {
752
                        targetItem = dataSource.GetSymbol(connEquipment.SPPID.RepresentationId);
753
                        if (targetItem != null)
754
                        {
755
                            _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle, TargetItem: targetItem);
756
                        }
757
                        else
758
                        {
759
                            _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
760
                        }
761
                    }
762
                    else
763
                    {
764
                        _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
765
                    }
766
                }
767
                else
768
                {
769
                    _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
770
                }
771
            }
772
            else
773
            {
774
                _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
775
            }
776

    
777
            if (_LMSymbol != null)
778
            {
779
                _LMSymbol.Commit();
780
                equipment.SPPID.RepresentationId = _LMSymbol.AsLMRepresentation().Id;
781
                equipment.SPPID.GraphicOID = _LMSymbol.get_GraphicOID();
782
                ReleaseCOMObjects(_LMSymbol);
783
            }
784

    
785
            if (targetItem != null)
786
            {
787
                ReleaseCOMObjects(targetItem);
788
            }
789
            
790
            ReleaseCOMObjects(_LMSymbol);
791

    
792
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
793
        }
794

    
795
        /// <summary>
796
        /// 3개의 Symbol이 붙어있을경우 CenterSymbol을 Grid기준으로 맞추기 위해서 모델링
797
        /// </summary>
798
        /// <param name="group"></param>
799
        private void SymbolModelingByThreeSymbolGroup(List<Symbol> group)
800
        {
801
            // Group의 가운데 찾기
802
            Symbol symbol1 = null;
803
            Symbol symbol2 = null;
804
            Symbol centerSymbol = null;
805
            foreach (var symbol in group)
806
            {
807
                int count = 0;
808
                foreach (var connector in symbol.CONNECTORS)
809
                {
810
                    object item = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM);
811
                    if (item != null && item.GetType() == typeof(Symbol))
812
                        count++;
813
                }
814

    
815
                // Center Symbol
816
                if (count == 2)
817
                {
818
                    SymbolModeling(symbol, null);
819
                    centerSymbol = symbol;
820
                }
821
                else if (symbol1 == null)
822
                    symbol1 = symbol;
823
                else
824
                    symbol2 = symbol;
825
            }
826

    
827
            SymbolModeling(symbol1, centerSymbol);
828
            SymbolModeling(symbol2, centerSymbol);
829
        }
830

    
831
        /// <summary>
832
        /// 심볼을 실제로 Modeling할때 ChildSymbol이 있다면 Modeling하는 메서드
833
        /// </summary>
834
        /// <param name="childSymbol"></param>
835
        /// <param name="parentSymbol"></param>
836
        private void CreateChildSymbol(ChildSymbol childSymbol, LMSymbol parentSymbol)
837
        {
838
            Ingr.RAD2D.Symbol2d symbol2d = radApp.ActiveDocument.ActiveSheet.DrawingObjects[parentSymbol.get_GraphicOID().ToString()];
839
            double x1 = 0;
840
            double x2 = 0;
841
            double y1 = 0;
842
            double y2 = 0;
843
            symbol2d.Range(out x1, out y1, out x2, out y2);
844

    
845
            LMSymbol _LMSymbol = _placement.PIDPlaceSymbol(childSymbol.SPPID.MAPPINGNAME, (x1 + x2) / 2, (y1 + y2) / 2, TargetItem: parentSymbol);
846
            if (_LMSymbol != null)
847
            {
848
                childSymbol.SPPID.RepresentationId = _LMSymbol.AsLMRepresentation().Id;
849
                foreach (var item in childSymbol.ChildSymbols)
850
                    CreateChildSymbol(item, _LMSymbol);
851
            }
852
            
853

    
854
            ReleaseCOMObjects(_LMSymbol);
855
        }
856

    
857
        /// <summary>
858
        /// item이 TargetItem과 같은 LineRun에 있는지 검사
859
        /// </summary>
860
        /// <param name="item"></param>
861
        /// <param name="targetItem"></param>
862
        /// <returns></returns>
863
        private bool IsSameLineRun(object item, object targetItem)
864
        {
865
            foreach (var lineNumber in document.LINENUMBERS)
866
            {
867
                foreach (var run in lineNumber.RUNS)
868
                {
869
                    foreach (var runItem in run.RUNITEMS)
870
                    {
871
                        if (runItem == item)
872
                        {
873
                            foreach (var findItem in run.RUNITEMS)
874
                            {
875
                                if (findItem == targetItem)
876
                                {
877
                                    return true;
878
                                }
879
                            }
880

    
881
                            return false;
882

    
883
                        }
884
                    }
885
                }
886
            }
887

    
888
            return false;
889
        }
890

    
891
        /// <summary>
892
        /// Line을 실제로 모델링하는 메서드
893
        /// </summary>
894
        /// <param name="lines"></param>
895
        private void LineModeling(List<Line> lines)
896
        {
897
            _LMAItem _LMAItem = _placement.PIDCreateItem(lines[0].SPPID.MAPPINGNAME);
898
            PlaceRunInputs placeRunInputs = new PlaceRunInputs();
899
            LMSymbol _LMSymbol1 = null;
900
            LMSymbol _LMSymbol2 = null;
901
            Dictionary<LMConnector, List<double[]>> connectorVertices1 = new Dictionary<LMConnector, List<double[]>>();
902
            LMConnector targetConnector1 = null;
903
            Dictionary<LMConnector, List<double[]>> connectorVertices2 = new Dictionary<LMConnector, List<double[]>>();
904
            LMConnector targetConnector2 = null;
905

    
906
            Line startBranchLine = null;
907
            Line endBranchLine = null;
908

    
909
            // Type, Line, TargetObjet, x, y
910
            List<Tuple<string, Line, object, double, double>> linePointInfo = new List<Tuple<string, Line, object, double, double>>();
911
            // Point 정리
912
            for (int i = 0; i < lines.Count; i++)
913
            {
914
                Line line = lines[i];
915
                if (i == 0 || i + 1 != lines.Count)
916
                {
917
                    // 시작점에 연결된 Symbol 찾기
918
                    object connItem = SPPIDUtil.FindObjectByUID(document, line.CONNECTORS[0].CONNECTEDITEM);
919
                    if (connItem != null && connItem.GetType() == typeof(Symbol))
920
                    {
921
                        Symbol symbol1 = connItem as Symbol;
922
                        _LMSymbol1 = GetTargetSymbol(symbol1, line);
923
                        if (_LMSymbol1 != null)
924
                        {
925
                            double x = line.SPPID.START_X;
926
                            double y = line.SPPID.START_Y;
927
                            Connector connector = SPPIDUtil.FindSymbolConnectorByUID(document, line.UID, symbol1);
928
                            if (connector != null)
929
                            {
930
                                GetTargetSymbolConnectorPoint(connector, symbol1, ref x, ref y);
931
                                line.SPPID.START_X = x;
932
                                line.SPPID.START_Y = y;
933
                            }
934

    
935
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("SYMBOL", line, _LMSymbol1, x, y));
936
                        }
937
                        else
938
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.START_X, line.SPPID.START_Y));
939
                    }
940
                    else if (connItem != null && connItem.GetType() == typeof(Line) && !lines.Contains(connItem))
941
                    {
942
                        connectorVertices1 = GetPipeRunVertices(((Line)connItem).SPPID.ModelItemId);
943
                        targetConnector1 = FindTargetLMConnector(connectorVertices1, line.SPPID.START_X, line.SPPID.START_Y, line.SPPID.END_X, line.SPPID.END_Y);
944

    
945
                        if (targetConnector1 != null)
946
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("LINE", line, targetConnector1, line.SPPID.START_X, line.SPPID.START_Y));
947
                        else
948
                        {
949
                            startBranchLine = connItem as Line;
950
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.START_X, line.SPPID.START_Y));
951
                        }
952
                    }
953
                    else
954
                        linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.START_X, line.SPPID.START_Y));
955
                        
956
                }
957
                if (i + 1 == lines.Count)
958
                {
959
                    // 끝점에 연결된 Symbol 찾기
960
                    object connItem = SPPIDUtil.FindObjectByUID(document, line.CONNECTORS[1].CONNECTEDITEM);
961

    
962
                    if (i != 0)
963
                        linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.START_X, line.SPPID.START_Y));
964

    
965
                    if (connItem != null && connItem.GetType() == typeof(Symbol))
966
                    {
967
                        Symbol symbol2 = connItem as Symbol;
968
                        _LMSymbol2 = GetTargetSymbol(connItem as Symbol, line);
969
                        if (_LMSymbol2 != null)
970
                        {
971
                            double x = line.SPPID.END_X;
972
                            double y = line.SPPID.END_Y;
973
                            Connector connector = SPPIDUtil.FindSymbolConnectorByUID(document, line.UID, symbol2);
974
                            if (connector != null)
975
                            {
976
                                GetTargetSymbolConnectorPoint(connector, symbol2, ref x, ref y);
977
                                line.SPPID.END_X = x;
978
                                line.SPPID.END_Y = y;
979
                            }
980

    
981
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("SYMBOL", line, _LMSymbol2, x, y));
982
                        }
983
                        else
984
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.END_X, line.SPPID.END_Y));
985
                    }
986
                    else if (connItem != null && connItem.GetType() == typeof(Line) && !lines.Contains(connItem))
987
                    {
988
                        connectorVertices2 = GetPipeRunVertices(((Line)connItem).SPPID.ModelItemId);
989
                        targetConnector2 = FindTargetLMConnector(connectorVertices2, line.SPPID.END_X, line.SPPID.END_Y, line.SPPID.START_X, line.SPPID.START_Y);
990

    
991
                        if (targetConnector2 != null)
992
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("LINE", line, targetConnector2, line.SPPID.END_X, line.SPPID.END_Y));
993
                        else
994
                        {
995
                            endBranchLine = connItem as Line;
996
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.END_X, line.SPPID.END_Y));
997
                        }
998
                    }
999
                    else
1000
                        linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.END_X, line.SPPID.END_Y));
1001
                }
1002
            }
1003

    
1004
            double prevX = double.NaN;
1005
            double prevY = double.NaN;
1006
            SlopeType prevSlopeType = SlopeType.None;
1007
            for (int i = 0; i < linePointInfo.Count; i++)
1008
            {
1009
                Tuple<string, Line, object, double, double> item = linePointInfo[i];
1010
                Line line = item.Item2;
1011
                double x = item.Item4;
1012
                double y = item.Item5;
1013
                SlopeType slopeType = SPPIDUtil.CalcSlope(line.SPPID.START_X, line.SPPID.START_Y, line.SPPID.END_X, line.SPPID.END_Y);
1014
                // Symbol일 경우 바로 Input Point
1015
                if (item.Item1 == "SYMBOL")
1016
                    placeRunInputs.AddSymbolTarget(item.Item3 as LMSymbol, x, y);
1017
                else
1018
                {
1019
                    SPPIDUtil.ConvertGridPoint(ref x, ref y);
1020
                    // i == 0은 그대로 사용
1021
                    if (i != 0)
1022
                    {
1023
                        Tuple<string, Line, object, double, double> prevItem = linePointInfo[i - 1];
1024
                        // y 좌표가 같아야함 및 Symbol 좌표가 정확하지 않으므로 한번더 보정
1025
                        if (prevSlopeType == SlopeType.HORIZONTAL)
1026
                        {
1027
                            y = prevY;
1028
                            SPPIDUtil.ConvertGridPointOnlyOnePoint(ref y);
1029
                        }
1030
                        else if (prevSlopeType == SlopeType.VERTICAL)
1031
                        {
1032
                            x = prevX;
1033
                            SPPIDUtil.ConvertGridPointOnlyOnePoint(ref x);
1034
                        }
1035

    
1036
                        // 마지막이 Symbol일 경우는 Symbol의 좌표를 따라감
1037
                        if (i + 1 == linePointInfo.Count - 1 && linePointInfo[i + 1].Item1 == "SYMBOL")
1038
                        {
1039
                            Line nextLine = linePointInfo[i + 1].Item2;
1040
                            SlopeType nextSlopeType = SPPIDUtil.CalcSlope(nextLine.SPPID.START_X, nextLine.SPPID.START_Y, nextLine.SPPID.END_X, nextLine.SPPID.END_Y);
1041
                            if (slopeType == SlopeType.HORIZONTAL)
1042
                                y = linePointInfo[i + 1].Item5;
1043
                            else if (slopeType == SlopeType.VERTICAL)
1044
                                x = linePointInfo[i + 1].Item4;
1045
                        }
1046
                    }
1047

    
1048
                    if (item.Item1 == "LINE")
1049
                        placeRunInputs.AddConnectorTarget(item.Item3 as LMConnector, x, y);
1050
                    else
1051
                        placeRunInputs.AddPoint(x, y);
1052
                }
1053

    
1054
                prevX = x;
1055
                prevY = y;
1056
                prevSlopeType = slopeType;
1057
            }
1058

    
1059
            LMConnector _lMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1060

    
1061
            if (_lMConnector != null)
1062
            {
1063
                foreach (var line in lines)
1064
                    line.SPPID.ModelItemId = _lMConnector.ModelItemID;
1065
                _lMConnector.Commit();
1066
                if (startBranchLine != null || endBranchLine != null)
1067
                {
1068
                    BranchLines.Add(new Tuple<string, Line, Line>(_lMConnector.ModelItemID, startBranchLine, endBranchLine));
1069
                }
1070
            }
1071

    
1072

    
1073
            if (_LMSymbol1 != null)
1074
                ReleaseCOMObjects(_LMSymbol1);
1075
            if (_LMSymbol2 != null)
1076
                ReleaseCOMObjects(_LMSymbol2);
1077
            if (targetConnector1 != null)
1078
                ReleaseCOMObjects(targetConnector1);
1079
            if (targetConnector2 != null)
1080
                ReleaseCOMObjects(targetConnector2);
1081
            foreach (var item in connectorVertices1)
1082
                ReleaseCOMObjects(item.Key);
1083
            foreach (var item in connectorVertices2)
1084
                ReleaseCOMObjects(item.Key);
1085

    
1086
            ReleaseCOMObjects(_lMConnector);
1087
            ReleaseCOMObjects(placeRunInputs);
1088
            ReleaseCOMObjects(_LMAItem);
1089
        }
1090

    
1091
        /// <summary>
1092
        /// Symbol이 모델링된 SPPPID Symbol Object를 반환 - 연결된 Symbol이 ChildSymbol일 수도 있기때문에 메서드 개발
1093
        /// </summary>
1094
        /// <param name="symbol"></param>
1095
        /// <param name="line"></param>
1096
        /// <returns></returns>
1097
        private LMSymbol GetTargetSymbol(Symbol symbol, Line line)
1098
        {
1099
            LMSymbol _LMSymbol = null;
1100
            foreach (var connector in symbol.CONNECTORS)
1101
            {
1102
                if (connector.CONNECTEDITEM == line.UID)
1103
                {
1104
                    if (connector.Index == 0)
1105
                        _LMSymbol = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
1106
                    else
1107
                    {
1108
                        ChildSymbol child = null;
1109
                        foreach (var childSymbol in symbol.ChildSymbols)
1110
                        {
1111
                            if (childSymbol.Connectors.Contains(connector))
1112
                                child = childSymbol;
1113
                            else
1114
                                child = GetChildSymbolByConnector(childSymbol, connector);
1115

    
1116
                            if (child != null)
1117
                                break;
1118
                        }
1119

    
1120
                        if (child != null)
1121
                            _LMSymbol = dataSource.GetSymbol(child.SPPID.RepresentationId);
1122
                    }
1123

    
1124
                    break;  
1125
                }
1126
            }
1127

    
1128
            return _LMSymbol;
1129
        }
1130

    
1131
        /// <summary>
1132
        /// Connector를 가지고 있는 ChildSymbol Object 반환
1133
        /// </summary>
1134
        /// <param name="item"></param>
1135
        /// <param name="connector"></param>
1136
        /// <returns></returns>
1137
        private ChildSymbol GetChildSymbolByConnector(ChildSymbol item, Connector connector)
1138
        {
1139
            foreach (var childSymbol in item.ChildSymbols)
1140
            {
1141
                if (childSymbol.Connectors.Contains(connector))
1142
                    return childSymbol;
1143
                else
1144
                    return GetChildSymbolByConnector(childSymbol, connector);
1145
            }
1146

    
1147
            return null;
1148
        }
1149

    
1150
        /// <summary>
1151
        /// Branch 라인을 다시 모델링하는 진입 메서드
1152
        /// </summary>
1153
        /// <param name="branch"></param>
1154
        private void BranchLineModeling(Tuple<string, Line, Line> branch)
1155
        {
1156
            List<Line> lines = SPPIDUtil.FindLinesByModelId(document, branch.Item1);
1157

    
1158
            Dictionary<LMConnector, List<double[]>> connectorVertices = GetPipeRunVertices(branch.Item1);
1159

    
1160
            LMConnector _StartConnector = null;
1161
            LMConnector _EndConnector = null;
1162
            double lengthStart = double.MaxValue;
1163
            double lengthEnd = double.MaxValue;
1164
            List<double[]> startPoints = new List<double[]>();
1165
            List<double[]> endPoints = new List<double[]>();
1166

    
1167
            foreach (var item in connectorVertices)
1168
            {
1169
                foreach (var point in item.Value)
1170
                {
1171
                    // Start Point가 Branch
1172
                    if (branch.Item2 != null)
1173
                    {
1174
                        Line targetLine = branch.Item2;
1175
                        double distance = SPPIDUtil.CalcLineToPointDistance(targetLine.SPPID.START_X, targetLine.SPPID.START_Y, targetLine.SPPID.END_X, targetLine.SPPID.END_Y, point[0], point[1]);
1176
                        if (lengthStart > distance)
1177
                        {
1178
                            _StartConnector = item.Key;
1179
                            lengthStart = distance;
1180
                            startPoints = item.Value;
1181
                        }
1182
                    }
1183
                    // End Point가 Branch
1184
                    if (branch.Item3 != null)
1185
                    {
1186
                        Line targetLine = branch.Item3;
1187
                        double distance = SPPIDUtil.CalcLineToPointDistance(targetLine.SPPID.START_X, targetLine.SPPID.START_Y, targetLine.SPPID.END_X, targetLine.SPPID.END_Y, point[0], point[1]);
1188
                        if (lengthEnd > distance)
1189
                        {
1190
                            _EndConnector = item.Key;
1191
                            lengthEnd = distance;
1192
                            endPoints = item.Value;
1193
                        }
1194
                    }
1195
                }
1196
            }
1197
            #region Branch가 양쪽 전부일 때
1198
            if (_StartConnector != null && _StartConnector == _EndConnector)
1199
            {
1200
                _placement.PIDRemovePlacement(_StartConnector.AsLMRepresentation());
1201

    
1202
                _LMAItem _LMAItem = _placement.PIDCreateItem(lines[0].SPPID.MAPPINGNAME);
1203
                PlaceRunInputs placeRunInputs = new PlaceRunInputs();
1204

    
1205
                Dictionary<LMConnector, List<double[]>> startConnectorVertices = GetPipeRunVertices(branch.Item2.SPPID.ModelItemId);
1206
                LMConnector _StartTargetConnector = FindTargetLMConnector(startConnectorVertices, startPoints[0][0], startPoints[0][1], startPoints[1][0], startPoints[1][1]);
1207
                Dictionary<LMConnector, List<double[]>> endConnectorVertices = GetPipeRunVertices(branch.Item3.SPPID.ModelItemId);
1208
                LMConnector _EndTargetConnector = FindTargetLMConnector(endConnectorVertices,
1209
                   startPoints[startPoints.Count - 1][0],
1210
                   startPoints[startPoints.Count - 1][1],
1211
                   startPoints[startPoints.Count - 2][0],
1212
                   startPoints[startPoints.Count - 2][1]);
1213

    
1214
                for (int i = 0; i < startPoints.Count; i++)
1215
                {
1216
                    double[] point = startPoints[i];
1217
                    if (i == 0)
1218
                        placeRunInputs.AddConnectorTarget(_StartTargetConnector, point[0], point[1]);
1219
                    else if (i == startPoints.Count - 1)
1220
                        placeRunInputs.AddConnectorTarget(_EndTargetConnector, point[0], point[1]);
1221
                    else
1222
                        placeRunInputs.AddPoint(point[0], point[1]);
1223
                }
1224

    
1225
                LMConnector _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1226
                if (_LMConnector != null)
1227
                {
1228
                    _LMConnector.Commit();
1229
                    foreach (var item in lines)
1230
                        item.SPPID.ModelItemId = _LMConnector.ModelItemID;
1231
                }
1232

    
1233
                foreach (var item in startConnectorVertices)
1234
                    ReleaseCOMObjects(item.Key);
1235
                foreach (var item in endConnectorVertices)
1236
                    ReleaseCOMObjects(item.Key);
1237
                ReleaseCOMObjects(placeRunInputs);
1238
                ReleaseCOMObjects(_LMAItem);
1239
                ReleaseCOMObjects(_LMConnector);
1240
            }
1241
            #endregion
1242
            #region 양쪽이 다른 Branch 
1243
            else
1244
            {
1245
                // Branch 시작 Connector
1246
                if (_StartConnector != null)
1247
                    BranchLineModelingByConnector(branch, _StartConnector, startPoints, true);
1248

    
1249
                // Branch 끝 Connector
1250
                if (_EndConnector != null)
1251
                    BranchLineModelingByConnector(branch, _EndConnector, endPoints, false);
1252
            }
1253
            #endregion
1254

    
1255
            if (_StartConnector != null)
1256
                ReleaseCOMObjects(_StartConnector);
1257
            if (_EndConnector != null)
1258
                ReleaseCOMObjects(_EndConnector);
1259
            foreach (var item in connectorVertices)
1260
                ReleaseCOMObjects(item.Key);
1261
        }
1262

    
1263
        /// <summary>
1264
        /// Branch 라인을 다시 실제로 모델링하는 메서드
1265
        /// </summary>
1266
        /// <param name="branch"></param>
1267
        /// <param name="_Connector"></param>
1268
        /// <param name="points"></param>
1269
        /// <param name="IsStart"></param>
1270
        private void BranchLineModelingByConnector(Tuple<string, Line, Line> branch, LMConnector _Connector, List<double[]> points, bool IsStart)
1271
        {
1272
            List<Line> lines = SPPIDUtil.FindLinesByModelId(document, branch.Item1);
1273
            Dictionary<LMConnector, List<double[]>> connectorVertices = GetPipeRunVertices(branch.Item1);
1274
            LMConnector _SameRunTargetConnector = null;
1275
            LMSymbol _SameRunTargetSymbol = null;
1276
            Dictionary<LMConnector, List<double[]>> branchConnectorVertices = null;
1277
            LMConnector _BranchTargetConnector = null;
1278
            PlaceRunInputs placeRunInputs = new PlaceRunInputs();
1279

    
1280
            // 같은 Line Run의 Connector 찾기
1281
            foreach (var item in connectorVertices)
1282
            {
1283
                if (item.Key == _Connector)
1284
                    continue;
1285

    
1286
                if (IsStart &&
1287
                    !DBNull.Value.Equals(item.Key.ConnectItem1SymbolID) &&
1288
                    !DBNull.Value.Equals(_Connector.ConnectItem2SymbolID)&& 
1289
                    item.Key.ConnectItem1SymbolID == _Connector.ConnectItem2SymbolID)
1290
                {
1291
                    _SameRunTargetConnector = item.Key;
1292
                    break;
1293
                }
1294
                else if (!IsStart &&
1295
                    !DBNull.Value.Equals(item.Key.ConnectItem2SymbolID) &&
1296
                    !DBNull.Value.Equals(_Connector.ConnectItem1SymbolID) && 
1297
                    item.Key.ConnectItem2SymbolID == _Connector.ConnectItem1SymbolID)
1298
                {
1299
                    _SameRunTargetConnector = item.Key;
1300
                    break;
1301
                }
1302
            }
1303

    
1304
            // Branch 반대편이 Symbol
1305
            if (_SameRunTargetConnector == null)
1306
            {
1307
                foreach (var line in lines)
1308
                {
1309
                    foreach (var connector in line.CONNECTORS)
1310
                    {
1311
                        Symbol symbol = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM) as Symbol;
1312
                        if (symbol != null)
1313
                        {
1314
                            _SameRunTargetSymbol = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
1315
                            break;
1316
                        }
1317
                    }
1318
                }
1319
            }
1320

    
1321
            // 기존 Connector 제거
1322
            _placement.PIDRemovePlacement(_Connector.AsLMRepresentation());
1323
            
1324
            // 시작 Connector일 경우 첫 Point가 TargetConnector를 찾아야함
1325
            if (IsStart)
1326
            {
1327
                branchConnectorVertices = GetPipeRunVertices(branch.Item2.SPPID.ModelItemId);
1328
                _BranchTargetConnector = FindTargetLMConnector(branchConnectorVertices, points[0][0], points[0][1], points[1][0], points[1][1]);
1329
            }
1330
            // 끝 Conenctor일 경우 마지막 Point가 TargetConnector를 찾아야함
1331
            else
1332
            {
1333
                branchConnectorVertices = GetPipeRunVertices(branch.Item3.SPPID.ModelItemId);
1334
                _BranchTargetConnector = FindTargetLMConnector(branchConnectorVertices,
1335
                    points[points.Count - 1][0],
1336
                    points[points.Count - 1][1],
1337
                    points[points.Count - 2][0],
1338
                    points[points.Count - 2][1]);
1339
            }
1340

    
1341
            for (int i = 0; i < points.Count; i++)
1342
            {
1343
                double[] point = points[i];
1344
                if (i == 0)
1345
                {
1346
                    if (IsStart)
1347
                    {
1348
                        if (_BranchTargetConnector != null)
1349
                        {
1350
                            placeRunInputs.AddConnectorTarget(_BranchTargetConnector, point[0], point[1]);
1351
                        }
1352
                        else
1353
                        {
1354
                            placeRunInputs.AddPoint(point[0], point[1]);
1355
                        }
1356
                        
1357
                    }
1358
                    else
1359
                    {
1360
                        if (_SameRunTargetConnector != null)
1361
                            placeRunInputs.AddConnectorTarget(_SameRunTargetConnector, point[0], point[1]);
1362
                        else if (_SameRunTargetSymbol != null)
1363
                            placeRunInputs.AddSymbolTarget(_SameRunTargetSymbol, point[0], point[1]);
1364
                        else
1365
                            placeRunInputs.AddPoint(point[0], point[1]);
1366
                    }
1367
                }
1368
                else if (i == points.Count - 1)
1369
                {
1370
                    if (IsStart)
1371
                    {
1372
                        if (_SameRunTargetConnector != null)
1373
                            placeRunInputs.AddConnectorTarget(_SameRunTargetConnector, point[0], point[1]);
1374
                        else if (_SameRunTargetSymbol != null)
1375
                            placeRunInputs.AddSymbolTarget(_SameRunTargetSymbol, point[0], point[1]);
1376
                        else
1377
                            placeRunInputs.AddPoint(point[0], point[1]);
1378
                    }
1379
                    else
1380
                    {
1381
                        if (_BranchTargetConnector != null)
1382
                        {
1383
                            placeRunInputs.AddConnectorTarget(_BranchTargetConnector, point[0], point[1]);
1384
                        }
1385
                        else
1386
                        {
1387
                            placeRunInputs.AddPoint(point[0], point[1]);
1388
                        }
1389
                    }
1390
                }
1391
                else
1392
                    placeRunInputs.AddPoint(point[0], point[1]);
1393
            }
1394
            _LMAItem _LMAItem = _placement.PIDCreateItem(lines[0].SPPID.MAPPINGNAME);
1395
            LMConnector _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1396

    
1397
            if (_LMConnector != null)
1398
            {
1399
                if (_SameRunTargetConnector != null)
1400
                {
1401
                    JoinPipeRun(_LMConnector.ModelItemID, _SameRunTargetConnector.ModelItemID);
1402
                }
1403
                else
1404
                {
1405
                    foreach (var item in lines)
1406
                        item.SPPID.ModelItemId = _LMConnector.ModelItemID;
1407
                }
1408

    
1409
                _LMConnector.Commit();
1410
                ReleaseCOMObjects(_LMConnector);
1411
            }
1412

    
1413
            ReleaseCOMObjects(placeRunInputs);
1414
            ReleaseCOMObjects(_LMAItem);
1415
            if (_BranchTargetConnector != null)
1416
                ReleaseCOMObjects(_BranchTargetConnector);
1417
            if (_SameRunTargetConnector != null)
1418
                ReleaseCOMObjects(_SameRunTargetConnector);
1419
            if (_SameRunTargetSymbol != null)
1420
                ReleaseCOMObjects(_SameRunTargetSymbol);
1421
            foreach (var item in connectorVertices)
1422
                ReleaseCOMObjects(item.Key);
1423
            foreach (var item in branchConnectorVertices)
1424
                ReleaseCOMObjects(item.Key);
1425
        }
1426

    
1427
        /// <summary>
1428
        /// EndBreak 모델링 메서드
1429
        /// </summary>
1430
        /// <param name="endBreak"></param>
1431
        private void EndBreakModeling(EndBreak endBreak)
1432
        {
1433
            object ownerObj = SPPIDUtil.FindObjectByUID(document, endBreak.OWNER);
1434
            LMConnector targetLMConnector = null;
1435
            if (ownerObj !=null && ownerObj.GetType() == typeof(Line))
1436
            {
1437
                Line ownerLine = ownerObj as Line;
1438
                LMLabelPersist _LmLabelPersist = null;
1439
                Dictionary<LMConnector, List<double[]>> connectorVertices = GetPipeRunVertices(ownerLine.SPPID.ModelItemId);
1440

    
1441
                targetLMConnector = FindTargetLMConnectorByPoint(connectorVertices, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y);
1442
                
1443
                if (targetLMConnector != null)
1444
                {
1445
                    Array array = new double[] { 0, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y };
1446
                    _LmLabelPersist = _placement.PIDPlaceLabel(endBreak.SPPID.MAPPINGNAME, ref array, Rotation: 0, LabeledItem: targetLMConnector.AsLMRepresentation(), IsLeaderVisible: true);
1447
                }
1448

    
1449
                if (_LmLabelPersist != null)
1450
                {
1451
                    _LmLabelPersist.Commit();
1452
                    ReleaseCOMObjects(_LmLabelPersist);
1453
                }
1454
                else
1455
                    RetryEndBreakModeling(endBreak, targetLMConnector);
1456

    
1457
                foreach (var item in connectorVertices)
1458
                    ReleaseCOMObjects(item.Key);
1459

    
1460
            }
1461
            else if (ownerObj != null && ownerObj.GetType() == typeof(Symbol))
1462
            {
1463
                Symbol ownerSymbol = ownerObj as Symbol;
1464
                LMSymbol _LMSymbol = dataSource.GetSymbol(ownerSymbol.SPPID.RepresentationId);
1465

    
1466
                targetLMConnector = null;
1467
                double distance = double.MaxValue;
1468

    
1469
                foreach (LMConnector connector in _LMSymbol.Avoid1Connectors)
1470
                {
1471
                    if (connector.get_ItemStatus() == "Active")
1472
                    {
1473
                        dynamic OID = connector.get_GraphicOID();
1474
                        DependencyObject drawingObject = radApp.ActiveDocument.ActiveSheet.DrawingObjects[OID];
1475
                        Ingr.RAD2D.LineStringGeometry2d lineStringGeometry = drawingObject.GetGeometry() as Ingr.RAD2D.LineStringGeometry2d;
1476
                        int verticesCount = lineStringGeometry.VertexCount;
1477
                        double[] vertices = null;
1478
                        lineStringGeometry.GetVertices(ref verticesCount, ref vertices);
1479
                        for (int i = 0; i < verticesCount; i++)
1480
                        {
1481
                            double x = 0;
1482
                            double y = 0;
1483
                            lineStringGeometry.GetVertex(i + 1, ref x, ref y);
1484

    
1485
                            double result = SPPIDUtil.CalcPointToPointdDistance(x, y, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y);
1486
                            if (result < distance)
1487
                            {
1488
                                targetLMConnector = connector;
1489
                                distance = result;
1490
                            }
1491
                        }
1492
                    }
1493
                }
1494

    
1495
                foreach (LMConnector connector in _LMSymbol.Avoid2Connectors)
1496
                {
1497
                    if (connector.get_ItemStatus() == "Active")
1498
                    {
1499
                        dynamic OID = connector.get_GraphicOID();
1500
                        DependencyObject drawingObject = radApp.ActiveDocument.ActiveSheet.DrawingObjects[OID];
1501
                        Ingr.RAD2D.LineStringGeometry2d lineStringGeometry = drawingObject.GetGeometry() as Ingr.RAD2D.LineStringGeometry2d;
1502
                        int verticesCount = lineStringGeometry.VertexCount;
1503
                        double[] vertices = null;
1504
                        lineStringGeometry.GetVertices(ref verticesCount, ref vertices);
1505
                        for (int i = 0; i < verticesCount; i++)
1506
                        {
1507
                            double x = 0;
1508
                            double y = 0;
1509
                            lineStringGeometry.GetVertex(i + 1, ref x, ref y);
1510

    
1511
                            double result = SPPIDUtil.CalcPointToPointdDistance(x, y, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y);
1512
                            if (result < distance)
1513
                            {
1514
                                targetLMConnector = connector;
1515
                                distance = result;
1516
                            }
1517
                        }
1518
                    }
1519
                }
1520

    
1521
                if (targetLMConnector != null)
1522
                {
1523
                    LMLabelPersist _LmLabelPersist = null;
1524
                    Array array = new double[] { 0, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y };
1525
                    _LmLabelPersist = _placement.PIDPlaceLabel(endBreak.SPPID.MAPPINGNAME, ref array, Rotation: 0, LabeledItem: targetLMConnector.AsLMRepresentation(), IsLeaderVisible: true);
1526
                    if (_LmLabelPersist != null)
1527
                    {
1528
                        _LmLabelPersist.Commit();
1529
                        ReleaseCOMObjects(_LmLabelPersist);
1530
                    }
1531
                    else
1532
                        RetryEndBreakModeling(endBreak, targetLMConnector);
1533
                }
1534
                
1535
                ReleaseCOMObjects(_LMSymbol);
1536
            }
1537

    
1538
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
1539
        }
1540

    
1541
        /// <summary>
1542
        /// EndBreak 모델링이 실패시 다시 시도하는 메서드
1543
        /// </summary>
1544
        /// <param name="endBreak"></param>
1545
        /// <param name="targetLMConnector"></param>
1546
        private void RetryEndBreakModeling(EndBreak endBreak, LMConnector targetLMConnector)
1547
        {
1548
            bool isZeroLength = Convert.ToBoolean(targetLMConnector.get_IsZeroLength());
1549
            Array array = null;
1550
            LMLabelPersist _LMLabelPersist = null;
1551
            LMConnector _LMConnector = null;
1552
            dynamic OID = targetLMConnector.get_GraphicOID();
1553
            DependencyObject drawingObject = radApp.ActiveDocument.ActiveSheet.DrawingObjects[OID];
1554
            Ingr.RAD2D.LineStringGeometry2d lineStringGeometry = drawingObject.GetGeometry() as Ingr.RAD2D.LineStringGeometry2d;
1555
            int verticesCount = lineStringGeometry.VertexCount;
1556
            PlaceRunInputs placeRunInputs = new PlaceRunInputs();
1557
            _LMAItem _LMAItem = _placement.PIDCreateItem(@"\Piping\Routing\Process Lines\Primary Piping.sym");
1558

    
1559
            if (isZeroLength)
1560
            {
1561
                double[] vertices = null;
1562
                lineStringGeometry.GetVertices(ref verticesCount, ref vertices);
1563
                double x = 0;
1564
                double y = 0;
1565
                lineStringGeometry.GetVertex(1, ref x, ref y);
1566

    
1567
                placeRunInputs.AddSymbolTarget(targetLMConnector.ConnectItem1SymbolObject, x, y);
1568
                placeRunInputs.AddSymbolTarget(targetLMConnector.ConnectItem2SymbolObject, x, y);
1569

    
1570
                _placement.PIDRemovePlacement(targetLMConnector.AsLMRepresentation());
1571
                _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1572

    
1573
                array = new double[] { 0, x, y };
1574
                _LMLabelPersist = _placement.PIDPlaceLabel(endBreak.SPPID.MAPPINGNAME, ref array, Rotation: 0, LabeledItem: _LMConnector.AsLMRepresentation(), IsLeaderVisible: true);
1575

    
1576
                AutoJoinPipeRun(_LMConnector.ModelItemID);
1577
            }
1578
            else
1579
            {
1580
                List<double[]> vertices = new List<double[]>();
1581
                for (int i = 1; i <= verticesCount; i++)
1582
                {
1583
                    double x = 0;
1584
                    double y = 0;
1585
                    lineStringGeometry.GetVertex(i, ref x, ref y);
1586
                    vertices.Add(new double[] { x, y });
1587
                }
1588

    
1589
                for (int i = 0; i < vertices.Count; i++)
1590
                {
1591
                    double[] points = vertices[i];
1592
                    if (i == 0)
1593
                    {
1594
                        if (targetLMConnector.ConnectItem1SymbolObject != null)
1595
                            placeRunInputs.AddSymbolTarget(targetLMConnector.ConnectItem1SymbolObject, points[0], points[1]);
1596
                        else
1597
                            placeRunInputs.AddPoint(points[0], points[1]);
1598
                    }
1599
                    else if (i == vertices.Count - 1)
1600
                    {
1601
                        if (targetLMConnector.ConnectItem2SymbolObject != null)
1602
                            placeRunInputs.AddSymbolTarget(targetLMConnector.ConnectItem2SymbolObject, points[0], points[1]);
1603
                        else
1604
                            placeRunInputs.AddPoint(points[0], points[1]);
1605
                    }
1606
                    else
1607
                        placeRunInputs.AddPoint(points[0], points[1]);
1608
                }
1609

    
1610
                List<Line> lines = SPPIDUtil.FindLinesByModelId(document, targetLMConnector.ModelItemID);
1611
                
1612
                _placement.PIDRemovePlacement(targetLMConnector.AsLMRepresentation());
1613
                _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1614

    
1615
                array = new double[] { 0, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y };
1616
                _LMLabelPersist = _placement.PIDPlaceLabel(endBreak.SPPID.MAPPINGNAME, ref array, Rotation: 0, LabeledItem: _LMConnector.AsLMRepresentation(), IsLeaderVisible: true);
1617

    
1618
                AutoJoinPipeRun(_LMConnector.ModelItemID);
1619
                foreach (var line in lines)
1620
                    line.SPPID.ModelItemId = _LMConnector.ModelItemID;
1621
            }
1622

    
1623

    
1624
            if (_LMLabelPersist != null)
1625
            {
1626
                _LMLabelPersist.Commit();
1627
                ReleaseCOMObjects(_LMLabelPersist);
1628
            }
1629
            else
1630
            {
1631
                
1632
            }
1633

    
1634
            ReleaseCOMObjects(_LMConnector);
1635
            ReleaseCOMObjects(placeRunInputs);
1636
            ReleaseCOMObjects(_LMAItem);
1637
        }
1638

    
1639
        /// <summary>
1640
        /// FromModelItem을 ToModelItem으로 PipeRunJoin하는 메서드
1641
        /// </summary>
1642
        /// <param name="fromModelItemId"></param>
1643
        /// <param name="toModelItemId"></param>
1644
        private void JoinPipeRun(string fromModelItemId, string toModelItemId)
1645
        {
1646
            LMModelItem modelItem1 = dataSource.GetModelItem(toModelItemId);
1647
            _LMAItem item1 = modelItem1.AsLMAItem();
1648
            LMModelItem modelItem2 = dataSource.GetModelItem(fromModelItemId);
1649
            _LMAItem item2 = modelItem2.AsLMAItem();
1650
            
1651
            // item2가 item1으로 조인
1652
            try
1653
            {
1654
                _placement.PIDJoinRuns(ref item1, ref item2);
1655
                item1.Commit();
1656
                item2.Commit();
1657

    
1658
                List<Line> lines = SPPIDUtil.FindLinesByModelId(document, fromModelItemId);
1659
                foreach (var line in lines)
1660
                    line.SPPID.ModelItemId = toModelItemId;
1661
            }
1662
            catch (Exception ex)
1663
            {
1664
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
1665
            }
1666
            finally
1667
            {
1668
                ReleaseCOMObjects(modelItem1);
1669
                ReleaseCOMObjects(item1);
1670
                ReleaseCOMObjects(modelItem2);
1671
                ReleaseCOMObjects(item2);
1672
            }
1673
        }
1674

    
1675
        /// <summary>
1676
        /// PipeRun을 자동으로 Join하는 메서드
1677
        /// </summary>
1678
        /// <param name="modelItemId"></param>
1679
        private void AutoJoinPipeRun(string modelItemId)
1680
        {
1681
            LMModelItem modelItem = dataSource.GetModelItem(modelItemId);
1682
            _LMAItem item = modelItem.AsLMAItem();
1683
            try
1684
            {
1685
                string modelitemID = item.Id;
1686
                _placement.PIDAutoJoin(item, AutoJoinEndConstants.autoJoin_Both, ref item);
1687
                string afterModelItemID = item.Id;
1688
                
1689
                if (modelitemID != afterModelItemID)
1690
                {
1691
                    List<Line> lines = SPPIDUtil.FindLinesByModelId(document, modelitemID);
1692
                    foreach (var line in lines)
1693
                        line.SPPID.ModelItemId = afterModelItemID;
1694
                }
1695
                item.Commit();
1696
            }
1697
            catch (Exception ex)
1698
            {
1699
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
1700
            }
1701
            finally
1702
            {
1703
                ReleaseCOMObjects(modelItem);
1704
                ReleaseCOMObjects(item);
1705
            }
1706
        }
1707

    
1708
        /// <summary>
1709
        /// LineRun에 있는 Line들을 Join하는 진입 메서드
1710
        /// </summary>
1711
        /// <param name="run"></param>
1712
        private void JoinRunLine(LineRun run)
1713
        {
1714
            string modelItemId = string.Empty;
1715
            foreach (var item in run.RUNITEMS)
1716
            {
1717
                if (item.GetType() == typeof(Line))
1718
                {
1719
                    Line line = item as Line;
1720
                    AutoJoinPipeRun(line.SPPID.ModelItemId);
1721
                    modelItemId = line.SPPID.ModelItemId;
1722

    
1723
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
1724
                }
1725
            }
1726
        }
1727

    
1728
        /// <summary>
1729
        /// PipeRun의 좌표를 가져오는 메서드
1730
        /// </summary>
1731
        /// <param name="modelId"></param>
1732
        /// <returns></returns>
1733
        private Dictionary<LMConnector, List<double[]>> GetPipeRunVertices(string modelId)
1734
        {
1735
            Dictionary<LMConnector, List<double[]>> connectorVertices = new Dictionary<LMConnector, List<double[]>>();
1736
            LMModelItem modelItem = dataSource.GetModelItem(modelId);
1737

    
1738
            if (modelItem != null)
1739
            {
1740
                foreach (LMRepresentation rep in modelItem.Representations)
1741
                {
1742
                    if (rep.Attributes["RepresentationType"].get_Value() == "Connector" && rep.Attributes["ItemStatus"].get_Value() == "Active")
1743
                    {
1744
                        LMConnector _LMConnector = dataSource.GetConnector(rep.Id);
1745
                        connectorVertices.Add(_LMConnector, new List<double[]>());
1746
                        dynamic OID = rep.get_GraphicOID();
1747
                        DependencyObject drawingObject = radApp.ActiveDocument.ActiveSheet.DrawingObjects[OID];
1748
                        Ingr.RAD2D.LineStringGeometry2d lineStringGeometry = drawingObject.GetGeometry() as Ingr.RAD2D.LineStringGeometry2d;
1749
                        int verticesCount = lineStringGeometry.VertexCount;
1750
                        double[] vertices = null;
1751
                        lineStringGeometry.GetVertices(ref verticesCount, ref vertices);
1752
                        for (int i = 0; i < verticesCount; i++)
1753
                        {
1754
                            double x = 0;
1755
                            double y = 0;
1756
                            lineStringGeometry.GetVertex(i + 1, ref x, ref y);
1757
                            connectorVertices[_LMConnector].Add(new double[] { Math.Round(x, 10), Math.Round(y, 10) });
1758
                        }
1759
                    }
1760
                }
1761

    
1762
                ReleaseCOMObjects(modelItem);
1763
            }
1764

    
1765
            return connectorVertices;
1766
        }
1767

    
1768
        /// <summary>
1769
        /// 좌표로 PipeRun의 Connector중에 어느 Connector에 가까운지/붙을지 가져오는 메서드 - 두점으로 라인의 교차점을 기준으로 구함
1770
        /// </summary>
1771
        /// <param name="connectorVertices"></param>
1772
        /// <param name="connX"></param>
1773
        /// <param name="connY"></param>
1774
        /// <param name="x2"></param>
1775
        /// <param name="y2"></param>
1776
        /// <returns></returns>
1777
        private LMConnector FindTargetLMConnector(Dictionary<LMConnector, List<double[]>> connectorVertices, double connX, double connY, double x2, double y2)
1778
        {
1779
            double length = double.MaxValue;
1780
            LMConnector targetConnector = null;
1781
            foreach (var item in connectorVertices)
1782
            {
1783
                List<double[]> points = item.Value;
1784
                for (int i = 0; i < points.Count - 1; i++)
1785
                {
1786
                    double[] point1 = points[i];
1787
                    double[] point2 = points[i + 1];
1788

    
1789
                    double maxLineX = Math.Max(point1[0], point2[0]);
1790
                    double minLineX = Math.Min(point1[0], point2[0]);
1791
                    double maxLineY = Math.Max(point1[1], point2[1]);
1792
                    double minLineY = Math.Min(point1[1], point2[1]);
1793

    
1794
                    SlopeType slope = SPPIDUtil.CalcSlope(minLineX, minLineY, maxLineX, maxLineY);
1795

    
1796
                    // 두직선의 교차점
1797
                    double[] crossingPoint = SPPIDUtil.CalcLineCrossingPoint(connX, connY, x2, y2, point1[0], point1[1], point2[0], point2[1]);
1798
                    if (crossingPoint != null)
1799
                    {
1800
                        double distance = SPPIDUtil.CalcPointToPointdDistance(connX, connY, crossingPoint[0], crossingPoint[1]);
1801
                        if (length >= distance)
1802
                        {
1803
                            if (slope == SlopeType.Slope &&
1804
                                minLineX <= crossingPoint[0] && maxLineX >= crossingPoint[0] &&
1805
                                minLineY <= crossingPoint[1] && maxLineY >= crossingPoint[1])
1806
                            {
1807
                                targetConnector = item.Key;
1808
                                length = distance;
1809
                            }
1810
                            else if (slope == SlopeType.HORIZONTAL &&
1811
                                minLineX <= crossingPoint[0] && maxLineX >= crossingPoint[0])
1812
                            {
1813
                                targetConnector = item.Key;
1814
                                length = distance;
1815
                            }
1816
                            else if (slope == SlopeType.VERTICAL &&
1817
                               minLineY <= crossingPoint[1] && maxLineY >= crossingPoint[1])
1818
                            {
1819
                                targetConnector = item.Key;
1820
                                length = distance;
1821
                            }
1822
                        }
1823
                    }
1824
                }
1825

    
1826

    
1827
            }
1828

    
1829
            if (targetConnector == null)
1830
            {
1831
                foreach (var item in connectorVertices)
1832
                {
1833
                    List<double[]> points = item.Value;
1834
                    foreach (var point in points)
1835
                    {
1836
                        double distance = SPPIDUtil.CalcPointToPointdDistance(connX, connY, point[0], point[1]);
1837
                        if (length >= distance)
1838
                        {
1839
                            targetConnector = item.Key;
1840
                            length = distance;
1841
                        }
1842
                    }
1843
                }
1844

    
1845
            }
1846

    
1847
            return targetConnector;
1848
        }
1849

    
1850
        /// <summary>
1851
        /// 좌표로 PipeRun의 Connector중에 어느 Connector에 가까운지/붙을지 가져오는 메서드 - 한점으로 제일 가까운 기준으로 구함(단순)
1852
        /// </summary>
1853
        /// <param name="connectorVertices"></param>
1854
        /// <param name="connX"></param>
1855
        /// <param name="connY"></param>
1856
        /// <returns></returns>
1857
        private LMConnector FindTargetLMConnectorByPoint(Dictionary<LMConnector, List<double[]>> connectorVertices, double connX, double connY)
1858
        {
1859
            double length = double.MaxValue;
1860
            LMConnector targetConnector = null;
1861
            foreach (var item in connectorVertices)
1862
            {
1863
                List<double[]> points = item.Value;
1864

    
1865
                foreach (double[] point in points)
1866
                {
1867
                    double distance = SPPIDUtil.CalcPointToPointdDistance(point[0], point[1], connX, connY);
1868
                    if (length >= distance)
1869
                    {
1870
                        targetConnector = item.Key;
1871
                        length = distance;
1872
                    }
1873
                }
1874
            }
1875

    
1876
            return targetConnector;
1877
        }
1878

    
1879
        /// <summary>
1880
        /// 좌표로 PipeRun의 Connector중에 어느 Connector에 가까운지/붙을지 가져오는 메서드 - 조건에 안맞아서 못찾을시 제일 가까운 점으로 가져오는 방식
1881
        /// </summary>
1882
        /// <param name="connectorVertices"></param>
1883
        /// <param name="connX"></param>
1884
        /// <param name="connY"></param>
1885
        /// <returns></returns>
1886
        private LMConnector FindTargetLMConnectorForLabel(Dictionary<LMConnector, List<double[]>> connectorVertices, double connX, double connY)
1887
        {
1888
            double length = double.MaxValue;
1889
            LMConnector targetConnector = null;
1890
            foreach (var item in connectorVertices)
1891
            {
1892
                List<double[]> points = item.Value;
1893
                for (int i = 0; i < points.Count - 1; i++)
1894
                {
1895
                    double[] point1 = points[i];
1896
                    double[] point2 = points[i + 1];
1897
                    double x1 = Math.Min(point1[0], point2[0]);
1898
                    double y1 = Math.Min(point1[1], point2[1]);
1899
                    double x2 = Math.Max(point1[0], point2[0]);
1900
                    double y2 = Math.Max(point1[1], point2[1]);
1901

    
1902
                    if ((x1 <= connX && x2 >= connX) ||
1903
                        (y1 <= connY && y2 >= connY))
1904
                    {
1905
                        double distance = SPPIDUtil.CalcPointToPointdDistance(point1[0], point1[1], connX, connY);
1906
                        if (length >= distance)
1907
                        {
1908
                            targetConnector = item.Key;
1909
                            length = distance;
1910
                        }
1911

    
1912
                        distance = SPPIDUtil.CalcPointToPointdDistance(point2[0], point2[1], connX, connY);
1913
                        if (length >= distance)
1914
                        {
1915
                            targetConnector = item.Key;
1916
                            length = distance;
1917
                        }
1918
                    }
1919
                }
1920
            }
1921

    
1922
            // 못찾았을때.
1923
            length = double.MaxValue;
1924
            if (targetConnector == null)
1925
            {
1926
                foreach (var item in connectorVertices)
1927
                {
1928
                    List<double[]> points = item.Value;
1929

    
1930
                    foreach (double[] point in points)
1931
                    {
1932
                        double distance = SPPIDUtil.CalcPointToPointdDistance(point[0], point[1], connX, connY);
1933
                        if (length >= distance)
1934
                        {
1935
                            targetConnector = item.Key;
1936
                            length = distance;
1937
                        }
1938
                    }
1939
                }
1940
            }
1941

    
1942
            return targetConnector;
1943
        }
1944

    
1945
        /// <summary>
1946
        /// Line Number Symbol을 실제로 Modeling하는 메서드
1947
        /// </summary>
1948
        /// <param name="lineNumber"></param>
1949
        private void LineNumberModeling(LineNumber lineNumber)
1950
        {
1951
            Line line = SPPIDUtil.FindObjectByUID(document, lineNumber.CONNLINE) as Line;
1952
            Dictionary<LMConnector, List<double[]>> connectorVertices = GetPipeRunVertices(line.SPPID.ModelItemId);
1953
            LMConnector connectedLMConnector = FindTargetLMConnectorForLabel(connectorVertices, lineNumber.SPPID.ORIGINAL_X, lineNumber.SPPID.ORIGINAL_Y);
1954
            if (connectedLMConnector != null)
1955
            {
1956
                double x = 0;
1957
                double y = 0;
1958
                CalcLabelLocation(ref x, ref y, lineNumber.SPPID.ORIGINAL_X, lineNumber.SPPID.ORIGINAL_Y, lineNumber.SPPIDLabelLocation, _ETCSetting.LineNumberLocation);
1959

    
1960
                Array points = new double[] { 0, x, y };
1961
                LMLabelPersist _LmLabelPresist = _placement.PIDPlaceLabel(lineNumber.SPPID.MAPPINGNAME, ref points, Rotation: lineNumber.ANGLE, LabeledItem: connectedLMConnector.AsLMRepresentation(), IsLeaderVisible: false);
1962

    
1963
                foreach (var item in connectorVertices)
1964
                    ReleaseCOMObjects(item.Key);
1965
                if (_LmLabelPresist != null)
1966
                {
1967
                    _LmLabelPresist.Commit();
1968
                    lineNumber.SPPID.RepresentationId = _LmLabelPresist.AsLMRepresentation().Id;
1969
                    ReleaseCOMObjects(_LmLabelPresist);
1970
                }
1971
                else
1972
                {
1973

    
1974
                }
1975
            }
1976

    
1977
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
1978
        }
1979

    
1980
        /// <summary>
1981
        /// Flow Mark Modeling
1982
        /// </summary>
1983
        /// <param name="line"></param>
1984
        private void FlowMarkModeling(Line line)
1985
        {
1986
            if (line.FLOWMARK && !string.IsNullOrEmpty(line.SPPID.ModelItemId) && !string.IsNullOrEmpty(_ETCSetting.FlowMarkSymbolPath))
1987
            {
1988
                SlopeType targetSlopeType = SPPIDUtil.CalcSlope(line.SPPID.START_X, line.SPPID.START_Y, line.SPPID.END_X, line.SPPID.END_Y);
1989
                string mappingPath = _ETCSetting.FlowMarkSymbolPath;
1990
                double percent = line.FLOWMARK_PERCENT;
1991
                double tempX = 0;
1992
                double tempY = 0;
1993

    
1994
                double gapX;
1995
                double gapY;
1996
                // ID2 기준의 Gap을 구함
1997
                if (percent == 0)
1998
                {
1999
                    gapX = 0;
2000
                    gapY = 0;
2001
                }
2002
                else
2003
                {
2004
                    gapX = Math.Abs(line.SPPID.START_X - line.SPPID.END_X) / 100 * percent;
2005
                    gapY = Math.Abs(line.SPPID.START_Y - line.SPPID.END_Y) / 100 * percent;
2006
                }
2007

    
2008
                if (line.SPPID.START_X < line.SPPID.END_X)
2009
                    tempX = line.SPPID.START_X + gapX;
2010
                else
2011
                    tempX = line.SPPID.START_X - gapX;
2012

    
2013
                if (line.SPPID.START_Y < line.SPPID.END_Y)
2014
                    tempY = line.SPPID.START_Y + gapY;
2015
                else
2016
                    tempY = line.SPPID.START_Y - gapY;
2017

    
2018
                
2019
               
2020
                Dictionary<LMConnector, List<double[]>> connectorVertices = GetPipeRunVertices(line.SPPID.ModelItemId);
2021
                LMConnector _TargetItem = null;
2022
                double distance = double.MaxValue;
2023
                double[] startPoint = null;
2024
                double[] endPoint = null;
2025
                // ID2의 기준 Gap으로 제일 가까운 Line 찾음(Slope도 같은조건)
2026
                foreach (var item in connectorVertices)
2027
                {
2028
                    for (int i = 0; i < item.Value.Count - 1; i++)
2029
                    {
2030
                        List<double[]> points = item.Value;
2031
                        double[] point1 = points[i];
2032
                        double[] point2 = points[i + 1];
2033

    
2034
                        SlopeType slopeType = SPPIDUtil.CalcSlope(point1[0], point1[1], point2[0], point2[1]);
2035
                        if (slopeType == targetSlopeType)
2036
                        {
2037
                            double result = SPPIDUtil.CalcPointToPointdDistance(point1[0], point1[1], tempX, tempY);
2038
                            if (result < distance)
2039
                            {
2040
                                distance = result;
2041
                                _TargetItem = item.Key;
2042

    
2043
                                startPoint = point1;
2044
                                endPoint = point2;
2045
                            }
2046

    
2047
                            result = SPPIDUtil.CalcPointToPointdDistance(point2[0], point2[1], tempX, tempY);
2048
                            if (result < distance)
2049
                            {
2050
                                distance = result;
2051
                                _TargetItem = item.Key;
2052

    
2053
                                startPoint = point1;
2054
                                endPoint = point2;
2055
                            }
2056
                        }
2057
                    }
2058
                }
2059

    
2060
                if (_TargetItem != null)
2061
                {
2062
                    double x = 0;
2063
                    double y = 0;
2064
                    double angle = 0;
2065
                    // SPPID 기준의 Gap으로 실 좌표를 구함
2066
                    if (percent == 0)
2067
                    {
2068
                        gapX = 0;
2069
                        gapY = 0;
2070
                    }
2071
                    else
2072
                    {
2073
                        gapX = Math.Abs(startPoint[0] - endPoint[0]) / 100 * percent;
2074
                        gapY = Math.Abs(startPoint[1] - endPoint[1]) / 100 * percent;
2075
                    }
2076

    
2077
                    if (startPoint[0] < endPoint[0])
2078
                        x = startPoint[0] + gapX;
2079
                    else
2080
                        x = startPoint[0] - gapX;
2081

    
2082
                    if (startPoint[1] < endPoint[1])
2083
                        y = startPoint[1] + gapY;
2084
                    else
2085
                        y = startPoint[1] - gapY;
2086
                    
2087
                    if (targetSlopeType == SlopeType.HORIZONTAL)
2088
                    {
2089
                        if (startPoint[0] < endPoint[0])
2090
                            angle = 0;
2091
                        else
2092
                            angle = Math.PI;
2093
                    }
2094
                    // 90 270
2095
                    else if (targetSlopeType == SlopeType.VERTICAL)
2096
                    {
2097
                        if (startPoint[1] < endPoint[1])
2098
                            angle = 90 * Math.PI / 180;
2099
                        else
2100
                            angle = 270 * Math.PI / 180;
2101
                    }
2102

    
2103
                    LMSymbol _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: 0, Rotation: angle, TargetItem: _TargetItem);
2104
                    
2105
                    if (_LMSymbol != null)
2106
                    {
2107
                        ReleaseCOMObjects(_LMSymbol);
2108
                    }
2109
                        
2110
                }
2111

    
2112
                foreach (var item in connectorVertices)
2113
                    ReleaseCOMObjects(item.Key);
2114
            }
2115
        }
2116

    
2117
        /// <summary>
2118
        /// Line Number 기준으로 모든 Item에 Line Number의 Attribute Input
2119
        /// </summary>
2120
        /// <param name="lineNumber"></param>
2121
        private void InputLineNumberAttribute(LineNumber lineNumber)
2122
        {
2123
            foreach (LineRun run in lineNumber.RUNS)
2124
            {
2125
                foreach (var item in run.RUNITEMS)
2126
                {
2127
                    if (item.GetType() == typeof(Symbol))
2128
                    {
2129
                        Symbol symbol = item as Symbol;
2130
                        LMSymbol _LMSymbol = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
2131
                        LMModelItem _LMModelItem = _LMSymbol.ModelItemObject;
2132

    
2133
                        if (_LMModelItem != null && _LMModelItem.get_ItemStatus() == "Active")
2134
                        {
2135
                            foreach (var attribute in lineNumber.ATTRIBUTES)
2136
                            {
2137
                                LineNumberMapping mapping = document.LineNumberMappings.Find(x => x.UID == attribute.UID);
2138
                                if (mapping != null && !string.IsNullOrEmpty(attribute.VALUE) && attribute.VALUE != "None")
2139
                                {
2140
                                    LMAAttribute _LMAAttribute = _LMModelItem.Attributes[mapping.SPPIDATTRIBUTENAME];
2141
                                    if (_LMAAttribute != null)
2142
                                    {
2143
                                        if (DBNull.Value.Equals(_LMAAttribute.get_Value()))
2144
                                            _LMAAttribute.set_Value(attribute.VALUE);
2145
                                        else if (_LMAAttribute.get_Value() != attribute.VALUE)
2146
                                            _LMAAttribute.set_Value(attribute.VALUE);
2147
                                    }
2148
                                }
2149
                            }
2150
                            _LMModelItem.Commit();
2151
                        }
2152
                        if (_LMModelItem != null)
2153
                            ReleaseCOMObjects(_LMModelItem);
2154
                        if (_LMSymbol != null)
2155
                            ReleaseCOMObjects(_LMSymbol);
2156
                    }
2157
                    else if (item.GetType() == typeof(Line))
2158
                    {
2159
                        Line line = item as Line;
2160
                        if (line != null)
2161
                        {
2162
                            LMModelItem _LMModelItem = dataSource.GetModelItem(line.SPPID.ModelItemId);
2163
                            if (_LMModelItem != null && _LMModelItem.get_ItemStatus() == "Active")
2164
                            {
2165
                                foreach (var attribute in lineNumber.ATTRIBUTES)
2166
                                {
2167
                                    LineNumberMapping mapping = document.LineNumberMappings.Find(x => x.UID == attribute.UID);
2168
                                    if (mapping != null && !string.IsNullOrEmpty(attribute.VALUE) && attribute.VALUE != "None")
2169
                                    {
2170
                                        LMAAttribute _LMAAttribute = _LMModelItem.Attributes[mapping.SPPIDATTRIBUTENAME];
2171
                                        if (_LMAAttribute != null)
2172
                                        {
2173
                                            if (DBNull.Value.Equals(_LMAAttribute.get_Value()))
2174
                                                _LMAAttribute.set_Value(attribute.VALUE);
2175
                                            else if (_LMAAttribute.get_Value() != attribute.VALUE)
2176
                                                _LMAAttribute.set_Value(attribute.VALUE);
2177
                                            
2178
                                        }
2179
                                    }
2180
                                }
2181
                                _LMModelItem.Commit();
2182
                            }
2183
                            if (_LMModelItem != null)
2184
                                ReleaseCOMObjects(_LMModelItem);
2185
                        }
2186
                    }
2187
                }
2188
            }
2189

    
2190
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2191
        }
2192

    
2193
        /// <summary>
2194
        /// Symbol Attribute 입력 메서드
2195
        /// </summary>
2196
        /// <param name="item"></param>
2197
        private void InputSymbolAttribute(object targetItem, List<BaseModel.Attribute> targetAttributes)
2198
        {
2199
            try
2200
            {
2201
                // Object 아이템이 Symbol일 경우 Equipment일 경우 
2202
                string sRep = null;
2203
                if (targetItem.GetType() == typeof(Symbol))
2204
                    sRep = ((Symbol)targetItem).SPPID.RepresentationId;
2205
                else if (targetItem.GetType() == typeof(Equipment))
2206
                    sRep = ((Equipment)targetItem).SPPID.RepresentationId;
2207
                    
2208
                if (!string.IsNullOrEmpty(sRep))
2209
                {
2210
                    LMSymbol _LMSymbol = dataSource.GetSymbol(sRep);
2211
                    LMModelItem _LMModelItem = _LMSymbol.ModelItemObject;
2212
                    LMAAttributes _Attributes = _LMModelItem.Attributes;
2213

    
2214
                    foreach (var item in targetAttributes)
2215
                    {
2216
                        AttributeMapping mapping = document.AttributeMappings.Find(x => x.UID == item.UID);
2217
                        if (mapping != null && !string.IsNullOrEmpty(item.VALUE) && item.VALUE != "None")
2218
                        {
2219
                            LMAAttribute _Attribute = _Attributes[mapping.SPPIDATTRIBUTENAME];
2220
                            if (_Attribute != null)
2221
                                _Attribute.set_Value(item.VALUE);
2222
                        }
2223
                    }
2224
                    _LMModelItem.Commit();
2225
                    
2226
                    ReleaseCOMObjects(_Attributes);
2227
                    ReleaseCOMObjects(_LMModelItem);
2228
                    ReleaseCOMObjects(_LMSymbol);
2229
                }
2230
            }
2231
            catch (Exception ex)
2232
            {
2233
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
2234
            }
2235

    
2236
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2237
        }
2238

    
2239
        /// <summary>
2240
        /// Text Modeling - Association일 경우는 Text대신 해당 맵핑된 Symbol로 모델링
2241
        /// </summary>
2242
        /// <param name="text"></param>
2243
        private void TextModeling(Text text)
2244
        {
2245
            LMSymbol _LMSymbol = null;
2246
            try
2247
            {
2248
                //if (text.ASSOCIATION && !string.IsNullOrEmpty(text.OWNER) && text.OWNER != "None")
2249
                if (text.ASSOCIATION)
2250
                {
2251
                    object owner = SPPIDUtil.FindObjectByUID(document, text.OWNER);
2252
                    if (owner.GetType() == typeof(Symbol))
2253
                    {
2254
                        Symbol symbol = owner as Symbol;
2255
                        _LMSymbol = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
2256
                        if (_LMSymbol != null)
2257
                        {
2258
                            Association association = symbol.ASSOCIATIONS.Find(x => x.VALUE == text.UID);
2259
                            List<BaseModel.Attribute> attributes = symbol.ATTRIBUTES.FindAll(x => x.ATTRIBUTETYPE == association.TYPE);
2260
                            AttributeMapping mapping = null;
2261
                            foreach (var attribute in attributes)
2262
                            {
2263
                                if (string.IsNullOrEmpty(attribute.VALUE) || attribute.VALUE == "None")
2264
                                    continue;
2265

    
2266
                                 mapping = document.AttributeMappings.Find(x => x.UID == attribute.UID && !string.IsNullOrEmpty(x.SPPIDSYMBOLNAME));
2267
                                if (mapping != null)
2268
                                    break;  
2269
                            }
2270

    
2271
                            if (mapping != null)
2272
                            {
2273
                                double x = 0;
2274
                                double y = 0;
2275

    
2276
                                CalcLabelLocation(ref x, ref y, text.SPPID.ORIGINAL_X, text.SPPID.ORIGINAL_Y, text.SPPIDLabelLocation, mapping.Location);
2277
                                Array array = new double[] { 0, x, y };
2278

    
2279
                                LMLabelPersist _LMLabelPersist = _placement.PIDPlaceLabel(mapping.SPPIDSYMBOLNAME, ref array, Rotation: text.ANGLE, LabeledItem: _LMSymbol.AsLMRepresentation(), IsLeaderVisible: mapping.LeaderLine);
2280
                                if (_LMLabelPersist!=null)
2281
                                {
2282
                                    _LMLabelPersist.Commit();
2283
                                    ReleaseCOMObjects(_LMLabelPersist);
2284
                                }
2285
                            }
2286
                        }
2287
                    }
2288
                    else if (owner.GetType() == typeof(Line))
2289
                    {
2290

    
2291
                    }
2292
                }
2293
                else
2294
                {
2295
                    LMItemNote _LMItemNote = null;
2296
                    LMAAttribute _LMAAttribute = null;
2297

    
2298
                    double x = 0;
2299
                    double y = 0;
2300

    
2301
                    CalcLabelLocation(ref x, ref y, text.SPPID.ORIGINAL_X, text.SPPID.ORIGINAL_Y, text.SPPIDLabelLocation, _ETCSetting.TextLocation);
2302

    
2303
                    _LMSymbol = _placement.PIDPlaceSymbol(text.SPPID.MAPPINGNAME, x, y);
2304
                    _LMSymbol.Commit();
2305
                    _LMItemNote = _placement.PIDDataSource.GetItemNote(_LMSymbol.ModelItemID);
2306
                    _LMItemNote.Commit();
2307
                    _LMAAttribute = _LMItemNote.Attributes["Note.Body"];
2308
                    _LMAAttribute.set_Value(text.VALUE);
2309
                    _LMItemNote.Commit();
2310

    
2311
                    if (_LMAAttribute != null)
2312
                        ReleaseCOMObjects(_LMAAttribute);
2313
                    if (_LMItemNote != null)
2314
                        ReleaseCOMObjects(_LMItemNote);
2315
                }
2316
            }
2317
            catch (Exception ex)
2318
            {
2319

    
2320
            }
2321
            finally
2322
            {
2323
                if (_LMSymbol != null)
2324
                    ReleaseCOMObjects(_LMSymbol);
2325
            }
2326

    
2327
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2328
        }
2329

    
2330
        /// <summary>
2331
        /// Note Modeling
2332
        /// </summary>
2333
        /// <param name="note"></param>
2334
        private void NoteModeling(Note note)
2335
        {
2336
            LMSymbol _LMSymbol = null;
2337
            LMItemNote _LMItemNote = null;
2338
            LMAAttribute _LMAAttribute = null;
2339

    
2340
            try
2341
            {
2342
                double x = 0;
2343
                double y = 0;
2344

    
2345
                CalcLabelLocation(ref x, ref y, note.SPPID.ORIGINAL_X, note.SPPID.ORIGINAL_Y, note.SPPIDLabelLocation, _ETCSetting.NoteLocation);
2346

    
2347
                _LMSymbol = _placement.PIDPlaceSymbol(note.SPPID.MAPPINGNAME, x, y);
2348
                _LMSymbol.Commit();
2349
                _LMItemNote = _placement.PIDDataSource.GetItemNote(_LMSymbol.ModelItemID);
2350
                _LMItemNote.Commit();
2351
                _LMAAttribute = _LMItemNote.Attributes["Note.Body"];
2352
                _LMAAttribute.set_Value(note.VALUE);
2353
                _LMItemNote.Commit();
2354
            }
2355
            catch (Exception ex)
2356
            {
2357

    
2358
            }
2359
            finally
2360
            {
2361
                if (_LMAAttribute != null)
2362
                    ReleaseCOMObjects(_LMAAttribute);
2363
                if (_LMItemNote != null)
2364
                    ReleaseCOMObjects(_LMItemNote);
2365
                if (_LMSymbol != null)
2366
                    ReleaseCOMObjects(_LMSymbol);
2367
            }
2368

    
2369
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2370
        }
2371

    
2372
        /// <summary>
2373
        /// Label의 좌표를 구하는 메서드(ID2 기준의 좌표 -> SPPID 좌표)
2374
        /// </summary>
2375
        /// <param name="x"></param>
2376
        /// <param name="y"></param>
2377
        /// <param name="originX"></param>
2378
        /// <param name="originY"></param>
2379
        /// <param name="SPPIDLabelLocation"></param>
2380
        /// <param name="location"></param>
2381
        private void CalcLabelLocation(ref double x, ref double y, double originX, double originY, SPPIDLabelLocationInfo SPPIDLabelLocation, Location location)
2382
        {
2383
            if (location == Location.None)
2384
            {
2385
                x = originX;
2386
                y = originY;
2387
            }
2388
            else
2389
            {
2390
                if (location.HasFlag(Location.Center))
2391
                {
2392
                    x = (SPPIDLabelLocation.X1 + SPPIDLabelLocation.X2) / 2;
2393
                    y = (SPPIDLabelLocation.Y1 + SPPIDLabelLocation.Y2) / 2;
2394
                }
2395

    
2396
                if (location.HasFlag(Location.Left))
2397
                    x = SPPIDLabelLocation.X1;
2398
                else if (location.HasFlag(Location.Right))
2399
                    x = SPPIDLabelLocation.X2;
2400

    
2401
                if (location.HasFlag(Location.Down))
2402
                    y = SPPIDLabelLocation.Y1;
2403
                else if (location.HasFlag(Location.Up))
2404
                    y = SPPIDLabelLocation.Y2;
2405
            }
2406
        }
2407

    
2408
        /// <summary>
2409
        /// Graphic OID로 해당 Symbol의 크기를 구하여 Zoom
2410
        /// </summary>
2411
        /// <param name="graphicOID"></param>
2412
        /// <param name="milliseconds"></param>
2413
        private void ZoomObjectByGraphicOID(string graphicOID, int milliseconds = 150)
2414
        {
2415
            if (radApp.ActiveDocument.ActiveSheet.DrawingObjects[graphicOID] != null)
2416
            {
2417
                double minX = 0;
2418
                double minY = 0;
2419
                double maxX = 0;
2420
                double maxY = 0;
2421
                radApp.ActiveDocument.ActiveSheet.DrawingObjects[graphicOID].Range(out minX, out minY, out maxX, out maxY);
2422
                radApp.ActiveWindow.ZoomArea2(minX - 0.007, minY - 0.007, maxX + 0.007, maxY + 0.007, null);
2423

    
2424
                Thread.Sleep(milliseconds);
2425
            }
2426
        }
2427

    
2428
        /// <summary>
2429
        /// ComObject를 Release
2430
        /// </summary>
2431
        /// <param name="objVars"></param>
2432
        public void ReleaseCOMObjects(params object[] objVars)
2433
        {
2434
            int intNewRefCount = 0;
2435
            foreach (object obj in objVars)
2436
            {
2437
                if (!Information.IsNothing(obj) && System.Runtime.InteropServices.Marshal.IsComObject(obj))
2438
                    intNewRefCount = intNewRefCount + System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj);
2439
            }
2440
        }
2441
    }
2442
}
클립보드 이미지 추가 (최대 크기: 500 MB)