프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / SPPIDConverter / AutoModeling.cs @ 6a7573b0

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

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

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

    
38
        public string DocumentLabelText { get; set; }
39

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

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

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

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

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

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

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

    
96
                CreateDocument();
97

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

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

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

    
111
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Priority Symbol Modeling");
112
                    List<Symbol> prioritySymbols = GetPrioritySymbol();
113
                    foreach (var item in prioritySymbols)
114
                        SymbolModelingByPriority(item);
115

    
116
                    // Equipment Modeling
117
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Equipments Modeling");
118
                    foreach (Equipment equipment in document.Equipments)
119
                        EquipmentModeling(equipment);
120

    
121
                    // LineRun Symbol Modeling
122
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Symbols Modeling");
123
                    foreach (LineNumber lineNumber in document.LINENUMBERS)
124
                        foreach (LineRun run in lineNumber.RUNS)
125
                            SymbolModelingByRun(run);
126
                    // TrimLineRun Symbol Modeling
127
                    foreach (TrimLine trimLine in document.TRIMLINES)
128
                        foreach (LineRun run in trimLine.RUNS)
129
                            SymbolModelingByRun(run);
130

    
131
                    // LineRun Line Modeling
132
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Lines Modeling");
133
                    foreach (LineNumber lineNumber in document.LINENUMBERS)
134
                        foreach (LineRun run in lineNumber.RUNS)
135
                            LineModelingByRun(run);
136
                    // TrimLineRun Line Modeling
137
                    foreach (TrimLine trimLine in document.TRIMLINES)
138
                        foreach (LineRun run in trimLine.RUNS)
139
                            LineModelingByRun(run);
140

    
141
                    // Branch Line Modeling
142
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Branch Lines Modeling");
143
                    foreach (var item in BranchLines)
144
                        BranchLineModeling(item);
145

    
146
                    // EndBreak Modeling
147
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "EndBreaks Modeling");
148
                    foreach (var item in document.EndBreaks)
149
                        EndBreakModeling(item);
150

    
151
                    // LineNumber Modeling
152
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "LineNumbers Modeling");
153
                    foreach (var item in document.LINENUMBERS)
154
                        LineNumberModeling(item);
155

    
156
                    // LineNumber Modeling
157
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Flow Mark Modeling");
158
                    foreach (var item in document.LINES)
159
                        FlowMarkModeling(item);
160

    
161
                    // Note Modeling
162
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Notes Modeling");
163
                    foreach (var item in document.NOTES)
164
                        NoteModeling(item);
165

    
166
                    // Text Modeling
167
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Texts Modeling");
168
                    foreach (var item in document.TEXTINFOS)
169
                        TextModeling(item);
170

    
171
                    // LineRun Line Join
172
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Join LineRuns");
173
                    foreach (LineNumber lineNumber in document.LINENUMBERS)
174
                        foreach (LineRun run in lineNumber.RUNS)
175
                            JoinRunLine(run);
176
                    // TrimLineRun Line Join
177
                    foreach (TrimLine trimLine in document.TRIMLINES)
178
                        foreach (LineRun run in trimLine.RUNS)
179
                            JoinRunLine(run);
180

    
181
                    // Input LineNumber Attribute
182
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Set Lines Attribute");
183
                    foreach (var item in document.LINENUMBERS)
184
                        InputLineNumberAttribute(item);
185

    
186
                    // Input Symbol Attribute
187
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Set Symbols Attribute");
188
                    foreach (var item in document.SYMBOLS)
189
                        InputSymbolAttribute(item, item.ATTRIBUTES);
190

    
191
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Labels Modeling");
192
                    foreach (var item in document.SYMBOLS)
193
                        LabelSymbolModeling(item);
194

    
195
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, AllCount);
196
                }
197
            }
198
            catch (Exception ex)
199
            {
200
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
201
            }
202
            finally
203
            {
204
                application.ActiveWindow.Fit();
205

    
206
                if (radApp.ActiveDocument != null)
207
                {
208
                    //radApp.ActiveDocument.Save();
209
                    //radApp.ActiveDocument.SaveOnClose = false;
210
                    //radApp.ActiveDocument.Close(false);
211

    
212
                    ReleaseCOMObjects(newDrawing);
213
                }
214

    
215
                ReleaseCOMObjects(dataSource);
216
                ReleaseCOMObjects(_placement);
217

    
218
                //SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.ClearParent, null);
219
                SplashScreenManager.CloseForm(false);
220
            }
221
        }
222

    
223
        /// <summary>
224
        /// 도면 생성 메서드
225
        /// </summary>
226
        private void CreateDocument()
227
        {
228
            string drawingName = document.DrawingName;
229
            string drawingNumber = document.DrawingNumber;
230

    
231
            GetDrawingNameAndNumber(ref drawingName, ref drawingNumber);
232

    
233
            newDrawing = application.Drawings.Add(document.Unit, document.Template, drawingNumber, drawingName);
234
            application.ActiveWindow.Fit();
235
            Thread.Sleep(1000);
236
            application.ActiveWindow.Zoom = 2000;
237
            Thread.Sleep(2000);
238

    
239
            
240
        }
241

    
242
        private void GetDrawingNameAndNumber(ref string drawingName, ref string drawingNumber)
243
        {
244
            LMDrawings drawings = new LMDrawings();
245
            drawings.Collect(dataSource);
246

    
247
            List<string> drawingNameList = new List<string>();
248
            List<string> drawingNumberList = new List<string>();
249

    
250
            foreach (LMDrawing item in drawings)
251
            {
252
                drawingNameList.Add(item.Attributes["Name"].get_Value().ToString());
253
                drawingNumberList.Add(item.Attributes["DrawingNumber"].get_Value().ToString());
254
            }
255

    
256
            int nameLength = drawingName.Length;
257
            while (drawingNameList.Contains(drawingName))
258
            {
259
                if (nameLength == drawingName.Length)
260
                    drawingName += "-1";
261
                else
262
                {
263
                    int index = Convert.ToInt32(drawingName.Remove(0, nameLength + 1));
264
                    drawingName = drawingName.Substring(0, nameLength + 1);
265
                    drawingName += ++index;
266
                }
267
            }
268

    
269
            int numberLength = drawingNumber.Length;
270
            while (drawingNameList.Contains(drawingNumber))
271
            {
272
                if (numberLength == drawingNumber.Length)
273
                    drawingNumber += "-1";
274
                else
275
                {
276
                    int index = Convert.ToInt32(drawingNumber.Remove(0, numberLength + 1));
277
                    drawingNumber = drawingNumber.Substring(0, numberLength + 1);
278
                    drawingNumber += ++index;
279
                }
280
            }
281

    
282
            ReleaseCOMObjects(drawings);
283
        }
284

    
285
        /// <summary>
286
        /// 도면 크기 구하는 메서드
287
        /// </summary>
288
        /// <returns></returns>
289
        private bool DocumentCoordinateCorrection()
290
        {
291
            if (Settings.Default.DrawingX != 0 && Settings.Default.DrawingY != 0)
292
            {
293
                document.SetSPPIDLocation(Settings.Default.DrawingX, Settings.Default.DrawingY);
294
                document.CoordinateCorrection();
295
                return true;
296
            }
297
            else
298
                return false;
299
        }
300

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

    
332
                    prevLine = line;
333

    
334
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
335
                }
336
                // Symbol 일 경우
337
                else if (item.GetType() == typeof(Symbol))
338
                {
339
                    if (lines.Count > 0)
340
                    {
341
                        LineModeling(lines);
342
                        lines.Clear();
343
                    }
344
                }
345
            }
346

    
347
            if (lines.Count > 0)
348
                LineModeling(lines);
349
        }
350

    
351
        /// <summary>
352
        /// 심볼을 Run 단위로 모델링하는 진입 메서드
353
        /// </summary>
354
        /// <param name="run"></param>
355
        private void SymbolModelingByRun(LineRun run)
356
        {
357
            // 양끝 Symbol 검사 후 Line이 나올때까지만 Symbol Modeling
358
            if (run.RUNITEMS.Count > 0)
359
            {
360
                if (run.RUNITEMS[0].GetType() == typeof(Symbol))
361
                    SymbolModelingByRunStart(run.RUNITEMS[0] as Symbol, run);
362

    
363
                if (run.RUNITEMS[run.RUNITEMS.Count - 1].GetType() == typeof(Symbol))
364
                    SymbolModelingByRunEnd(run.RUNITEMS[run.RUNITEMS.Count - 1] as Symbol, run);
365
            }
366

    
367
            Symbol targetSymbol = null;
368
            foreach (var item in run.RUNITEMS)
369
            {
370
                if (item.GetType() == typeof(Symbol))
371
                {
372
                    Symbol symbol = item as Symbol;
373
                    SymbolModeling(symbol, targetSymbol);
374
                    targetSymbol = symbol;
375
                }
376
                else
377
                {
378
                    targetSymbol = null;
379
                }
380
            }
381
        }
382

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

    
410

    
411
        }
412

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

    
441
        /// <summary>
442
        /// 심볼을 실제로 Modeling 메서드
443
        /// </summary>
444
        /// <param name="symbol"></param>
445
        /// <param name="targetSymbol"></param>
446
        /// <param name="prevSymbol"></param>
447
        private void SymbolModeling(Symbol symbol, Symbol targetSymbol)
448
        {
449
#if DEBUG
450
            try
451
            {
452
#endif
453
                // OWNERSYMBOL Attribute, 값을 가지고 있을 경우
454
                BaseModel.Attribute itemAttribute = symbol.ATTRIBUTES.Find(attr => attr.ATTRIBUTE == "OWNERSYMBOL");
455
                if (itemAttribute != null && string.IsNullOrEmpty(itemAttribute.VALUE) && itemAttribute.VALUE != "None")
456
                    return;
457
                // 이미 모델링 됐을 경우
458
                else if (!string.IsNullOrEmpty(symbol.SPPID.RepresentationId))
459
                    return;
460

    
461
                LMSymbol _LMSymbol = null;
462

    
463
                string mappingPath = symbol.SPPID.MAPPINGNAME;
464
                double x = symbol.SPPID.ORIGINAL_X;
465
                double y = symbol.SPPID.ORIGINAL_Y;
466
                int mirror = 0;
467
                double angle = symbol.ANGLE;
468

    
469
                SPPIDUtil.ConvertGridPoint(ref x, ref y);
470

    
471
                // OPC 일경우 180도 일때 Mirror
472
                if (mappingPath.Contains("Piping OPC's") && angle == Math.PI)
473
                    mirror = 1;
474

    
475
                // Mirror 계산
476
                if (symbol.FLIP == 1)
477
                {
478
                    mirror = 1;
479
                    angle += Math.PI;
480
                }
481

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

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

    
495

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

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

    
506
                ReleaseCOMObjects(_LMSymbol);
507
                SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
508
#if DEBUG
509

    
510
            }
511
            catch (Exception ex)
512
            {
513
                System.Windows.Forms.MessageBox.Show(ex.StackTrace);
514
            }
515
#endif
516
        }
517

    
518
        /// <summary>
519
        /// ID2의 Symbol Width와 Height를 비교해서 상대적인 SPPID Connector좌표를 가져온다.
520
        /// </summary>
521
        /// <param name="targetConnector"></param>
522
        /// <param name="targetSymbol"></param>
523
        /// <param name="x"></param>
524
        /// <param name="y"></param>
525
        private void GetTargetSymbolConnectorPoint(Connector targetConnector, Symbol targetSymbol, ref double x, ref double y)
526
        {
527
            LMSymbol _TargetItem = dataSource.GetSymbol(targetSymbol.SPPID.RepresentationId);
528

    
529
            double[] range = null;
530
            List<double[]> points = new List<double[]>();
531
            GetSPPIDSymbolRangeAndConnectionPoints(targetSymbol, ref range, points);
532
            double x1 = range[0];
533
            double y1 = range[1];
534
            double x2 = range[2];
535
            double y2 = range[3];
536

    
537
            // Origin 기준 Connector의 위치차이
538
            double sceneX = 0;
539
            double sceneY = 0;
540
            SPPIDUtil.ConvertPointBystring(targetConnector.SCENECONNECTPOINT, ref sceneX, ref sceneY);
541
            double originX = 0;
542
            double originY = 0;
543
            SPPIDUtil.ConvertPointBystring(targetSymbol.ORIGINALPOINT, ref originX, ref originY);
544
            double gapX = originX - sceneX;
545
            double gapY = originY - sceneY;
546

    
547
            // SPPID Symbol과 ID2 심볼의 크기 차이
548
            double sizeWidth = 0;
549
            double sizeHeight = 0;
550
            SPPIDUtil.ConvertPointBystring(targetSymbol.SIZE, ref sizeWidth, ref sizeHeight);
551
            double percentX = (x2 - x1) / sizeWidth;
552
            double percentY = (y2 - y1) / sizeHeight;
553

    
554
            double SPPIDgapX = gapX * percentX;
555
            double SPPIDgapY = gapY * percentY;
556

    
557
            double[] SPPIDOriginPoint = new double[] { _TargetItem.get_XCoordinate() - SPPIDgapX, _TargetItem.get_YCoordinate() + SPPIDgapY };
558
            double distance = double.MaxValue;
559
            double[] resultPoint;
560
            foreach (var point in points)
561
            {
562
                double result = SPPIDUtil.CalcPointToPointdDistance(point[0], point[1], SPPIDOriginPoint[0], SPPIDOriginPoint[1]);
563
                if (distance > result)
564
                {
565
                    distance = result;
566
                    resultPoint = point;
567
                    x = point[0];
568
                    y = point[1];
569
                }
570
            }
571

    
572
            ReleaseCOMObjects(_TargetItem);
573
        }
574

    
575
        /// <summary>
576
        /// SPPID Symbol의 Range를 구한다.
577
        /// </summary>
578
        /// <param name="symbol"></param>
579
        /// <param name="range"></param>
580
        private void GetSPPIDSymbolRangeAndConnectionPoints(Symbol symbol, ref double[] range, List<double[]> points)
581
        {
582
            LMSymbol _TargetItem = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
583
            Ingr.RAD2D.Symbol2d symbol2d = radApp.ActiveDocument.ActiveSheet.DrawingObjects[_TargetItem.get_GraphicOID().ToString()];
584
            double x1 = 0;
585
            double y1 = 0;
586
            double x2 = 0;
587
            double y2 = 0;
588
            symbol2d.Range(out x1, out y1, out x2, out y2);
589
            range = new double[] { x1, y1, x2, y2 };
590

    
591
            for (int i = 1; i < int.MaxValue; i++)
592
            {
593
                double connX = 0;
594
                double connY = 0;
595
                if (_placement.PIDConnectPointLocation(_TargetItem, i, ref connX, ref connY))
596
                    points.Add(new double[] { connX, connY });
597
                else
598
                    break;
599
            }
600

    
601
            foreach (var childSymbol in symbol.ChildSymbols)
602
                GetSPPIDChildSymbolRange(childSymbol, ref range, points);
603

    
604
            ReleaseCOMObjects(_TargetItem);
605
        }
606

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

    
626
            for (int i = 1; i < int.MaxValue; i++)
627
            {
628
                double connX = 0;
629
                double connY = 0;
630
                if (_placement.PIDConnectPointLocation(_ChildSymbol, i, ref connX, ref connY))
631
                    points.Add(new double[] { connX, connY });
632
                else
633
                    break;
634
            }
635

    
636
            foreach (var loopChildSymbol in childSymbol.ChildSymbols)
637
                GetSPPIDChildSymbolRange(loopChildSymbol, ref range, points);
638

    
639
            ReleaseCOMObjects(_ChildSymbol);
640
        }
641

    
642
        /// <summary>
643
        /// Label Symbol Modeling
644
        /// </summary>
645
        /// <param name="symbol"></param>
646
        private void LabelSymbolModeling(Symbol symbol)
647
        {
648
            BaseModel.Attribute itemAttribute = symbol.ATTRIBUTES.Find(x => x.ATTRIBUTE == "OWNERSYMBOL");
649
            if (itemAttribute == null || string.IsNullOrEmpty(itemAttribute.VALUE))
650
                return;
651

    
652
            Array points = new double[] { 0, symbol.SPPID.ORIGINAL_X, symbol.SPPID.ORIGINAL_Y };
653
            
654
            string symbolUID = itemAttribute.VALUE;
655
            object targetItem = SPPIDUtil.FindObjectByUID(document, symbolUID);
656
            if (targetItem != null)
657
            {
658
                // Object 아이템이 Symbol일 경우 Equipment일 경우 
659
                string sRep = null;
660
                if (targetItem.GetType() == typeof(Symbol))
661
                    sRep = ((Symbol)targetItem).SPPID.RepresentationId;
662
                else if (targetItem.GetType() == typeof(Equipment))
663
                    sRep = ((Equipment)targetItem).SPPID.RepresentationId;
664

    
665
                if (!string.IsNullOrEmpty(sRep))
666
                {
667
                    // LEADER Line 검사
668
                    bool leaderLine = false;
669
                    SymbolMapping symbolMapping = document.SymbolMappings.Find(x => x.UID == symbol.DBUID);
670
                    if (symbolMapping != null)
671
                        leaderLine = symbolMapping.LEADERLINE;
672

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

    
677
                    //Leader 선 센터로
678
                    if (_LMLabelPresist != null)
679
                    {
680
                        // Target Item에 Label의 Attribute Input
681
                        InputSymbolAttribute(targetItem, symbol.ATTRIBUTES);
682

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

    
711
                                    if (result)
712
                                        break;
713
                                }
714

    
715
                                if (result)
716
                                    break;
717
                            }
718
                        }
719

    
720
                        _LMLabelPresist.Commit();
721
                    }
722
                    
723
                    ReleaseCOMObjects(_TargetItem);
724
                    ReleaseCOMObjects(_LMLabelPresist);
725
                }
726
            }
727

    
728
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
729
        }
730

    
731
        /// <summary>
732
        /// Equipment를 실제로 Modeling 메서드
733
        /// </summary>
734
        /// <param name="equipment"></param>
735
        private void EquipmentModeling(Equipment equipment)
736
        {
737
            if (!string.IsNullOrEmpty(equipment.SPPID.RepresentationId))
738
                return;
739

    
740
            LMSymbol _LMSymbol = null;
741
            LMSymbol targetItem = null;
742
            string mappingPath = equipment.SPPID.MAPPINGNAME;
743
            double x = equipment.SPPID.ORIGINAL_X;
744
            double y = equipment.SPPID.ORIGINAL_Y;
745
            int mirror = 0;
746
            double angle = equipment.ANGLE;
747

    
748
            SPPIDUtil.ConvertGridPoint(ref x, ref y);
749

    
750
            Connector connector = equipment.CONNECTORS.Find(conn => !string.IsNullOrEmpty(conn.CONNECTEDITEM) && conn.CONNECTEDITEM != "None");
751
            if (connector != null)
752
            {
753
                Equipment connEquipment = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM) as Equipment;
754
                if (connEquipment != null)
755
                {
756
                    if (string.IsNullOrEmpty(connEquipment.SPPID.RepresentationId))
757
                        EquipmentModeling(connEquipment);
758

    
759
                    if (!string.IsNullOrEmpty(connEquipment.SPPID.RepresentationId))
760
                    {
761
                        targetItem = dataSource.GetSymbol(connEquipment.SPPID.RepresentationId);
762
                        if (targetItem != null)
763
                        {
764
                            _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle, TargetItem: targetItem);
765
                        }
766
                        else
767
                        {
768
                            _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
769
                        }
770
                    }
771
                    else
772
                    {
773
                        _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
774
                    }
775
                }
776
                else
777
                {
778
                    _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
779
                }
780
            }
781
            else
782
            {
783
                _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
784
            }
785

    
786
            if (_LMSymbol != null)
787
            {
788
                _LMSymbol.Commit();
789
                equipment.SPPID.RepresentationId = _LMSymbol.AsLMRepresentation().Id;
790
                equipment.SPPID.GraphicOID = _LMSymbol.get_GraphicOID();
791
                ReleaseCOMObjects(_LMSymbol);
792
            }
793

    
794
            if (targetItem != null)
795
            {
796
                ReleaseCOMObjects(targetItem);
797
            }
798
            
799
            ReleaseCOMObjects(_LMSymbol);
800

    
801
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
802
        }
803

    
804
        private void SymbolModelingByPriority(Symbol symbol)
805
        {
806
            // Angle, Center, 우선순위 모델링
807
            SymbolModeling(symbol, null);
808
            List<Symbol> group = new List<Symbol>() { symbol };
809
            SPPIDUtil.FindConnectedSymbolGroup(document, symbol, group);
810

    
811
            List<Symbol> endModeling = new List<Symbol>() { symbol };
812
            while (endModeling.Count != group.Count)
813
            {
814
                foreach (var item in group)
815
                {
816
                    if (!endModeling.Contains(item))
817
                    {
818
                        bool result = false;
819
                        foreach (var connector in item.CONNECTORS)
820
                        {
821
                            Symbol connSymbol = group.Find(x => x.UID == connector.CONNECTEDITEM);
822
                            if (connSymbol == item)
823
                                throw new Exception(connSymbol.UID);
824

    
825
                            if (connSymbol != null && endModeling.Contains(connSymbol))
826
                            {
827
                                SymbolModeling(item, connSymbol);
828
                                endModeling.Add(item);
829
                                result = true;
830
                                break;
831
                            }
832
                        }
833

    
834
                        if (result)
835
                            break;
836
                    }
837
                }
838
            }
839
        }
840

    
841
        /// <summary>
842
        /// 심볼을 실제로 Modeling할때 ChildSymbol이 있다면 Modeling하는 메서드
843
        /// </summary>
844
        /// <param name="childSymbol"></param>
845
        /// <param name="parentSymbol"></param>
846
        private void CreateChildSymbol(ChildSymbol childSymbol, LMSymbol parentSymbol)
847
        {
848
            Ingr.RAD2D.Symbol2d symbol2d = radApp.ActiveDocument.ActiveSheet.DrawingObjects[parentSymbol.get_GraphicOID().ToString()];
849
            double x1 = 0;
850
            double x2 = 0;
851
            double y1 = 0;
852
            double y2 = 0;
853
            symbol2d.Range(out x1, out y1, out x2, out y2);
854

    
855
            LMSymbol _LMSymbol = _placement.PIDPlaceSymbol(childSymbol.SPPID.MAPPINGNAME, (x1 + x2) / 2, (y1 + y2) / 2, TargetItem: parentSymbol);
856
            if (_LMSymbol != null)
857
            {
858
                childSymbol.SPPID.RepresentationId = _LMSymbol.AsLMRepresentation().Id;
859
                foreach (var item in childSymbol.ChildSymbols)
860
                    CreateChildSymbol(item, _LMSymbol);
861
            }
862
            
863

    
864
            ReleaseCOMObjects(_LMSymbol);
865
        }
866

    
867
        /// <summary>
868
        /// item이 TargetItem과 같은 LineRun에 있는지 검사
869
        /// </summary>
870
        /// <param name="item"></param>
871
        /// <param name="targetItem"></param>
872
        /// <returns></returns>
873
        private bool IsSameLineRun(object item, object targetItem)
874
        {
875
            foreach (var lineNumber in document.LINENUMBERS)
876
            {
877
                foreach (var run in lineNumber.RUNS)
878
                {
879
                    foreach (var runItem in run.RUNITEMS)
880
                    {
881
                        if (runItem == item)
882
                        {
883
                            foreach (var findItem in run.RUNITEMS)
884
                            {
885
                                if (findItem == targetItem)
886
                                {
887
                                    return true;
888
                                }
889
                            }
890

    
891
                            return false;
892

    
893
                        }
894
                    }
895
                }
896
            }
897

    
898
            return false;
899
        }
900

    
901
        /// <summary>
902
        /// Line을 실제로 모델링하는 메서드
903
        /// </summary>
904
        /// <param name="lines"></param>
905
        private void LineModeling(List<Line> lines)
906
        {
907
            _LMAItem _LMAItem = _placement.PIDCreateItem(lines[0].SPPID.MAPPINGNAME);
908
            PlaceRunInputs placeRunInputs = new PlaceRunInputs();
909
            LMSymbol _LMSymbol1 = null;
910
            LMSymbol _LMSymbol2 = null;
911
            Dictionary<LMConnector, List<double[]>> connectorVertices1 = new Dictionary<LMConnector, List<double[]>>();
912
            LMConnector targetConnector1 = null;
913
            Dictionary<LMConnector, List<double[]>> connectorVertices2 = new Dictionary<LMConnector, List<double[]>>();
914
            LMConnector targetConnector2 = null;
915

    
916
            Line startBranchLine = null;
917
            Line endBranchLine = null;
918

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

    
945
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("SYMBOL", line, _LMSymbol1, x, y));
946
                        }
947
                        else
948
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.START_X, line.SPPID.START_Y));
949
                    }
950
                    else if (connItem != null && connItem.GetType() == typeof(Line) && !lines.Contains(connItem))
951
                    {
952
                        connectorVertices1 = GetPipeRunVertices(((Line)connItem).SPPID.ModelItemId);
953
                        targetConnector1 = FindTargetLMConnector(connectorVertices1, line.SPPID.START_X, line.SPPID.START_Y, line.SPPID.END_X, line.SPPID.END_Y);
954

    
955
                        if (targetConnector1 != null)
956
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("LINE", line, targetConnector1, line.SPPID.START_X, line.SPPID.START_Y));
957
                        else
958
                        {
959
                            startBranchLine = connItem as Line;
960
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.START_X, line.SPPID.START_Y));
961
                        }
962
                    }
963
                    else
964
                        linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.START_X, line.SPPID.START_Y));
965
                        
966
                }
967
                if (i + 1 == lines.Count)
968
                {
969
                    // 끝점에 연결된 Symbol 찾기
970
                    object connItem = SPPIDUtil.FindObjectByUID(document, line.CONNECTORS[1].CONNECTEDITEM);
971

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

    
975
                    if (connItem != null && connItem.GetType() == typeof(Symbol))
976
                    {
977
                        Symbol symbol2 = connItem as Symbol;
978
                        _LMSymbol2 = GetTargetSymbol(connItem as Symbol, line);
979
                        if (_LMSymbol2 != null)
980
                        {
981
                            double x = line.SPPID.END_X;
982
                            double y = line.SPPID.END_Y;
983
                            Connector connector = SPPIDUtil.FindSymbolConnectorByUID(document, line.UID, symbol2);
984
                            if (connector != null)
985
                            {
986
                                GetTargetSymbolConnectorPoint(connector, symbol2, ref x, ref y);
987
                                line.SPPID.END_X = x;
988
                                line.SPPID.END_Y = y;
989
                            }
990

    
991
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("SYMBOL", line, _LMSymbol2, x, y));
992
                        }
993
                        else
994
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.END_X, line.SPPID.END_Y));
995
                    }
996
                    else if (connItem != null && connItem.GetType() == typeof(Line) && !lines.Contains(connItem))
997
                    {
998
                        connectorVertices2 = GetPipeRunVertices(((Line)connItem).SPPID.ModelItemId);
999
                        targetConnector2 = FindTargetLMConnector(connectorVertices2, line.SPPID.END_X, line.SPPID.END_Y, line.SPPID.START_X, line.SPPID.START_Y);
1000

    
1001
                        if (targetConnector2 != null)
1002
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("LINE", line, targetConnector2, line.SPPID.END_X, line.SPPID.END_Y));
1003
                        else
1004
                        {
1005
                            endBranchLine = connItem as Line;
1006
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.END_X, line.SPPID.END_Y));
1007
                        }
1008
                    }
1009
                    else
1010
                        linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.END_X, line.SPPID.END_Y));
1011
                }
1012
            }
1013

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

    
1046
                        // 마지막이 Symbol일 경우는 Symbol의 좌표를 따라감
1047
                        if (i + 1 == linePointInfo.Count - 1 && linePointInfo[i + 1].Item1 == "SYMBOL")
1048
                        {
1049
                            Line nextLine = linePointInfo[i + 1].Item2;
1050
                            SlopeType nextSlopeType = SPPIDUtil.CalcSlope(nextLine.SPPID.START_X, nextLine.SPPID.START_Y, nextLine.SPPID.END_X, nextLine.SPPID.END_Y);
1051
                            if (slopeType == SlopeType.HORIZONTAL)
1052
                                y = linePointInfo[i + 1].Item5;
1053
                            else if (slopeType == SlopeType.VERTICAL)
1054
                                x = linePointInfo[i + 1].Item4;
1055
                        }
1056
                    }
1057

    
1058
                    if (item.Item1 == "LINE")
1059
                        placeRunInputs.AddConnectorTarget(item.Item3 as LMConnector, x, y);
1060
                    else
1061
                        placeRunInputs.AddPoint(x, y);
1062
                }
1063

    
1064
                prevX = x;
1065
                prevY = y;
1066
                prevSlopeType = slopeType;
1067
            }
1068

    
1069
            LMConnector _lMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1070

    
1071
            if (_lMConnector != null)
1072
            {
1073
                foreach (var line in lines)
1074
                    line.SPPID.ModelItemId = _lMConnector.ModelItemID;
1075
                _lMConnector.Commit();
1076
                if (startBranchLine != null || endBranchLine != null)
1077
                    BranchLines.Add(new Tuple<string, Line, Line>(_lMConnector.ModelItemID, startBranchLine, endBranchLine));
1078
            }
1079

    
1080
            if (_LMSymbol1 != null)
1081
                ReleaseCOMObjects(_LMSymbol1);
1082
            if (_LMSymbol2 != null)
1083
                ReleaseCOMObjects(_LMSymbol2);
1084
            if (targetConnector1 != null)
1085
                ReleaseCOMObjects(targetConnector1);
1086
            if (targetConnector2 != null)
1087
                ReleaseCOMObjects(targetConnector2);
1088
            foreach (var item in connectorVertices1)
1089
                ReleaseCOMObjects(item.Key);
1090
            foreach (var item in connectorVertices2)
1091
                ReleaseCOMObjects(item.Key);
1092

    
1093
            ReleaseCOMObjects(_lMConnector);
1094
            ReleaseCOMObjects(placeRunInputs);
1095
            ReleaseCOMObjects(_LMAItem);
1096
        }
1097

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

    
1123
                            if (child != null)
1124
                                break;
1125
                        }
1126

    
1127
                        if (child != null)
1128
                            _LMSymbol = dataSource.GetSymbol(child.SPPID.RepresentationId);
1129
                    }
1130

    
1131
                    break;  
1132
                }
1133
            }
1134

    
1135
            return _LMSymbol;
1136
        }
1137

    
1138
        /// <summary>
1139
        /// Connector를 가지고 있는 ChildSymbol Object 반환
1140
        /// </summary>
1141
        /// <param name="item"></param>
1142
        /// <param name="connector"></param>
1143
        /// <returns></returns>
1144
        private ChildSymbol GetChildSymbolByConnector(ChildSymbol item, Connector connector)
1145
        {
1146
            foreach (var childSymbol in item.ChildSymbols)
1147
            {
1148
                if (childSymbol.Connectors.Contains(connector))
1149
                    return childSymbol;
1150
                else
1151
                    return GetChildSymbolByConnector(childSymbol, connector);
1152
            }
1153

    
1154
            return null;
1155
        }
1156

    
1157
        /// <summary>
1158
        /// Branch 라인을 다시 모델링하는 진입 메서드
1159
        /// </summary>
1160
        /// <param name="branch"></param>
1161
        private void BranchLineModeling(Tuple<string, Line, Line> branch)
1162
        {
1163
            List<Line> lines = SPPIDUtil.FindLinesByModelId(document, branch.Item1);
1164

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

    
1167
            LMConnector _StartConnector = null;
1168
            LMConnector _EndConnector = null;
1169
            double lengthStart = double.MaxValue;
1170
            double lengthEnd = double.MaxValue;
1171
            List<double[]> startPoints = new List<double[]>();
1172
            List<double[]> endPoints = new List<double[]>();
1173

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

    
1209
                _LMAItem _LMAItem = _placement.PIDCreateItem(lines[0].SPPID.MAPPINGNAME);
1210
                PlaceRunInputs placeRunInputs = new PlaceRunInputs();
1211

    
1212
                Dictionary<LMConnector, List<double[]>> startConnectorVertices = GetPipeRunVertices(branch.Item2.SPPID.ModelItemId);
1213
                LMConnector _StartTargetConnector = FindTargetLMConnector(startConnectorVertices, startPoints[0][0], startPoints[0][1], startPoints[1][0], startPoints[1][1]);
1214
                Dictionary<LMConnector, List<double[]>> endConnectorVertices = GetPipeRunVertices(branch.Item3.SPPID.ModelItemId);
1215
                LMConnector _EndTargetConnector = FindTargetLMConnector(endConnectorVertices,
1216
                   startPoints[startPoints.Count - 1][0],
1217
                   startPoints[startPoints.Count - 1][1],
1218
                   startPoints[startPoints.Count - 2][0],
1219
                   startPoints[startPoints.Count - 2][1]);
1220

    
1221
                for (int i = 0; i < startPoints.Count; i++)
1222
                {
1223
                    double[] point = startPoints[i];
1224
                    if (i == 0)
1225
                        placeRunInputs.AddConnectorTarget(_StartTargetConnector, point[0], point[1]);
1226
                    else if (i == startPoints.Count - 1)
1227
                        placeRunInputs.AddConnectorTarget(_EndTargetConnector, point[0], point[1]);
1228
                    else
1229
                        placeRunInputs.AddPoint(point[0], point[1]);
1230
                }
1231

    
1232
                LMConnector _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1233
                if (_LMConnector != null)
1234
                {
1235
                    _LMConnector.Commit();
1236
                    foreach (var item in lines)
1237
                        item.SPPID.ModelItemId = _LMConnector.ModelItemID;
1238
                }
1239

    
1240
                foreach (var item in startConnectorVertices)
1241
                    ReleaseCOMObjects(item.Key);
1242
                foreach (var item in endConnectorVertices)
1243
                    ReleaseCOMObjects(item.Key);
1244
                ReleaseCOMObjects(placeRunInputs);
1245
                ReleaseCOMObjects(_LMAItem);
1246
                ReleaseCOMObjects(_LMConnector);
1247
            }
1248
            #endregion
1249
            #region 양쪽이 다른 Branch 
1250
            else
1251
            {
1252
                // Branch 시작 Connector
1253
                if (_StartConnector != null)
1254
                    BranchLineModelingByConnector(branch, _StartConnector, startPoints, true);
1255

    
1256
                // Branch 끝 Connector
1257
                if (_EndConnector != null)
1258
                    BranchLineModelingByConnector(branch, _EndConnector, endPoints, false);
1259
            }
1260
            #endregion
1261

    
1262
            if (_StartConnector != null)
1263
                ReleaseCOMObjects(_StartConnector);
1264
            if (_EndConnector != null)
1265
                ReleaseCOMObjects(_EndConnector);
1266
            foreach (var item in connectorVertices)
1267
                ReleaseCOMObjects(item.Key);
1268
        }
1269

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

    
1287
            // 같은 Line Run의 Connector 찾기
1288
            foreach (var item in connectorVertices)
1289
            {
1290
                if (item.Key == _Connector)
1291
                    continue;
1292

    
1293
                if (IsStart &&
1294
                    !DBNull.Value.Equals(item.Key.ConnectItem1SymbolID) &&
1295
                    !DBNull.Value.Equals(_Connector.ConnectItem2SymbolID)&& 
1296
                    item.Key.ConnectItem1SymbolID == _Connector.ConnectItem2SymbolID)
1297
                {
1298
                    _SameRunTargetConnector = item.Key;
1299
                    break;
1300
                }
1301
                else if (!IsStart &&
1302
                    !DBNull.Value.Equals(item.Key.ConnectItem2SymbolID) &&
1303
                    !DBNull.Value.Equals(_Connector.ConnectItem1SymbolID) && 
1304
                    item.Key.ConnectItem2SymbolID == _Connector.ConnectItem1SymbolID)
1305
                {
1306
                    _SameRunTargetConnector = item.Key;
1307
                    break;
1308
                }
1309
            }
1310

    
1311
            // Branch 반대편이 Symbol
1312
            if (_SameRunTargetConnector == null)
1313
            {
1314
                foreach (var line in lines)
1315
                {
1316
                    foreach (var connector in line.CONNECTORS)
1317
                    {
1318
                        Symbol symbol = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM) as Symbol;
1319
                        if (symbol != null)
1320
                        {
1321
                            _SameRunTargetSymbol = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
1322
                            break;
1323
                        }
1324
                    }
1325
                }
1326
            }
1327

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

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

    
1404
            if (_LMConnector != null)
1405
            {
1406
                if (_SameRunTargetConnector != null)
1407
                {
1408
                    JoinPipeRun(_LMConnector.ModelItemID, _SameRunTargetConnector.ModelItemID);
1409
                }
1410
                else
1411
                {
1412
                    foreach (var item in lines)
1413
                        item.SPPID.ModelItemId = _LMConnector.ModelItemID;
1414
                }
1415

    
1416
                _LMConnector.Commit();
1417
                ReleaseCOMObjects(_LMConnector);
1418
            }
1419

    
1420
            ReleaseCOMObjects(placeRunInputs);
1421
            ReleaseCOMObjects(_LMAItem);
1422
            if (_BranchTargetConnector != null)
1423
                ReleaseCOMObjects(_BranchTargetConnector);
1424
            if (_SameRunTargetConnector != null)
1425
                ReleaseCOMObjects(_SameRunTargetConnector);
1426
            if (_SameRunTargetSymbol != null)
1427
                ReleaseCOMObjects(_SameRunTargetSymbol);
1428
            foreach (var item in connectorVertices)
1429
                ReleaseCOMObjects(item.Key);
1430
            foreach (var item in branchConnectorVertices)
1431
                ReleaseCOMObjects(item.Key);
1432
        }
1433

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

    
1448
                targetLMConnector = FindTargetLMConnectorByPoint(connectorVertices, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y);
1449
                
1450
                if (targetLMConnector != null)
1451
                {
1452
                    Array array = new double[] { 0, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y };
1453
                    _LmLabelPersist = _placement.PIDPlaceLabel(endBreak.SPPID.MAPPINGNAME, ref array, Rotation: 0, LabeledItem: targetLMConnector.AsLMRepresentation(), IsLeaderVisible: true);
1454
                }
1455

    
1456
                if (_LmLabelPersist != null)
1457
                {
1458
                    _LmLabelPersist.Commit();
1459
                    ReleaseCOMObjects(_LmLabelPersist);
1460
                }
1461
                else
1462
                    RetryEndBreakModeling(endBreak, targetLMConnector);
1463

    
1464
                foreach (var item in connectorVertices)
1465
                    ReleaseCOMObjects(item.Key);
1466

    
1467
            }
1468
            else if (ownerObj != null && ownerObj.GetType() == typeof(Symbol))
1469
            {
1470
                Symbol ownerSymbol = ownerObj as Symbol;
1471
                LMSymbol _LMSymbol = dataSource.GetSymbol(ownerSymbol.SPPID.RepresentationId);
1472

    
1473
                targetLMConnector = null;
1474
                double distance = double.MaxValue;
1475

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

    
1492
                            double result = SPPIDUtil.CalcPointToPointdDistance(x, y, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y);
1493
                            if (result < distance)
1494
                            {
1495
                                targetLMConnector = connector;
1496
                                distance = result;
1497
                            }
1498
                        }
1499
                    }
1500
                }
1501

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

    
1518
                            double result = SPPIDUtil.CalcPointToPointdDistance(x, y, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y);
1519
                            if (result < distance)
1520
                            {
1521
                                targetLMConnector = connector;
1522
                                distance = result;
1523
                            }
1524
                        }
1525
                    }
1526
                }
1527

    
1528
                if (targetLMConnector != null)
1529
                {
1530
                    LMLabelPersist _LmLabelPersist = null;
1531
                    Array array = new double[] { 0, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y };
1532
                    _LmLabelPersist = _placement.PIDPlaceLabel(endBreak.SPPID.MAPPINGNAME, ref array, Rotation: 0, LabeledItem: targetLMConnector.AsLMRepresentation(), IsLeaderVisible: true);
1533
                    if (_LmLabelPersist != null)
1534
                    {
1535
                        _LmLabelPersist.Commit();
1536
                        ReleaseCOMObjects(_LmLabelPersist);
1537
                    }
1538
                    else
1539
                        RetryEndBreakModeling(endBreak, targetLMConnector);
1540
                }
1541
                
1542
                ReleaseCOMObjects(_LMSymbol);
1543
            }
1544

    
1545
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
1546
        }
1547

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

    
1566
            if (isZeroLength)
1567
            {
1568
                double[] vertices = null;
1569
                lineStringGeometry.GetVertices(ref verticesCount, ref vertices);
1570
                double x = 0;
1571
                double y = 0;
1572
                lineStringGeometry.GetVertex(1, ref x, ref y);
1573

    
1574
                placeRunInputs.AddSymbolTarget(targetLMConnector.ConnectItem1SymbolObject, x, y);
1575
                placeRunInputs.AddSymbolTarget(targetLMConnector.ConnectItem2SymbolObject, x, y);
1576

    
1577
                _placement.PIDRemovePlacement(targetLMConnector.AsLMRepresentation());
1578
                _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1579

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

    
1583
                AutoJoinPipeRun(_LMConnector.ModelItemID);
1584
            }
1585
            else
1586
            {
1587
                List<double[]> vertices = new List<double[]>();
1588
                for (int i = 1; i <= verticesCount; i++)
1589
                {
1590
                    double x = 0;
1591
                    double y = 0;
1592
                    lineStringGeometry.GetVertex(i, ref x, ref y);
1593
                    vertices.Add(new double[] { x, y });
1594
                }
1595

    
1596
                for (int i = 0; i < vertices.Count; i++)
1597
                {
1598
                    double[] points = vertices[i];
1599
                    if (i == 0)
1600
                    {
1601
                        if (targetLMConnector.ConnectItem1SymbolObject != null)
1602
                            placeRunInputs.AddSymbolTarget(targetLMConnector.ConnectItem1SymbolObject, points[0], points[1]);
1603
                        else
1604
                            placeRunInputs.AddPoint(points[0], points[1]);
1605
                    }
1606
                    else if (i == vertices.Count - 1)
1607
                    {
1608
                        if (targetLMConnector.ConnectItem2SymbolObject != null)
1609
                            placeRunInputs.AddSymbolTarget(targetLMConnector.ConnectItem2SymbolObject, points[0], points[1]);
1610
                        else
1611
                            placeRunInputs.AddPoint(points[0], points[1]);
1612
                    }
1613
                    else
1614
                        placeRunInputs.AddPoint(points[0], points[1]);
1615
                }
1616

    
1617
                List<Line> lines = SPPIDUtil.FindLinesByModelId(document, targetLMConnector.ModelItemID);
1618
                
1619
                _placement.PIDRemovePlacement(targetLMConnector.AsLMRepresentation());
1620
                _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1621

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

    
1625
                AutoJoinPipeRun(_LMConnector.ModelItemID);
1626
                foreach (var line in lines)
1627
                    line.SPPID.ModelItemId = _LMConnector.ModelItemID;
1628
            }
1629

    
1630

    
1631
            if (_LMLabelPersist != null)
1632
            {
1633
                _LMLabelPersist.Commit();
1634
                ReleaseCOMObjects(_LMLabelPersist);
1635
            }
1636
            else
1637
            {
1638
                
1639
            }
1640

    
1641
            ReleaseCOMObjects(_LMConnector);
1642
            ReleaseCOMObjects(placeRunInputs);
1643
            ReleaseCOMObjects(_LMAItem);
1644
        }
1645

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

    
1665
                List<Line> lines = SPPIDUtil.FindLinesByModelId(document, fromModelItemId);
1666
                foreach (var line in lines)
1667
                    line.SPPID.ModelItemId = toModelItemId;
1668
            }
1669
            catch (Exception ex)
1670
            {
1671
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
1672
            }
1673
            finally
1674
            {
1675
                ReleaseCOMObjects(modelItem1);
1676
                ReleaseCOMObjects(item1);
1677
                ReleaseCOMObjects(modelItem2);
1678
                ReleaseCOMObjects(item2);
1679
            }
1680
        }
1681

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

    
1715
        /// <summary>
1716
        /// LineRun에 있는 Line들을 Join하는 진입 메서드
1717
        /// </summary>
1718
        /// <param name="run"></param>
1719
        private void JoinRunLine(LineRun run)
1720
        {
1721
            string modelItemId = string.Empty;
1722
            foreach (var item in run.RUNITEMS)
1723
            {
1724
                if (item.GetType() == typeof(Line))
1725
                {
1726
                    Line line = item as Line;
1727
                    AutoJoinPipeRun(line.SPPID.ModelItemId);
1728
                    modelItemId = line.SPPID.ModelItemId;
1729

    
1730
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
1731
                }
1732
            }
1733
        }
1734

    
1735
        /// <summary>
1736
        /// PipeRun의 좌표를 가져오는 메서드
1737
        /// </summary>
1738
        /// <param name="modelId"></param>
1739
        /// <returns></returns>
1740
        private Dictionary<LMConnector, List<double[]>> GetPipeRunVertices(string modelId)
1741
        {
1742
            Dictionary<LMConnector, List<double[]>> connectorVertices = new Dictionary<LMConnector, List<double[]>>();
1743
            LMModelItem modelItem = dataSource.GetModelItem(modelId);
1744

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

    
1769
                ReleaseCOMObjects(modelItem);
1770
            }
1771

    
1772
            return connectorVertices;
1773
        }
1774

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

    
1796
                    double maxLineX = Math.Max(point1[0], point2[0]);
1797
                    double minLineX = Math.Min(point1[0], point2[0]);
1798
                    double maxLineY = Math.Max(point1[1], point2[1]);
1799
                    double minLineY = Math.Min(point1[1], point2[1]);
1800

    
1801
                    SlopeType slope = SPPIDUtil.CalcSlope(minLineX, minLineY, maxLineX, maxLineY);
1802

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

    
1833

    
1834
            }
1835

    
1836
            if (targetConnector == null)
1837
            {
1838
                foreach (var item in connectorVertices)
1839
                {
1840
                    List<double[]> points = item.Value;
1841
                    foreach (var point in points)
1842
                    {
1843
                        double distance = SPPIDUtil.CalcPointToPointdDistance(connX, connY, point[0], point[1]);
1844
                        if (length >= distance)
1845
                        {
1846
                            targetConnector = item.Key;
1847
                            length = distance;
1848
                        }
1849
                    }
1850
                }
1851

    
1852
            }
1853

    
1854
            return targetConnector;
1855
        }
1856

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

    
1872
                foreach (double[] point in points)
1873
                {
1874
                    double distance = SPPIDUtil.CalcPointToPointdDistance(point[0], point[1], connX, connY);
1875
                    if (length >= distance)
1876
                    {
1877
                        targetConnector = item.Key;
1878
                        length = distance;
1879
                    }
1880
                }
1881
            }
1882

    
1883
            return targetConnector;
1884
        }
1885

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

    
1909
                    if ((x1 <= connX && x2 >= connX) ||
1910
                        (y1 <= connY && y2 >= connY))
1911
                    {
1912
                        double distance = SPPIDUtil.CalcPointToPointdDistance(point1[0], point1[1], connX, connY);
1913
                        if (length >= distance)
1914
                        {
1915
                            targetConnector = item.Key;
1916
                            length = distance;
1917
                        }
1918

    
1919
                        distance = SPPIDUtil.CalcPointToPointdDistance(point2[0], point2[1], connX, connY);
1920
                        if (length >= distance)
1921
                        {
1922
                            targetConnector = item.Key;
1923
                            length = distance;
1924
                        }
1925
                    }
1926
                }
1927
            }
1928

    
1929
            // 못찾았을때.
1930
            length = double.MaxValue;
1931
            if (targetConnector == null)
1932
            {
1933
                foreach (var item in connectorVertices)
1934
                {
1935
                    List<double[]> points = item.Value;
1936

    
1937
                    foreach (double[] point in points)
1938
                    {
1939
                        double distance = SPPIDUtil.CalcPointToPointdDistance(point[0], point[1], connX, connY);
1940
                        if (length >= distance)
1941
                        {
1942
                            targetConnector = item.Key;
1943
                            length = distance;
1944
                        }
1945
                    }
1946
                }
1947
            }
1948

    
1949
            return targetConnector;
1950
        }
1951

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

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

    
1970
                foreach (var item in connectorVertices)
1971
                    ReleaseCOMObjects(item.Key);
1972
                if (_LmLabelPresist != null)
1973
                {
1974
                    _LmLabelPresist.Commit();
1975
                    lineNumber.SPPID.RepresentationId = _LmLabelPresist.AsLMRepresentation().Id;
1976
                    ReleaseCOMObjects(_LmLabelPresist);
1977
                }
1978
                else
1979
                {
1980

    
1981
                }
1982
            }
1983

    
1984
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
1985
        }
1986

    
1987
        /// <summary>
1988
        /// Flow Mark Modeling
1989
        /// </summary>
1990
        /// <param name="line"></param>
1991
        private void FlowMarkModeling(Line line)
1992
        {
1993
            if (line.FLOWMARK && !string.IsNullOrEmpty(line.SPPID.ModelItemId) && !string.IsNullOrEmpty(_ETCSetting.FlowMarkSymbolPath))
1994
            {
1995
                SlopeType targetSlopeType = SPPIDUtil.CalcSlope(line.SPPID.START_X, line.SPPID.START_Y, line.SPPID.END_X, line.SPPID.END_Y);
1996
                string mappingPath = _ETCSetting.FlowMarkSymbolPath;
1997
                double percent = line.FLOWMARK_PERCENT;
1998
                double tempX = 0;
1999
                double tempY = 0;
2000

    
2001
                double gapX;
2002
                double gapY;
2003
                // ID2 기준의 Gap을 구함
2004
                if (percent == 0)
2005
                {
2006
                    gapX = 0;
2007
                    gapY = 0;
2008
                }
2009
                else
2010
                {
2011
                    gapX = Math.Abs(line.SPPID.START_X - line.SPPID.END_X) / 100 * percent;
2012
                    gapY = Math.Abs(line.SPPID.START_Y - line.SPPID.END_Y) / 100 * percent;
2013
                }
2014

    
2015
                if (line.SPPID.START_X < line.SPPID.END_X)
2016
                    tempX = line.SPPID.START_X + gapX;
2017
                else
2018
                    tempX = line.SPPID.START_X - gapX;
2019

    
2020
                if (line.SPPID.START_Y < line.SPPID.END_Y)
2021
                    tempY = line.SPPID.START_Y + gapY;
2022
                else
2023
                    tempY = line.SPPID.START_Y - gapY;
2024

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

    
2041
                        SlopeType slopeType = SPPIDUtil.CalcSlope(point1[0], point1[1], point2[0], point2[1]);
2042
                        if (slopeType == targetSlopeType)
2043
                        {
2044
                            double result = SPPIDUtil.CalcPointToPointdDistance(point1[0], point1[1], tempX, tempY);
2045
                            if (result < distance)
2046
                            {
2047
                                distance = result;
2048
                                _TargetItem = item.Key;
2049

    
2050
                                startPoint = point1;
2051
                                endPoint = point2;
2052
                            }
2053

    
2054
                            result = SPPIDUtil.CalcPointToPointdDistance(point2[0], point2[1], tempX, tempY);
2055
                            if (result < distance)
2056
                            {
2057
                                distance = result;
2058
                                _TargetItem = item.Key;
2059

    
2060
                                startPoint = point1;
2061
                                endPoint = point2;
2062
                            }
2063
                        }
2064
                    }
2065
                }
2066

    
2067
                if (_TargetItem != null)
2068
                {
2069
                    double x = 0;
2070
                    double y = 0;
2071
                    double angle = 0;
2072
                    // SPPID 기준의 Gap으로 실 좌표를 구함
2073
                    if (percent == 0)
2074
                    {
2075
                        gapX = 0;
2076
                        gapY = 0;
2077
                    }
2078
                    else
2079
                    {
2080
                        gapX = Math.Abs(startPoint[0] - endPoint[0]) / 100 * percent;
2081
                        gapY = Math.Abs(startPoint[1] - endPoint[1]) / 100 * percent;
2082
                    }
2083

    
2084
                    if (startPoint[0] < endPoint[0])
2085
                        x = startPoint[0] + gapX;
2086
                    else
2087
                        x = startPoint[0] - gapX;
2088

    
2089
                    if (startPoint[1] < endPoint[1])
2090
                        y = startPoint[1] + gapY;
2091
                    else
2092
                        y = startPoint[1] - gapY;
2093
                    
2094
                    if (targetSlopeType == SlopeType.HORIZONTAL)
2095
                    {
2096
                        if (startPoint[0] < endPoint[0])
2097
                            angle = 0;
2098
                        else
2099
                            angle = Math.PI;
2100
                    }
2101
                    // 90 270
2102
                    else if (targetSlopeType == SlopeType.VERTICAL)
2103
                    {
2104
                        if (startPoint[1] < endPoint[1])
2105
                            angle = 90 * Math.PI / 180;
2106
                        else
2107
                            angle = 270 * Math.PI / 180;
2108
                    }
2109

    
2110
                    LMSymbol _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: 0, Rotation: angle, TargetItem: _TargetItem);
2111
                    
2112
                    if (_LMSymbol != null)
2113
                    {
2114
                        ReleaseCOMObjects(_LMSymbol);
2115
                    }
2116
                        
2117
                }
2118

    
2119
                foreach (var item in connectorVertices)
2120
                    ReleaseCOMObjects(item.Key);
2121
            }
2122
        }
2123

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

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

    
2197
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2198
        }
2199

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

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

    
2243
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2244
        }
2245

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

    
2273
                                 mapping = document.AttributeMappings.Find(x => x.UID == attribute.UID && !string.IsNullOrEmpty(x.SPPIDSYMBOLNAME));
2274
                                if (mapping != null)
2275
                                    break;  
2276
                            }
2277

    
2278
                            if (mapping != null)
2279
                            {
2280
                                double x = 0;
2281
                                double y = 0;
2282

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

    
2286
                                LMLabelPersist _LMLabelPersist = _placement.PIDPlaceLabel(mapping.SPPIDSYMBOLNAME, ref array, Rotation: text.ANGLE, LabeledItem: _LMSymbol.AsLMRepresentation(), IsLeaderVisible: mapping.LeaderLine);
2287
                                if (_LMLabelPersist!=null)
2288
                                {
2289
                                    _LMLabelPersist.Commit();
2290
                                    ReleaseCOMObjects(_LMLabelPersist);
2291
                                }
2292
                            }
2293
                        }
2294
                    }
2295
                    else if (owner.GetType() == typeof(Line))
2296
                    {
2297

    
2298
                    }
2299
                }
2300
                else
2301
                {
2302
                    LMItemNote _LMItemNote = null;
2303
                    LMAAttribute _LMAAttribute = null;
2304

    
2305
                    double x = 0;
2306
                    double y = 0;
2307

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

    
2310
                    _LMSymbol = _placement.PIDPlaceSymbol(text.SPPID.MAPPINGNAME, x, y);
2311
                    _LMSymbol.Commit();
2312
                    _LMItemNote = _placement.PIDDataSource.GetItemNote(_LMSymbol.ModelItemID);
2313
                    _LMItemNote.Commit();
2314
                    _LMAAttribute = _LMItemNote.Attributes["Note.Body"];
2315
                    _LMAAttribute.set_Value(text.VALUE);
2316
                    _LMItemNote.Commit();
2317

    
2318
                    if (_LMAAttribute != null)
2319
                        ReleaseCOMObjects(_LMAAttribute);
2320
                    if (_LMItemNote != null)
2321
                        ReleaseCOMObjects(_LMItemNote);
2322
                }
2323
            }
2324
            catch (Exception ex)
2325
            {
2326

    
2327
            }
2328
            finally
2329
            {
2330
                if (_LMSymbol != null)
2331
                    ReleaseCOMObjects(_LMSymbol);
2332
            }
2333

    
2334
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2335
        }
2336

    
2337
        /// <summary>
2338
        /// Note Modeling
2339
        /// </summary>
2340
        /// <param name="note"></param>
2341
        private void NoteModeling(Note note)
2342
        {
2343
            LMSymbol _LMSymbol = null;
2344
            LMItemNote _LMItemNote = null;
2345
            LMAAttribute _LMAAttribute = null;
2346

    
2347
            try
2348
            {
2349
                double x = 0;
2350
                double y = 0;
2351

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

    
2354
                _LMSymbol = _placement.PIDPlaceSymbol(note.SPPID.MAPPINGNAME, x, y);
2355
                _LMSymbol.Commit();
2356
                _LMItemNote = _placement.PIDDataSource.GetItemNote(_LMSymbol.ModelItemID);
2357
                _LMItemNote.Commit();
2358
                _LMAAttribute = _LMItemNote.Attributes["Note.Body"];
2359
                _LMAAttribute.set_Value(note.VALUE);
2360
                _LMItemNote.Commit();
2361
            }
2362
            catch (Exception ex)
2363
            {
2364

    
2365
            }
2366
            finally
2367
            {
2368
                if (_LMAAttribute != null)
2369
                    ReleaseCOMObjects(_LMAAttribute);
2370
                if (_LMItemNote != null)
2371
                    ReleaseCOMObjects(_LMItemNote);
2372
                if (_LMSymbol != null)
2373
                    ReleaseCOMObjects(_LMSymbol);
2374
            }
2375

    
2376
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2377
        }
2378

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

    
2403
                if (location.HasFlag(Location.Left))
2404
                    x = SPPIDLabelLocation.X1;
2405
                else if (location.HasFlag(Location.Right))
2406
                    x = SPPIDLabelLocation.X2;
2407

    
2408
                if (location.HasFlag(Location.Down))
2409
                    y = SPPIDLabelLocation.Y1;
2410
                else if (location.HasFlag(Location.Up))
2411
                    y = SPPIDLabelLocation.Y2;
2412
            }
2413
        }
2414

    
2415
        /// <summary>
2416
        /// Symbol의 우선순위 Modeling 목록을 가져온다.
2417
        /// 1. Angle Valve
2418
        /// 2. 3개로 이루어진 Symbol Group
2419
        /// </summary>
2420
        /// <returns></returns>
2421
        private List<Symbol> GetPrioritySymbol()
2422
        {
2423
            DataTable symbolTable = document.SymbolTable;
2424

    
2425
            // List에 순서대로 쌓는다.
2426
            List<Symbol> symbols = new List<Symbol>();
2427
            // Angle Valve 부터
2428
            foreach (var symbol in document.SYMBOLS.FindAll(x => x.CONNECTORS.Count == 2))
2429
            {
2430
                if (!symbols.Contains(symbol))
2431
                {
2432
                    double originX = 0;
2433
                    double originY = 0;
2434

    
2435
                    // ID2 Table에서 Original Point 가져옴.
2436
                    string OriginalPoint = symbolTable.Select(string.Format("UID = {0}",symbol.DBUID))[0]["OriginalPoint"].ToString();
2437
                    SPPIDUtil.ConvertPointBystring(OriginalPoint, ref originX, ref originY);
2438

    
2439
                    SlopeType slopeType1 = SlopeType.None;
2440
                    SlopeType slopeType2 = SlopeType.None;
2441
                    foreach (Connector connector in symbol.CONNECTORS)
2442
                    {
2443
                        double connectorX = 0;
2444
                        double connectorY = 0;
2445
                        SPPIDUtil.ConvertPointBystring(connector.CONNECTPOINT, ref connectorX, ref connectorY);
2446
                        if (slopeType1 == SlopeType.None)
2447
                            slopeType1 = SPPIDUtil.CalcSlope(originX, originY, connectorX, connectorY);
2448
                        else
2449
                            slopeType2 = SPPIDUtil.CalcSlope(originX, originY, connectorX, connectorY);
2450
                    }
2451

    
2452
                    if ((slopeType1 == SlopeType.VERTICAL && slopeType2 == SlopeType.HORIZONTAL) ||
2453
                        (slopeType2 == SlopeType.VERTICAL && slopeType1 == SlopeType.HORIZONTAL))
2454
                        symbols.Add(symbol);
2455
                }
2456
            }
2457

    
2458
            // 3개의 Symbol이 뭉쳐 있을 때
2459
            foreach (var item in document.SYMBOLS)
2460
            {
2461
                List<Symbol> group = new List<Symbol>();
2462
                SPPIDUtil.FindConnectedSymbolGroup(document, item, group);
2463
                if (group.Count == 3)
2464
                {
2465
                    Symbol symbol = SPPIDUtil.FindCenterAtThreeSymbols(document, group);
2466
                    if (!symbols.Contains(symbol))
2467
                        symbols.Add(symbol);
2468
                }
2469
            }
2470

    
2471
            // Connection Point가 3개 이상
2472
            foreach (var symbol in document.SYMBOLS)
2473
                if (symbol.CONNECTORS.Count > 2 && !symbols.Contains(symbol))
2474
                    symbols.Add(symbol);
2475

    
2476
            return symbols;
2477
        }
2478

    
2479
        /// <summary>
2480
        /// Graphic OID로 해당 Symbol의 크기를 구하여 Zoom
2481
        /// </summary>
2482
        /// <param name="graphicOID"></param>
2483
        /// <param name="milliseconds"></param>
2484
        private void ZoomObjectByGraphicOID(string graphicOID, int milliseconds = 150)
2485
        {
2486
            if (radApp.ActiveDocument.ActiveSheet.DrawingObjects[graphicOID] != null)
2487
            {
2488
                double minX = 0;
2489
                double minY = 0;
2490
                double maxX = 0;
2491
                double maxY = 0;
2492
                radApp.ActiveDocument.ActiveSheet.DrawingObjects[graphicOID].Range(out minX, out minY, out maxX, out maxY);
2493
                radApp.ActiveWindow.ZoomArea2(minX - 0.007, minY - 0.007, maxX + 0.007, maxY + 0.007, null);
2494

    
2495
                Thread.Sleep(milliseconds);
2496
            }
2497
        }
2498

    
2499
        /// <summary>
2500
        /// ComObject를 Release
2501
        /// </summary>
2502
        /// <param name="objVars"></param>
2503
        public void ReleaseCOMObjects(params object[] objVars)
2504
        {
2505
            int intNewRefCount = 0;
2506
            foreach (object obj in objVars)
2507
            {
2508
                if (!Information.IsNothing(obj) && System.Runtime.InteropServices.Marshal.IsComObject(obj))
2509
                    intNewRefCount = intNewRefCount + System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj);
2510
            }
2511
        }
2512
    }
2513
}
클립보드 이미지 추가 (최대 크기: 500 MB)