프로젝트

일반

사용자정보

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

hytos / DTI_PID / SPPIDConverter / AutoModeling.cs @ 1ed39474

이력 | 보기 | 이력해설 | 다운로드 (135 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
        List<string> ZeroLengthModelItemID = new List<string>();
43

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

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

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

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

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

    
87
        private void SetSystemEditingCommand(bool value)
88
        {
89
            foreach (var item in radApp.Commands)
90
            {
91
                if (item.Argument == "SystemEditingCmd.SystemEditing")
92
                {
93
                    if (item.Checked != value)
94
                    {
95
                        radApp.RunMacro("systemeditingcmd.dll");
96
                        break;
97
                    }
98

    
99
                }
100
            }
101
        }
102

    
103
        /// <summary>
104
        /// 도면 단위당 실행되는 메서드
105
        /// </summary>
106
        public void Run()
107
        {
108
            string drawingNumber = document.DrawingNumber;
109
            string drawingName = document.DrawingName;
110
            try
111
            {
112
                _placement = new Placement();
113
                dataSource = _placement.PIDDataSource;
114

    
115
                CreateDocument(ref drawingNumber, ref drawingName);
116

    
117
                if (DocumentCoordinateCorrection())
118
                {
119
                    int AllCount = CalcProgressCount();
120

    
121
                    SplashScreenManager.ShowForm(typeof(SPPIDSplashScreen), true, true);
122
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetAllStep, AllCount);
123
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetDocumentName, DocumentLabelText);
124

    
125
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Priority Symbol Modeling");
126
                    List<Symbol> prioritySymbols = GetPrioritySymbol();
127
                    foreach (var item in prioritySymbols)
128
                        SymbolModelingByPriority(item);
129

    
130
                    // Equipment Modeling
131
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Equipments Modeling");
132
                    foreach (Equipment equipment in document.Equipments)
133
                        EquipmentModeling(equipment);
134

    
135
                    // LineRun Symbol Modeling
136
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Symbols Modeling");
137
                    foreach (LineNumber lineNumber in document.LINENUMBERS)
138
                        foreach (LineRun run in lineNumber.RUNS)
139
                            SymbolModelingByRun(run);
140
                    // TrimLineRun Symbol Modeling
141
                    foreach (TrimLine trimLine in document.TRIMLINES)
142
                        foreach (LineRun run in trimLine.RUNS)
143
                            SymbolModelingByRun(run);
144

    
145
                    // LineRun Line Modeling
146
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Lines Modeling");
147
                    foreach (LineNumber lineNumber in document.LINENUMBERS)
148
                        foreach (LineRun run in lineNumber.RUNS)
149
                            LineModelingByRun(run);
150
                    // TrimLineRun Line Modeling
151
                    foreach (TrimLine trimLine in document.TRIMLINES)
152
                        foreach (LineRun run in trimLine.RUNS)
153
                            LineModelingByRun(run);
154

    
155
                    // Branch Line Modeling
156
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Branch Lines Modeling");
157
                    foreach (var item in BranchLines)
158
                        BranchLineModeling(item);
159

    
160
                    // EndBreak Modeling
161
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "EndBreaks Modeling");
162
                    foreach (var item in document.EndBreaks)
163
                        EndBreakModeling(item);
164

    
165
                    // SpecBreak Modeling
166
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "SpecBreaks Modeling");
167
                    foreach (var item in document.SpecBreaks)
168
                        SpecBreakModeling(item);
169

    
170
                    JoinZeroLengthLine();
171

    
172
                    // LineNumber Modeling
173
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "LineNumbers Modeling");
174
                    foreach (var item in document.LINENUMBERS)
175
                        LineNumberModeling(item);
176

    
177
                    // FlowMark Modeling
178
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Flow Mark Modeling");
179
                    foreach (var item in document.LINES)
180
                        FlowMarkModeling(item);
181

    
182
                    // Note Modeling
183
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Notes Modeling");
184
                    foreach (var item in document.NOTES)
185
                        NoteModeling(item);
186

    
187
                    // Text Modeling
188
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Texts Modeling");
189
                    foreach (var item in document.TEXTINFOS)
190
                        TextModeling(item);
191

    
192
                    // LineRun Line Join
193
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Join LineRuns");
194
                    foreach (LineNumber lineNumber in document.LINENUMBERS)
195
                        foreach (LineRun run in lineNumber.RUNS)
196
                            JoinRunLine(run);
197
                    // TrimLineRun Line Join
198
                    foreach (TrimLine trimLine in document.TRIMLINES)
199
                        foreach (LineRun run in trimLine.RUNS)
200
                            JoinRunLine(run);
201

    
202
                    // Input LineNumber Attribute
203
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Set LineNumbers Attribute");
204
                    foreach (var item in document.LINENUMBERS)
205
                        InputLineNumberAttribute(item);
206

    
207
                    // Input Symbol Attribute
208
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Set Symbols Attribute");
209
                    foreach (var item in document.SYMBOLS)
210
                        InputSymbolAttribute(item, item.ATTRIBUTES);
211

    
212
                    // Input SpecBreak Attribute
213
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Set Symbols Attribute");
214
                    foreach (var item in document.SpecBreaks)
215
                        InputSpecBreakAttribute(item);
216

    
217
                    // Label Symbol Modeling
218
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetStep, "Labels Modeling");
219
                    foreach (var item in document.SYMBOLS)
220
                        LabelSymbolModeling(item);
221

    
222
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, AllCount);
223
                }
224
            }
225
            catch (Exception ex)
226
            {
227
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
228
            }
229
            finally
230
            {
231
                application.ActiveWindow.Fit();
232

    
233
                if (radApp.ActiveDocument != null)
234
                {
235
                    //radApp.ActiveDocument.Save();
236
                    //radApp.ActiveDocument.SaveOnClose = false;
237
                    //radApp.ActiveDocument.Close(false);
238

    
239
                    ReleaseCOMObjects(newDrawing);
240
                }
241

    
242
                ReleaseCOMObjects(dataSource);
243
                ReleaseCOMObjects(_placement);
244

    
245
                Project_DB.InsertDrawingInfo(document.PATH, drawingNumber, drawingName, document);
246
                //SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.ClearParent, null);
247
                SplashScreenManager.CloseForm(false);
248
            }
249
        }
250

    
251
        /// <summary>
252
        /// 도면 생성 메서드
253
        /// </summary>
254
        private void CreateDocument(ref string drawingNumber, ref string drawingName)
255
        {
256
            GetDrawingNameAndNumber(ref drawingName, ref drawingNumber);
257

    
258
            newDrawing = application.Drawings.Add(document.Unit, document.Template, drawingNumber, drawingName);
259
            application.ActiveWindow.Fit();
260
            Thread.Sleep(1000);
261
            application.ActiveWindow.Zoom = 2000;
262
            Thread.Sleep(2000);
263
        }
264

    
265
        /// <summary>
266
        /// DrawingName, DrawingNumber를 확인하여 중복이 있으면 _1을 붙이고 +1씩 한다.
267
        /// </summary>
268
        /// <param name="drawingName"></param>
269
        /// <param name="drawingNumber"></param>
270
        private void GetDrawingNameAndNumber(ref string drawingName, ref string drawingNumber)
271
        {
272
            LMDrawings drawings = new LMDrawings();
273
            drawings.Collect(dataSource);
274
            
275
            List<string> drawingNameList = new List<string>();
276
            List<string> drawingNumberList = new List<string>();
277

    
278
            foreach (LMDrawing item in drawings)
279
            {
280
                drawingNameList.Add(item.Attributes["Name"].get_Value().ToString());
281
                drawingNumberList.Add(item.Attributes["DrawingNumber"].get_Value().ToString());
282
            }
283

    
284
            int nameLength = drawingName.Length;
285
            while (drawingNameList.Contains(drawingName))
286
            {
287
                if (nameLength == drawingName.Length)
288
                    drawingName += "-1";
289
                else
290
                {
291
                    int index = Convert.ToInt32(drawingName.Remove(0, nameLength + 1));
292
                    drawingName = drawingName.Substring(0, nameLength + 1);
293
                    drawingName += ++index;
294
                }
295
            }
296

    
297
            int numberLength = drawingNumber.Length;
298
            while (drawingNameList.Contains(drawingNumber))
299
            {
300
                if (numberLength == drawingNumber.Length)
301
                    drawingNumber += "-1";
302
                else
303
                {
304
                    int index = Convert.ToInt32(drawingNumber.Remove(0, numberLength + 1));
305
                    drawingNumber = drawingNumber.Substring(0, numberLength + 1);
306
                    drawingNumber += ++index;
307
                }
308
            }
309

    
310
            ReleaseCOMObjects(drawings);
311
        }
312

    
313
        /// <summary>
314
        /// 도면 크기 구하는 메서드
315
        /// </summary>
316
        /// <returns></returns>
317
        private bool DocumentCoordinateCorrection()
318
        {
319
            if (Settings.Default.DrawingX != 0 && Settings.Default.DrawingY != 0)
320
            {
321
                document.SetSPPIDLocation(Settings.Default.DrawingX, Settings.Default.DrawingY);
322
                document.CoordinateCorrection();
323
                return true;
324
            }
325
            else
326
                return false;
327
        }
328

    
329
        /// <summary>
330
        /// 라인을 Run 단위로 모델링하는 진입 메서드
331
        /// </summary>
332
        /// <param name="run"></param>
333
        private void LineModelingByRun(LineRun run)
334
        {
335
            Line prevLine = null;
336
            List<Line> lines = new List<Line>();
337
            foreach (var item in run.RUNITEMS)
338
            {
339
                // Line일 경우
340
                if (item.GetType() == typeof(Line))
341
                {
342
                    Line line = item as Line;
343
                    if (prevLine == null)
344
                        lines.Add(line);
345
                    else if (prevLine != null)
346
                    {
347
                        if (prevLine.SPPID.MAPPINGNAME == line.SPPID.MAPPINGNAME)
348
                            lines.Add(line);
349
                        else
350
                        {
351
                            if (lines.Count > 0)
352
                            {
353
                                LineModeling(lines);
354
                                lines.Clear();
355
                            }
356
                            lines.Add(line);
357
                        }
358
                    }
359

    
360
                    prevLine = line;
361

    
362
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
363
                }
364
                // Symbol 일 경우
365
                else if (item.GetType() == typeof(Symbol))
366
                {
367
                    if (lines.Count > 0)
368
                    {
369
                        LineModeling(lines);
370
                        lines.Clear();
371
                    }
372
                }
373
            }
374

    
375
            if (lines.Count > 0)
376
                LineModeling(lines);
377
        }
378

    
379
        /// <summary>
380
        /// 심볼을 Run 단위로 모델링하는 진입 메서드
381
        /// </summary>
382
        /// <param name="run"></param>
383
        private void SymbolModelingByRun(LineRun run)
384
        {
385
            // 양끝 Symbol 검사 후 Line이 나올때까지만 Symbol Modeling
386
            if (run.RUNITEMS.Count > 0)
387
            {
388
                if (run.RUNITEMS[0].GetType() == typeof(Symbol))
389
                    SymbolModelingByRunStart(run.RUNITEMS[0] as Symbol, run);
390

    
391
                if (run.RUNITEMS[run.RUNITEMS.Count - 1].GetType() == typeof(Symbol))
392
                    SymbolModelingByRunEnd(run.RUNITEMS[run.RUNITEMS.Count - 1] as Symbol, run);
393
            }
394

    
395
            Symbol targetSymbol = null;
396
            foreach (var item in run.RUNITEMS)
397
            {
398
                if (item.GetType() == typeof(Symbol))
399
                {
400
                    Symbol symbol = item as Symbol;
401
                    SymbolModeling(symbol, targetSymbol);
402
                    targetSymbol = symbol;
403
                }
404
                else
405
                {
406
                    targetSymbol = null;
407
                }
408
            }
409
        }
410

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

    
438

    
439
        }
440

    
441
        /// <summary>
442
        /// Run에 있는 심볼을 모델링하는데 기준이 Run의 끝점
443
        /// </summary>
444
        /// <param name="symbol"></param>
445
        /// <param name="run"></param>
446
        private void SymbolModelingByRunEnd(Symbol symbol, LineRun run)
447
        {
448
            foreach (var connector in symbol.CONNECTORS)
449
            {
450
                object targetItem = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM);
451
                if (targetItem != null &&
452
                    (targetItem.GetType() == typeof(Symbol) || targetItem.GetType() == typeof(Equipment)) &&
453
                    !IsSameLineRun(symbol, targetItem))
454
                {
455
                    SymbolModeling(symbol, targetItem as Symbol);
456
                    for (int i = run.RUNITEMS.Count - 2; i >= 0; i--)
457
                    {
458
                        object item = run.RUNITEMS[i];
459
                        if (item.GetType() == typeof(Symbol))
460
                            SymbolModeling(item as Symbol, run.RUNITEMS[i + 1] as Symbol);
461
                        else
462
                            break;
463
                    }
464
                    break;
465
                }
466
            }
467
        }
468

    
469
        /// <summary>
470
        /// 심볼을 실제로 Modeling 메서드
471
        /// </summary>
472
        /// <param name="symbol"></param>
473
        /// <param name="targetSymbol"></param>
474
        /// <param name="prevSymbol"></param>
475
        private void SymbolModeling(Symbol symbol, Symbol targetSymbol)
476
        {
477
#if DEBUG
478
            try
479
            {
480
#endif
481
                // OWNERSYMBOL Attribute, 값을 가지고 있을 경우
482
                BaseModel.Attribute itemAttribute = symbol.ATTRIBUTES.Find(attr => attr.ATTRIBUTE == "OWNERSYMBOL");
483
                if (itemAttribute != null && string.IsNullOrEmpty(itemAttribute.VALUE) && itemAttribute.VALUE != "None")
484
                    return;
485
                // 이미 모델링 됐을 경우
486
                else if (!string.IsNullOrEmpty(symbol.SPPID.RepresentationId))
487
                    return;
488

    
489
                LMSymbol _LMSymbol = null;
490

    
491
                string mappingPath = symbol.SPPID.MAPPINGNAME;
492
                double x = symbol.SPPID.ORIGINAL_X;
493
                double y = symbol.SPPID.ORIGINAL_Y;
494
                int mirror = 0;
495
                double angle = symbol.ANGLE;
496

    
497
                SPPIDUtil.ConvertGridPoint(ref x, ref y);
498

    
499
                // OPC 일경우 180도 일때 Mirror
500
                if (mappingPath.Contains("Piping OPC's") && angle == Math.PI)
501
                    mirror = 1;
502

    
503
                // Mirror 계산
504
                if (symbol.FLIP == 1)
505
                {
506
                    mirror = 1;
507
                    angle += Math.PI;
508
                }
509

    
510
                if (targetSymbol != null && !string.IsNullOrEmpty(targetSymbol.SPPID.RepresentationId))
511
                {
512
                    LMSymbol _TargetItem = dataSource.GetSymbol(targetSymbol.SPPID.RepresentationId);
513
                    Connector connector = SPPIDUtil.FindSymbolConnectorByUID(document, symbol.UID, targetSymbol);
514
                    if (connector != null)
515
                        GetTargetSymbolConnectorPoint(connector, targetSymbol, ref x, ref y);
516

    
517
                    _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle, TargetItem: _TargetItem);
518

    
519
                    if (_LMSymbol != null && _TargetItem != null)
520
                    {
521
                        symbol.SPPID.RepresentationId = _LMSymbol.AsLMRepresentation().Id;
522
                        LMConnector reModelingConnector = FindBreakLineTarget(symbol, targetSymbol);
523

    
524
                        if (reModelingConnector != null)
525
                            ReModelingLMConnector(reModelingConnector);
526
                    }
527

    
528
                    ReleaseCOMObjects(_TargetItem);
529
                }
530
                else
531
                    _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
532

    
533

    
534
                if (_LMSymbol != null)
535
                {
536
                    _LMSymbol.Commit();
537
                    symbol.SPPID.RepresentationId = _LMSymbol.AsLMRepresentation().Id;
538
                    symbol.SPPID.ModelItemID = _LMSymbol.ModelItemID;
539
                    symbol.SPPID.GraphicOID = _LMSymbol.get_GraphicOID();
540

    
541
                    foreach (var item in symbol.ChildSymbols)
542
                        CreateChildSymbol(item, _LMSymbol);
543
                }
544

    
545
                ReleaseCOMObjects(_LMSymbol);
546
                SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
547
#if DEBUG
548

    
549
            }
550
            catch (Exception ex)
551
            {
552
                System.Windows.Forms.MessageBox.Show(ex.StackTrace);
553
            }
554
#endif
555
        }
556

    
557
        /// <summary>
558
        /// ID2의 Symbol Width와 Height를 비교해서 상대적인 SPPID Connector좌표를 가져온다.
559
        /// </summary>
560
        /// <param name="targetConnector"></param>
561
        /// <param name="targetSymbol"></param>
562
        /// <param name="x"></param>
563
        /// <param name="y"></param>
564
        private void GetTargetSymbolConnectorPoint(Connector targetConnector, Symbol targetSymbol, ref double x, ref double y)
565
        {
566
            LMSymbol _TargetItem = dataSource.GetSymbol(targetSymbol.SPPID.RepresentationId);
567

    
568
            double[] range = null;
569
            List<double[]> points = new List<double[]>();
570
            GetSPPIDSymbolRangeAndConnectionPoints(targetSymbol, ref range, points);
571
            double x1 = range[0];
572
            double y1 = range[1];
573
            double x2 = range[2];
574
            double y2 = range[3];
575

    
576
            // Origin 기준 Connector의 위치차이
577
            double sceneX = 0;
578
            double sceneY = 0;
579
            SPPIDUtil.ConvertPointBystring(targetConnector.SCENECONNECTPOINT, ref sceneX, ref sceneY);
580
            double originX = 0;
581
            double originY = 0;
582
            SPPIDUtil.ConvertPointBystring(targetSymbol.ORIGINALPOINT, ref originX, ref originY);
583
            double gapX = originX - sceneX;
584
            double gapY = originY - sceneY;
585

    
586
            // SPPID Symbol과 ID2 심볼의 크기 차이
587
            double sizeWidth = 0;
588
            double sizeHeight = 0;
589
            SPPIDUtil.ConvertPointBystring(targetSymbol.SIZE, ref sizeWidth, ref sizeHeight);
590
            double percentX = (x2 - x1) / sizeWidth;
591
            double percentY = (y2 - y1) / sizeHeight;
592

    
593
            double SPPIDgapX = gapX * percentX;
594
            double SPPIDgapY = gapY * percentY;
595

    
596
            double[] SPPIDOriginPoint = new double[] { _TargetItem.get_XCoordinate() - SPPIDgapX, _TargetItem.get_YCoordinate() + SPPIDgapY };
597
            double distance = double.MaxValue;
598
            double[] resultPoint;
599
            foreach (var point in points)
600
            {
601
                double result = SPPIDUtil.CalcPointToPointdDistance(point[0], point[1], SPPIDOriginPoint[0], SPPIDOriginPoint[1]);
602
                if (distance > result)
603
                {
604
                    distance = result;
605
                    resultPoint = point;
606
                    x = point[0];
607
                    y = point[1];
608
                }
609
            }
610

    
611
            ReleaseCOMObjects(_TargetItem);
612
        }
613

    
614
        /// <summary>
615
        /// SPPID Symbol의 Range를 구한다.
616
        /// </summary>
617
        /// <param name="symbol"></param>
618
        /// <param name="range"></param>
619
        private void GetSPPIDSymbolRangeAndConnectionPoints(Symbol symbol, ref double[] range, List<double[]> points)
620
        {
621
            LMSymbol _TargetItem = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
622
            Ingr.RAD2D.Symbol2d symbol2d = radApp.ActiveDocument.ActiveSheet.DrawingObjects[_TargetItem.get_GraphicOID().ToString()];
623
            double x1 = 0;
624
            double y1 = 0;
625
            double x2 = 0;
626
            double y2 = 0;
627
            symbol2d.Range(out x1, out y1, out x2, out y2);
628
            range = new double[] { x1, y1, x2, y2 };
629

    
630
            for (int i = 1; i < int.MaxValue; i++)
631
            {
632
                double connX = 0;
633
                double connY = 0;
634
                if (_placement.PIDConnectPointLocation(_TargetItem, i, ref connX, ref connY))
635
                    points.Add(new double[] { connX, connY });
636
                else
637
                    break;
638
            }
639

    
640
            foreach (var childSymbol in symbol.ChildSymbols)
641
                GetSPPIDChildSymbolRange(childSymbol, ref range, points);
642

    
643
            ReleaseCOMObjects(_TargetItem);
644
        }
645

    
646
        /// <summary>
647
        /// Child Modeling 된 Symbol의 Range를 구한다.
648
        /// </summary>
649
        /// <param name="childSymbol"></param>
650
        /// <param name="range"></param>
651
        private void GetSPPIDChildSymbolRange(ChildSymbol childSymbol, ref double[] range, List<double[]> points)
652
        {
653
            LMSymbol _ChildSymbol = dataSource.GetSymbol(childSymbol.SPPID.RepresentationId);
654
            Ingr.RAD2D.Symbol2d symbol2d = radApp.ActiveDocument.ActiveSheet.DrawingObjects[_ChildSymbol.get_GraphicOID().ToString()];
655
            double x1 = 0;
656
            double y1 = 0;
657
            double x2 = 0;
658
            double y2 = 0;
659
            symbol2d.Range(out x1, out y1, out x2, out y2);
660
            range[0] = Math.Min(range[0], x1);
661
            range[1] = Math.Min(range[1], y1);
662
            range[2] = Math.Max(range[2], x2);
663
            range[3] = Math.Max(range[3], y2);
664

    
665
            for (int i = 1; i < int.MaxValue; i++)
666
            {
667
                double connX = 0;
668
                double connY = 0;
669
                if (_placement.PIDConnectPointLocation(_ChildSymbol, i, ref connX, ref connY))
670
                    points.Add(new double[] { connX, connY });
671
                else
672
                    break;
673
            }
674

    
675
            foreach (var loopChildSymbol in childSymbol.ChildSymbols)
676
                GetSPPIDChildSymbolRange(loopChildSymbol, ref range, points);
677

    
678
            ReleaseCOMObjects(_ChildSymbol);
679
        }
680

    
681
        /// <summary>
682
        /// Label Symbol Modeling
683
        /// </summary>
684
        /// <param name="symbol"></param>
685
        private void LabelSymbolModeling(Symbol symbol)
686
        {
687
            BaseModel.Attribute itemAttribute = symbol.ATTRIBUTES.Find(x => x.ATTRIBUTE == "OWNERSYMBOL");
688
            if (itemAttribute == null || string.IsNullOrEmpty(itemAttribute.VALUE))
689
                return;
690

    
691
            Array points = new double[] { 0, symbol.SPPID.ORIGINAL_X, symbol.SPPID.ORIGINAL_Y };
692
            
693
            string symbolUID = itemAttribute.VALUE;
694
            object targetItem = SPPIDUtil.FindObjectByUID(document, symbolUID);
695
            if (targetItem != null)
696
            {
697
                // Object 아이템이 Symbol일 경우 Equipment일 경우 
698
                string sRep = null;
699
                if (targetItem.GetType() == typeof(Symbol))
700
                    sRep = ((Symbol)targetItem).SPPID.RepresentationId;
701
                else if (targetItem.GetType() == typeof(Equipment))
702
                    sRep = ((Equipment)targetItem).SPPID.RepresentationId;
703

    
704
                if (!string.IsNullOrEmpty(sRep))
705
                {
706
                    // LEADER Line 검사
707
                    bool leaderLine = false;
708
                    SymbolMapping symbolMapping = document.SymbolMappings.Find(x => x.UID == symbol.DBUID);
709
                    if (symbolMapping != null)
710
                        leaderLine = symbolMapping.LEADERLINE;
711

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

    
716
                    //Leader 선 센터로
717
                    if (_LMLabelPresist != null)
718
                    {
719
                        // Target Item에 Label의 Attribute Input
720
                        InputSymbolAttribute(targetItem, symbol.ATTRIBUTES);
721

    
722
                        string OID = _LMLabelPresist.get_GraphicOID();
723
                        DependencyObject dependency = radApp.ActiveDocument.ActiveSheet.DrawingObjects[OID] as DependencyObject;
724
                        if (dependency != null)
725
                        {
726
                            bool result = false;
727
                            foreach (var attributes in dependency.AttributeSets)
728
                            {
729
                                foreach (var attribute in attributes)
730
                                {
731
                                    string name = attribute.Name;
732
                                    string value = attribute.GetValue().ToString();
733
                                    if (name == "DrawingItemType" && value == "LabelPersist")
734
                                    {
735
                                        foreach (DrawingObjectBase drawingObject in dependency.DrawingObjects)
736
                                        {
737
                                            if (drawingObject.Type == Ingr.RAD2D.ObjectType.igLineString2d)
738
                                            {
739
                                                Ingr.RAD2D.LineString2d lineString2D = drawingObject as Ingr.RAD2D.LineString2d;
740
                                                double prevX = _TargetItem.get_XCoordinate();
741
                                                double prevY = _TargetItem.get_YCoordinate();
742
                                                lineString2D.InsertVertex(lineString2D.VertexCount, prevX, prevY);
743
                                                lineString2D.RemoveVertex(lineString2D.VertexCount);
744
                                                result = true;
745
                                                break;
746
                                            }
747
                                        }
748
                                    }
749

    
750
                                    if (result)
751
                                        break;
752
                                }
753

    
754
                                if (result)
755
                                    break;
756
                            }
757
                        }
758

    
759
                        _LMLabelPresist.Commit();
760
                    }
761
                    
762
                    ReleaseCOMObjects(_TargetItem);
763
                    ReleaseCOMObjects(_LMLabelPresist);
764
                }
765
            }
766

    
767
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
768
        }
769

    
770
        /// <summary>
771
        /// Equipment를 실제로 Modeling 메서드
772
        /// </summary>
773
        /// <param name="equipment"></param>
774
        private void EquipmentModeling(Equipment equipment)
775
        {
776
            if (!string.IsNullOrEmpty(equipment.SPPID.RepresentationId))
777
                return;
778

    
779
            LMSymbol _LMSymbol = null;
780
            LMSymbol targetItem = null;
781
            string mappingPath = equipment.SPPID.MAPPINGNAME;
782
            double x = equipment.SPPID.ORIGINAL_X;
783
            double y = equipment.SPPID.ORIGINAL_Y;
784
            int mirror = 0;
785
            double angle = equipment.ANGLE;
786

    
787
            SPPIDUtil.ConvertGridPoint(ref x, ref y);
788

    
789
            Connector connector = equipment.CONNECTORS.Find(conn => !string.IsNullOrEmpty(conn.CONNECTEDITEM) && conn.CONNECTEDITEM != "None");
790
            if (connector != null)
791
            {
792
                Equipment connEquipment = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM) as Equipment;
793
                if (connEquipment != null)
794
                {
795
                    if (string.IsNullOrEmpty(connEquipment.SPPID.RepresentationId))
796
                        EquipmentModeling(connEquipment);
797

    
798
                    if (!string.IsNullOrEmpty(connEquipment.SPPID.RepresentationId))
799
                    {
800
                        targetItem = dataSource.GetSymbol(connEquipment.SPPID.RepresentationId);
801
                        if (targetItem != null)
802
                        {
803
                            _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle, TargetItem: targetItem);
804
                        }
805
                        else
806
                        {
807
                            _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
808
                        }
809
                    }
810
                    else
811
                    {
812
                        _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
813
                    }
814
                }
815
                else
816
                {
817
                    _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
818
                }
819
            }
820
            else
821
            {
822
                _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: mirror, Rotation: angle);
823
            }
824

    
825
            if (_LMSymbol != null)
826
            {
827
                _LMSymbol.Commit();
828
                equipment.SPPID.RepresentationId = _LMSymbol.AsLMRepresentation().Id;
829
                equipment.SPPID.GraphicOID = _LMSymbol.get_GraphicOID();
830
                ReleaseCOMObjects(_LMSymbol);
831
            }
832

    
833
            if (targetItem != null)
834
            {
835
                ReleaseCOMObjects(targetItem);
836
            }
837
            
838
            ReleaseCOMObjects(_LMSymbol);
839

    
840
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
841
        }
842

    
843
        private void SymbolModelingByPriority(Symbol symbol)
844
        {
845
            // Angle, Center, 우선순위 모델링
846
            SymbolModeling(symbol, null);
847
            List<Symbol> group = new List<Symbol>() { symbol };
848
            SPPIDUtil.FindConnectedSymbolGroup(document, symbol, group);
849

    
850
            List<Symbol> endModeling = new List<Symbol>() { symbol };
851
            while (endModeling.Count != group.Count)
852
            {
853
                foreach (var item in group)
854
                {
855
                    if (!endModeling.Contains(item))
856
                    {
857
                        bool result = false;
858
                        foreach (var connector in item.CONNECTORS)
859
                        {
860
                            Symbol connSymbol = group.Find(x => x.UID == connector.CONNECTEDITEM);
861
                            if (connSymbol == item)
862
                                throw new Exception(connSymbol.UID);
863

    
864
                            if (connSymbol != null && endModeling.Contains(connSymbol))
865
                            {
866
                                SymbolModeling(item, connSymbol);
867
                                endModeling.Add(item);
868
                                result = true;
869
                                break;
870
                            }
871
                        }
872

    
873
                        if (result)
874
                            break;
875
                    }
876
                }
877
            }
878
        }
879

    
880
        /// <summary>
881
        /// 심볼을 실제로 Modeling할때 ChildSymbol이 있다면 Modeling하는 메서드
882
        /// </summary>
883
        /// <param name="childSymbol"></param>
884
        /// <param name="parentSymbol"></param>
885
        private void CreateChildSymbol(ChildSymbol childSymbol, LMSymbol parentSymbol)
886
        {
887
            Ingr.RAD2D.Symbol2d symbol2d = radApp.ActiveDocument.ActiveSheet.DrawingObjects[parentSymbol.get_GraphicOID().ToString()];
888
            double x1 = 0;
889
            double x2 = 0;
890
            double y1 = 0;
891
            double y2 = 0;
892
            symbol2d.Range(out x1, out y1, out x2, out y2);
893

    
894
            LMSymbol _LMSymbol = _placement.PIDPlaceSymbol(childSymbol.SPPID.MAPPINGNAME, (x1 + x2) / 2, (y1 + y2) / 2, TargetItem: parentSymbol);
895
            if (_LMSymbol != null)
896
            {
897
                childSymbol.SPPID.RepresentationId = _LMSymbol.AsLMRepresentation().Id;
898
                foreach (var item in childSymbol.ChildSymbols)
899
                    CreateChildSymbol(item, _LMSymbol);
900
            }
901
            
902

    
903
            ReleaseCOMObjects(_LMSymbol);
904
        }
905

    
906
        /// <summary>
907
        /// item이 TargetItem과 같은 LineRun에 있는지 검사
908
        /// </summary>
909
        /// <param name="item"></param>
910
        /// <param name="targetItem"></param>
911
        /// <returns></returns>
912
        private bool IsSameLineRun(object item, object targetItem)
913
        {
914
            foreach (var lineNumber in document.LINENUMBERS)
915
            {
916
                foreach (var run in lineNumber.RUNS)
917
                {
918
                    foreach (var runItem in run.RUNITEMS)
919
                    {
920
                        if (runItem == item)
921
                        {
922
                            foreach (var findItem in run.RUNITEMS)
923
                            {
924
                                if (findItem == targetItem)
925
                                {
926
                                    return true;
927
                                }
928
                            }
929

    
930
                            return false;
931

    
932
                        }
933
                    }
934
                }
935
            }
936

    
937
            return false;
938
        }
939

    
940
        /// <summary>
941
        /// Line을 실제로 모델링하는 메서드
942
        /// </summary>
943
        /// <param name="lines"></param>
944
        private void LineModeling(List<Line> lines)
945
        {
946
            _LMAItem _LMAItem = _placement.PIDCreateItem(lines[0].SPPID.MAPPINGNAME);
947
            PlaceRunInputs placeRunInputs = new PlaceRunInputs();
948
            LMSymbol _LMSymbol1 = null;
949
            LMSymbol _LMSymbol2 = null;
950
            Dictionary<LMConnector, List<double[]>> connectorVertices1 = new Dictionary<LMConnector, List<double[]>>();
951
            LMConnector targetConnector1 = null;
952
            Dictionary<LMConnector, List<double[]>> connectorVertices2 = new Dictionary<LMConnector, List<double[]>>();
953
            LMConnector targetConnector2 = null;
954
            
955
            Line startBranchLine = null;
956
            Line endBranchLine = null;
957

    
958
            // Type, Line, TargetObjet, x, y
959
            List<Tuple<string, Line, object, double, double>> linePointInfo = new List<Tuple<string, Line, object, double, double>>();
960
            // Point 정리
961
            for (int i = 0; i < lines.Count; i++)
962
            {
963
                Line line = lines[i];
964
                if (i == 0 || i + 1 != lines.Count)
965
                {
966
                    // 시작점에 연결된 Symbol 찾기
967
                    object connItem = SPPIDUtil.FindObjectByUID(document, line.CONNECTORS[0].CONNECTEDITEM);
968
                    if (connItem != null && connItem.GetType() == typeof(Symbol))
969
                    {
970
                        Symbol symbol1 = connItem as Symbol;
971
                        _LMSymbol1 = GetTargetSymbol(symbol1, line);
972
                        if (_LMSymbol1 != null)
973
                        {
974
                            double x = line.SPPID.START_X;
975
                            double y = line.SPPID.START_Y;
976
                            Connector connector = SPPIDUtil.FindSymbolConnectorByUID(document, line.UID, symbol1);
977
                            if (connector != null)
978
                            {
979
                                GetTargetSymbolConnectorPoint(connector, symbol1, ref x, ref y);
980
                                line.SPPID.START_X = x;
981
                                line.SPPID.START_Y = y;
982
                            }
983

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

    
994
                        if (targetConnector1 != null)
995
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("LINE", line, targetConnector1, line.SPPID.START_X, line.SPPID.START_Y));
996
                        else
997
                        {
998
                            startBranchLine = connItem as Line;
999
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.START_X, line.SPPID.START_Y));
1000
                        }
1001
                    }
1002
                    else
1003
                        linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.START_X, line.SPPID.START_Y));
1004
                        
1005
                }
1006
                if (i + 1 == lines.Count)
1007
                {
1008
                    // 끝점에 연결된 Symbol 찾기
1009
                    object connItem = SPPIDUtil.FindObjectByUID(document, line.CONNECTORS[1].CONNECTEDITEM);
1010

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

    
1014
                    if (connItem != null && connItem.GetType() == typeof(Symbol))
1015
                    {
1016
                        Symbol symbol2 = connItem as Symbol;
1017
                        _LMSymbol2 = GetTargetSymbol(connItem as Symbol, line);
1018
                        if (_LMSymbol2 != null)
1019
                        {
1020
                            double x = line.SPPID.END_X;
1021
                            double y = line.SPPID.END_Y;
1022
                            Connector connector = SPPIDUtil.FindSymbolConnectorByUID(document, line.UID, symbol2);
1023
                            if (connector != null)
1024
                            {
1025
                                GetTargetSymbolConnectorPoint(connector, symbol2, ref x, ref y);
1026
                                line.SPPID.END_X = x;
1027
                                line.SPPID.END_Y = y;
1028
                            }
1029

    
1030
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("SYMBOL", line, _LMSymbol2, x, y));
1031
                        }
1032
                        else
1033
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.END_X, line.SPPID.END_Y));
1034
                    }
1035
                    else if (connItem != null && connItem.GetType() == typeof(Line) && !lines.Contains(connItem))
1036
                    {
1037
                        connectorVertices2 = GetPipeRunVertices(((Line)connItem).SPPID.ModelItemId);
1038
                        targetConnector2 = FindTargetLMConnector(connectorVertices2, line.SPPID.END_X, line.SPPID.END_Y, line.SPPID.START_X, line.SPPID.START_Y);
1039

    
1040
                        if (targetConnector2 != null)
1041
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>("LINE", line, targetConnector2, line.SPPID.END_X, line.SPPID.END_Y));
1042
                        else
1043
                        {
1044
                            endBranchLine = connItem as Line;
1045
                            linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.END_X, line.SPPID.END_Y));
1046
                        }
1047
                    }
1048
                    else
1049
                        linePointInfo.Add(new Tuple<string, Line, object, double, double>(null, line, null, line.SPPID.END_X, line.SPPID.END_Y));
1050
                }
1051
            }
1052

    
1053
            double prevX = double.NaN;
1054
            double prevY = double.NaN;
1055
            SlopeType prevSlopeType = SlopeType.None;
1056
            for (int i = 0; i < linePointInfo.Count; i++)
1057
            {
1058
                Tuple<string, Line, object, double, double> item = linePointInfo[i];
1059
                Line line = item.Item2;
1060
                double x = item.Item4;
1061
                double y = item.Item5;
1062
                SlopeType slopeType = SPPIDUtil.CalcSlope(line.SPPID.START_X, line.SPPID.START_Y, line.SPPID.END_X, line.SPPID.END_Y);
1063
                // Symbol일 경우 바로 Input Point
1064
                if (item.Item1 == "SYMBOL")
1065
                    placeRunInputs.AddSymbolTarget(item.Item3 as LMSymbol, x, y);
1066
                else
1067
                {
1068
                    SPPIDUtil.ConvertGridPoint(ref x, ref y);
1069
                    // i == 0은 그대로 사용
1070
                    if (i != 0)
1071
                    {
1072
                        Tuple<string, Line, object, double, double> prevItem = linePointInfo[i - 1];
1073
                        // y 좌표가 같아야함 및 Symbol 좌표가 정확하지 않으므로 한번더 보정
1074
                        if (prevSlopeType == SlopeType.HORIZONTAL)
1075
                        {
1076
                            y = prevY;
1077
                            SPPIDUtil.ConvertGridPointOnlyOnePoint(ref y);
1078
                        }
1079
                        else if (prevSlopeType == SlopeType.VERTICAL)
1080
                        {
1081
                            x = prevX;
1082
                            SPPIDUtil.ConvertGridPointOnlyOnePoint(ref x);
1083
                        }
1084

    
1085
                        // 마지막이 Symbol일 경우는 Symbol의 좌표를 따라감
1086
                        if (i + 1 == linePointInfo.Count - 1 && linePointInfo[i + 1].Item1 == "SYMBOL")
1087
                        {
1088
                            Line nextLine = linePointInfo[i + 1].Item2;
1089
                            SlopeType nextSlopeType = SPPIDUtil.CalcSlope(nextLine.SPPID.START_X, nextLine.SPPID.START_Y, nextLine.SPPID.END_X, nextLine.SPPID.END_Y);
1090
                            if (slopeType == SlopeType.HORIZONTAL)
1091
                                y = linePointInfo[i + 1].Item5;
1092
                            else if (slopeType == SlopeType.VERTICAL)
1093
                                x = linePointInfo[i + 1].Item4;
1094
                        }
1095
                    }
1096

    
1097
                    if (item.Item1 == "LINE")
1098
                        placeRunInputs.AddConnectorTarget(item.Item3 as LMConnector, x, y);
1099
                    else
1100
                        placeRunInputs.AddPoint(x, y);
1101
                }
1102

    
1103
                prevX = x;
1104
                prevY = y;
1105
                prevSlopeType = slopeType;
1106
            }
1107

    
1108
            LMConnector _lMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1109

    
1110
            if (_lMConnector != null)
1111
            {
1112
                if (_LMSymbol1 != null || _LMSymbol2 != null)
1113
                    ReModelingLine(lines, _lMConnector, _LMSymbol1, _LMSymbol2);
1114
                else
1115
                {
1116
                    foreach (var line in lines)
1117
                        line.SPPID.ModelItemId = _lMConnector.ModelItemID;
1118
                    _lMConnector.Commit();
1119
                }
1120
                if (startBranchLine != null || endBranchLine != null)
1121
                    BranchLines.Add(new Tuple<string, Line, Line>(lines[0].SPPID.ModelItemId, startBranchLine, endBranchLine));
1122
                
1123
            }
1124

    
1125
            if (_LMSymbol1 != null)
1126
                ReleaseCOMObjects(_LMSymbol1);
1127
            if (_LMSymbol2 != null)
1128
                ReleaseCOMObjects(_LMSymbol2);
1129
            if (targetConnector1 != null)
1130
                ReleaseCOMObjects(targetConnector1);
1131
            if (targetConnector2 != null)
1132
                ReleaseCOMObjects(targetConnector2);
1133
            foreach (var item in connectorVertices1)
1134
                ReleaseCOMObjects(item.Key);
1135
            foreach (var item in connectorVertices2)
1136
                ReleaseCOMObjects(item.Key);
1137

    
1138
            ReleaseCOMObjects(_lMConnector);
1139
            ReleaseCOMObjects(placeRunInputs);
1140
            ReleaseCOMObjects(_LMAItem);
1141
        }
1142

    
1143
        /// <summary>
1144
        /// Symbol에 붙을 경우 Line을 Remodeling 한다.
1145
        /// </summary>
1146
        /// <param name="lines"></param>
1147
        /// <param name="prevLMConnector"></param>
1148
        /// <param name="startSymbol"></param>
1149
        /// <param name="endSymbol"></param>
1150
        private void ReModelingLine(List<Line> lines, LMConnector prevLMConnector, LMSymbol startSymbol, LMSymbol endSymbol)
1151
        {
1152
            
1153
            string symbolPath = string.Empty;
1154
            #region get symbol path
1155
            LMModelItem modelItem = dataSource.GetModelItem(prevLMConnector.ModelItemID);
1156
            foreach (LMRepresentation rep in modelItem.Representations)
1157
            {
1158
                if (!DBNull.Value.Equals(rep.get_FileName()) && !string.IsNullOrEmpty(rep.get_FileName()))
1159
                {
1160
                    symbolPath = rep.get_FileName();
1161
                    break;
1162
                }
1163
            }
1164
            #endregion
1165
            _LMAItem _LMAItem = _placement.PIDCreateItem(symbolPath);
1166
            LMConnector newConnector = null;
1167
            dynamic OID = prevLMConnector.get_GraphicOID();
1168
            DependencyObject drawingObject = radApp.ActiveDocument.ActiveSheet.DrawingObjects[OID];
1169
            Ingr.RAD2D.LineStringGeometry2d lineStringGeometry = drawingObject.GetGeometry() as Ingr.RAD2D.LineStringGeometry2d;
1170
            int verticesCount = lineStringGeometry.VertexCount;
1171
            PlaceRunInputs placeRunInputs = new PlaceRunInputs();
1172
            
1173
            List<double[]> vertices = new List<double[]>();
1174
            for (int i = 1; i <= verticesCount; i++)
1175
            {
1176
                double x = 0;
1177
                double y = 0;
1178
                lineStringGeometry.GetVertex(i, ref x, ref y);
1179
                vertices.Add(new double[] { x, y });
1180
            }
1181

    
1182
            for (int i = 0; i < vertices.Count; i++)
1183
            {
1184
                double[] points = vertices[i];
1185
                // 시작 심볼이 있고 첫번째 좌표일 때
1186
                if (startSymbol != null && i == 0)
1187
                {
1188
                    SlopeType slopeType = SPPIDUtil.CalcSlope(points[0], points[1], vertices[i + 1][0], vertices[i + 1][1]);
1189
                    if (slopeType == SlopeType.HORIZONTAL)
1190
                        placeRunInputs.AddPoint(points[0], -0.1);
1191
                    else if (slopeType == SlopeType.VERTICAL)
1192
                        placeRunInputs.AddPoint(-0.1, points[1]);
1193
                    else
1194
                        placeRunInputs.AddPoint(points[0], -0.1);
1195

    
1196
                    placeRunInputs.AddPoint(points[0], points[1]);
1197
                }
1198
                // 마지막 심볼이 있고 마지막 좌표일 때
1199
                else if (endSymbol != null && i == vertices.Count - 1)
1200
                {
1201
                    placeRunInputs.AddPoint(points[0], points[1]);
1202

    
1203
                    SlopeType slopeType = SPPIDUtil.CalcSlope(points[0], points[1], vertices[i - 1][0], vertices[i - 1][1]);
1204
                    if (slopeType == SlopeType.HORIZONTAL)
1205
                        placeRunInputs.AddPoint(points[0], -0.1);
1206
                    else if (slopeType == SlopeType.VERTICAL)
1207
                        placeRunInputs.AddPoint(-0.1, points[1]);
1208
                    else
1209
                        placeRunInputs.AddPoint(points[0], -0.1);
1210
                }
1211
                // 첫번째이며 시작 심볼이 아니고 Connecotr일 경우
1212
                else if (i == 0 && prevLMConnector.ConnectItem1SymbolObject != null)
1213
                    placeRunInputs.AddSymbolTarget(prevLMConnector.ConnectItem1SymbolObject, points[0], points[1]);
1214
                // 마지막이며 마지막 심볼이 아니고 Connecotr일 경우
1215
                else if (i == vertices.Count - 1 && prevLMConnector.ConnectItem2SymbolObject != null)
1216
                    placeRunInputs.AddSymbolTarget(prevLMConnector.ConnectItem2SymbolObject, points[0], points[1]);
1217
                else
1218
                    placeRunInputs.AddPoint(points[0], points[1]);
1219
            }
1220

    
1221
            _placement.PIDRemovePlacement(prevLMConnector.AsLMRepresentation());
1222
            newConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1223

    
1224
            ReleaseCOMObjects(placeRunInputs);
1225
            ReleaseCOMObjects(_LMAItem);
1226
            ReleaseCOMObjects(modelItem);
1227

    
1228
            if (newConnector != null)
1229
            {
1230
                if (startSymbol != null)
1231
                {
1232
                    _LMAItem = _placement.PIDCreateItem(symbolPath);
1233
                    placeRunInputs = new PlaceRunInputs();
1234
                    placeRunInputs.AddSymbolTarget(startSymbol, vertices[0][0], vertices[0][1]);
1235
                    placeRunInputs.AddConnectorTarget(newConnector, vertices[0][0], vertices[0][1]);
1236
                    LMConnector _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1237
                    if (_LMConnector != null)
1238
                    {
1239
                        RemoveConnectorForReModelingLine(newConnector);
1240
                        ZeroLengthModelItemID.Add(_LMConnector.ModelItemID);
1241
                        ReleaseCOMObjects(_LMConnector);
1242
                    }
1243
                    ReleaseCOMObjects(placeRunInputs);
1244
                    ReleaseCOMObjects(_LMAItem);
1245
                }
1246

    
1247
                if (endSymbol != null)
1248
                {
1249
                    if (startSymbol != null)
1250
                    {
1251
                        Dictionary<LMConnector, List<double[]>> dicVertices = GetPipeRunVertices(newConnector.ModelItemID);
1252
                        newConnector = dicVertices.First().Key;
1253
                    }
1254

    
1255
                    _LMAItem = _placement.PIDCreateItem(symbolPath);
1256
                    placeRunInputs = new PlaceRunInputs();
1257
                    placeRunInputs.AddSymbolTarget(endSymbol, vertices[vertices.Count - 1][0], vertices[vertices.Count - 1][1]);
1258
                    placeRunInputs.AddConnectorTarget(newConnector, vertices[vertices.Count - 1][0], vertices[vertices.Count - 1][1]);
1259
                    LMConnector _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1260
                    if (_LMConnector != null)
1261
                    {
1262
                        RemoveConnectorForReModelingLine(newConnector);
1263
                        ZeroLengthModelItemID.Add(_LMConnector.ModelItemID);
1264
                        ReleaseCOMObjects(_LMConnector);
1265
                    }
1266
                    ReleaseCOMObjects(placeRunInputs);
1267
                    ReleaseCOMObjects(_LMAItem);
1268
                }
1269

    
1270
                foreach (var line in lines)
1271
                    line.SPPID.ModelItemId = newConnector.ModelItemID;
1272
                ReleaseCOMObjects(newConnector);
1273
            }
1274

    
1275
            ReleaseCOMObjects(modelItem);
1276
        }
1277

    
1278
        /// <summary>
1279
        /// Remodeling 과정에서 생긴 불필요한 Connector 제거
1280
        /// </summary>
1281
        /// <param name="connector"></param>
1282
        private void RemoveConnectorForReModelingLine(LMConnector connector)
1283
        {
1284
            Dictionary<LMConnector, List<double[]>> dicVertices = GetPipeRunVertices(connector.ModelItemID);
1285
            foreach (var item in dicVertices)
1286
            {
1287
                bool result = false;
1288
                foreach (var point in item.Value)
1289
                {
1290
                    if (point[0] < 0 || point[1] < 0)
1291
                    {
1292
                        result = true;
1293
                        _placement.PIDRemovePlacement(item.Key.AsLMRepresentation());
1294
                        break;
1295
                    }
1296
                }
1297

    
1298
                if (result)
1299
                    break;
1300
            }
1301
            foreach (var item in dicVertices)
1302
                ReleaseCOMObjects(item.Key);
1303
        }
1304

    
1305
        /// <summary>
1306
        /// Symbol이 모델링된 SPPPID Symbol Object를 반환 - 연결된 Symbol이 ChildSymbol일 수도 있기때문에 메서드 개발
1307
        /// </summary>
1308
        /// <param name="symbol"></param>
1309
        /// <param name="line"></param>
1310
        /// <returns></returns>
1311
        private LMSymbol GetTargetSymbol(Symbol symbol, Line line)
1312
        {
1313
            LMSymbol _LMSymbol = null;
1314
            foreach (var connector in symbol.CONNECTORS)
1315
            {
1316
                if (connector.CONNECTEDITEM == line.UID)
1317
                {
1318
                    if (connector.Index == 0)
1319
                        _LMSymbol = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
1320
                    else
1321
                    {
1322
                        ChildSymbol child = null;
1323
                        foreach (var childSymbol in symbol.ChildSymbols)
1324
                        {
1325
                            if (childSymbol.Connectors.Contains(connector))
1326
                                child = childSymbol;
1327
                            else
1328
                                child = GetChildSymbolByConnector(childSymbol, connector);
1329

    
1330
                            if (child != null)
1331
                                break;
1332
                        }
1333

    
1334
                        if (child != null)
1335
                            _LMSymbol = dataSource.GetSymbol(child.SPPID.RepresentationId);
1336
                    }
1337

    
1338
                    break;  
1339
                }
1340
            }
1341

    
1342
            return _LMSymbol;
1343
        }
1344

    
1345
        /// <summary>
1346
        /// Connector를 가지고 있는 ChildSymbol Object 반환
1347
        /// </summary>
1348
        /// <param name="item"></param>
1349
        /// <param name="connector"></param>
1350
        /// <returns></returns>
1351
        private ChildSymbol GetChildSymbolByConnector(ChildSymbol item, Connector connector)
1352
        {
1353
            foreach (var childSymbol in item.ChildSymbols)
1354
            {
1355
                if (childSymbol.Connectors.Contains(connector))
1356
                    return childSymbol;
1357
                else
1358
                    return GetChildSymbolByConnector(childSymbol, connector);
1359
            }
1360

    
1361
            return null;
1362
        }
1363

    
1364
        /// <summary>
1365
        /// Branch 라인을 다시 모델링하는 진입 메서드
1366
        /// </summary>
1367
        /// <param name="branch"></param>
1368
        private void BranchLineModeling(Tuple<string, Line, Line> branch)
1369
        {
1370
            List<Line> lines = SPPIDUtil.FindLinesByModelId(document, branch.Item1);
1371

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

    
1374
            LMConnector _StartConnector = null;
1375
            LMConnector _EndConnector = null;
1376
            double lengthStart = double.MaxValue;
1377
            double lengthEnd = double.MaxValue;
1378
            List<double[]> startPoints = new List<double[]>();
1379
            List<double[]> endPoints = new List<double[]>();
1380

    
1381
            foreach (var item in connectorVertices)
1382
            {
1383
                foreach (var point in item.Value)
1384
                {
1385
                    // Start Point가 Branch
1386
                    if (branch.Item2 != null)
1387
                    {
1388
                        Line targetLine = branch.Item2;
1389
                        double distance = SPPIDUtil.CalcLineToPointDistance(targetLine.SPPID.START_X, targetLine.SPPID.START_Y, targetLine.SPPID.END_X, targetLine.SPPID.END_Y, point[0], point[1]);
1390
                        if (lengthStart > distance)
1391
                        {
1392
                            _StartConnector = item.Key;
1393
                            lengthStart = distance;
1394
                            startPoints = item.Value;
1395
                        }
1396
                    }
1397
                    // End Point가 Branch
1398
                    if (branch.Item3 != null)
1399
                    {
1400
                        Line targetLine = branch.Item3;
1401
                        double distance = SPPIDUtil.CalcLineToPointDistance(targetLine.SPPID.START_X, targetLine.SPPID.START_Y, targetLine.SPPID.END_X, targetLine.SPPID.END_Y, point[0], point[1]);
1402
                        if (lengthEnd > distance)
1403
                        {
1404
                            _EndConnector = item.Key;
1405
                            lengthEnd = distance;
1406
                            endPoints = item.Value;
1407
                        }
1408
                    }
1409
                }
1410
            }
1411
            #region Branch가 양쪽 전부일 때
1412
            if (_StartConnector != null && _StartConnector == _EndConnector)
1413
            {
1414
                _placement.PIDRemovePlacement(_StartConnector.AsLMRepresentation());
1415

    
1416
                _LMAItem _LMAItem = _placement.PIDCreateItem(lines[0].SPPID.MAPPINGNAME);
1417
                PlaceRunInputs placeRunInputs = new PlaceRunInputs();
1418

    
1419
                Dictionary<LMConnector, List<double[]>> startConnectorVertices = GetPipeRunVertices(branch.Item2.SPPID.ModelItemId);
1420
                LMConnector _StartTargetConnector = FindTargetLMConnector(startConnectorVertices, startPoints[0][0], startPoints[0][1], startPoints[1][0], startPoints[1][1]);
1421
                Dictionary<LMConnector, List<double[]>> endConnectorVertices = GetPipeRunVertices(branch.Item3.SPPID.ModelItemId);
1422
                LMConnector _EndTargetConnector = FindTargetLMConnector(endConnectorVertices,
1423
                   startPoints[startPoints.Count - 1][0],
1424
                   startPoints[startPoints.Count - 1][1],
1425
                   startPoints[startPoints.Count - 2][0],
1426
                   startPoints[startPoints.Count - 2][1]);
1427

    
1428
                for (int i = 0; i < startPoints.Count; i++)
1429
                {
1430
                    double[] point = startPoints[i];
1431
                    if (i == 0)
1432
                        placeRunInputs.AddConnectorTarget(_StartTargetConnector, point[0], point[1]);
1433
                    else if (i == startPoints.Count - 1)
1434
                        placeRunInputs.AddConnectorTarget(_EndTargetConnector, point[0], point[1]);
1435
                    else
1436
                        placeRunInputs.AddPoint(point[0], point[1]);
1437
                }
1438

    
1439
                LMConnector _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1440
                if (_LMConnector != null)
1441
                {
1442
                    _LMConnector.Commit();
1443
                    foreach (var item in lines)
1444
                        item.SPPID.ModelItemId = _LMConnector.ModelItemID;
1445
                }
1446

    
1447
                foreach (var item in startConnectorVertices)
1448
                    ReleaseCOMObjects(item.Key);
1449
                foreach (var item in endConnectorVertices)
1450
                    ReleaseCOMObjects(item.Key);
1451
                ReleaseCOMObjects(placeRunInputs);
1452
                ReleaseCOMObjects(_LMAItem);
1453
                ReleaseCOMObjects(_LMConnector);
1454
            }
1455
            #endregion
1456
            #region 양쪽이 다른 Branch 
1457
            else
1458
            {
1459
                // Branch 시작 Connector
1460
                if (_StartConnector != null)
1461
                    BranchLineModelingByConnector(branch, _StartConnector, startPoints, true);
1462

    
1463
                // Branch 끝 Connector
1464
                if (_EndConnector != null)
1465
                    BranchLineModelingByConnector(branch, _EndConnector, endPoints, false);
1466
            }
1467
            #endregion
1468

    
1469
            if (_StartConnector != null)
1470
                ReleaseCOMObjects(_StartConnector);
1471
            if (_EndConnector != null)
1472
                ReleaseCOMObjects(_EndConnector);
1473
            foreach (var item in connectorVertices)
1474
                ReleaseCOMObjects(item.Key);
1475
        }
1476

    
1477
        /// <summary>
1478
        /// Branch 라인을 다시 실제로 모델링하는 메서드
1479
        /// </summary>
1480
        /// <param name="branch"></param>
1481
        /// <param name="_Connector"></param>
1482
        /// <param name="points"></param>
1483
        /// <param name="IsStart"></param>
1484
        private void BranchLineModelingByConnector(Tuple<string, Line, Line> branch, LMConnector _Connector, List<double[]> points, bool IsStart)
1485
        {
1486
            List<Line> lines = SPPIDUtil.FindLinesByModelId(document, branch.Item1);
1487
            Dictionary<LMConnector, List<double[]>> connectorVertices = GetPipeRunVertices(branch.Item1);
1488
            LMConnector _SameRunTargetConnector = null;
1489
            LMSymbol _SameRunTargetSymbol = null;
1490
            Dictionary<LMConnector, List<double[]>> branchConnectorVertices = null;
1491
            LMConnector _BranchTargetConnector = null;
1492
            PlaceRunInputs placeRunInputs = new PlaceRunInputs();
1493

    
1494
            // 같은 Line Run의 Connector 찾기
1495
            foreach (var item in connectorVertices)
1496
            {
1497
                if (item.Key == _Connector)
1498
                    continue;
1499

    
1500
                if (IsStart &&
1501
                    !DBNull.Value.Equals(item.Key.ConnectItem1SymbolID) &&
1502
                    !DBNull.Value.Equals(_Connector.ConnectItem2SymbolID)&& 
1503
                    item.Key.ConnectItem1SymbolID == _Connector.ConnectItem2SymbolID)
1504
                {
1505
                    _SameRunTargetConnector = item.Key;
1506
                    break;
1507
                }
1508
                else if (!IsStart &&
1509
                    !DBNull.Value.Equals(item.Key.ConnectItem2SymbolID) &&
1510
                    !DBNull.Value.Equals(_Connector.ConnectItem1SymbolID) && 
1511
                    item.Key.ConnectItem2SymbolID == _Connector.ConnectItem1SymbolID)
1512
                {
1513
                    _SameRunTargetConnector = item.Key;
1514
                    break;
1515
                }
1516
            }
1517

    
1518
            // Branch 반대편이 Symbol
1519
            if (_SameRunTargetConnector == null)
1520
            {
1521
                foreach (var line in lines)
1522
                {
1523
                    foreach (var connector in line.CONNECTORS)
1524
                    {
1525
                        Symbol symbol = SPPIDUtil.FindObjectByUID(document, connector.CONNECTEDITEM) as Symbol;
1526
                        if (symbol != null)
1527
                        {
1528
                            _SameRunTargetSymbol = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
1529
                            break;
1530
                        }
1531
                    }
1532
                }
1533
            }
1534

    
1535
            // 기존 Connector 제거
1536
            _placement.PIDRemovePlacement(_Connector.AsLMRepresentation());
1537
            
1538
            // 시작 Connector일 경우 첫 Point가 TargetConnector를 찾아야함
1539
            if (IsStart)
1540
            {
1541
                branchConnectorVertices = GetPipeRunVertices(branch.Item2.SPPID.ModelItemId);
1542
                _BranchTargetConnector = FindTargetLMConnector(branchConnectorVertices, points[0][0], points[0][1], points[1][0], points[1][1]);
1543
            }
1544
            // 끝 Conenctor일 경우 마지막 Point가 TargetConnector를 찾아야함
1545
            else
1546
            {
1547
                branchConnectorVertices = GetPipeRunVertices(branch.Item3.SPPID.ModelItemId);
1548
                _BranchTargetConnector = FindTargetLMConnector(branchConnectorVertices,
1549
                    points[points.Count - 1][0],
1550
                    points[points.Count - 1][1],
1551
                    points[points.Count - 2][0],
1552
                    points[points.Count - 2][1]);
1553
            }
1554

    
1555
            for (int i = 0; i < points.Count; i++)
1556
            {
1557
                double[] point = points[i];
1558
                if (i == 0)
1559
                {
1560
                    if (IsStart)
1561
                    {
1562
                        if (_BranchTargetConnector != null)
1563
                        {
1564
                            placeRunInputs.AddConnectorTarget(_BranchTargetConnector, point[0], point[1]);
1565
                        }
1566
                        else
1567
                        {
1568
                            placeRunInputs.AddPoint(point[0], point[1]);
1569
                        }
1570
                        
1571
                    }
1572
                    else
1573
                    {
1574
                        if (_SameRunTargetConnector != null)
1575
                            placeRunInputs.AddConnectorTarget(_SameRunTargetConnector, point[0], point[1]);
1576
                        else if (_SameRunTargetSymbol != null)
1577
                            placeRunInputs.AddSymbolTarget(_SameRunTargetSymbol, point[0], point[1]);
1578
                        else
1579
                            placeRunInputs.AddPoint(point[0], point[1]);
1580
                    }
1581
                }
1582
                else if (i == points.Count - 1)
1583
                {
1584
                    if (IsStart)
1585
                    {
1586
                        if (_SameRunTargetConnector != null)
1587
                            placeRunInputs.AddConnectorTarget(_SameRunTargetConnector, point[0], point[1]);
1588
                        else if (_SameRunTargetSymbol != null)
1589
                            placeRunInputs.AddSymbolTarget(_SameRunTargetSymbol, point[0], point[1]);
1590
                        else
1591
                            placeRunInputs.AddPoint(point[0], point[1]);
1592
                    }
1593
                    else
1594
                    {
1595
                        if (_BranchTargetConnector != null)
1596
                        {
1597
                            placeRunInputs.AddConnectorTarget(_BranchTargetConnector, point[0], point[1]);
1598
                        }
1599
                        else
1600
                        {
1601
                            placeRunInputs.AddPoint(point[0], point[1]);
1602
                        }
1603
                    }
1604
                }
1605
                else
1606
                    placeRunInputs.AddPoint(point[0], point[1]);
1607
            }
1608
            _LMAItem _LMAItem = _placement.PIDCreateItem(lines[0].SPPID.MAPPINGNAME);
1609
            LMConnector _LMConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1610

    
1611
            if (_LMConnector != null)
1612
            {
1613
                if (_SameRunTargetConnector != null)
1614
                {
1615
                    JoinPipeRun(_LMConnector.ModelItemID, _SameRunTargetConnector.ModelItemID);
1616
                }
1617
                else
1618
                {
1619
                    foreach (var item in lines)
1620
                        item.SPPID.ModelItemId = _LMConnector.ModelItemID;
1621
                }
1622

    
1623
                _LMConnector.Commit();
1624
                ReleaseCOMObjects(_LMConnector);
1625
            }
1626

    
1627
            ReleaseCOMObjects(placeRunInputs);
1628
            ReleaseCOMObjects(_LMAItem);
1629
            if (_BranchTargetConnector != null)
1630
                ReleaseCOMObjects(_BranchTargetConnector);
1631
            if (_SameRunTargetConnector != null)
1632
                ReleaseCOMObjects(_SameRunTargetConnector);
1633
            if (_SameRunTargetSymbol != null)
1634
                ReleaseCOMObjects(_SameRunTargetSymbol);
1635
            foreach (var item in connectorVertices)
1636
                ReleaseCOMObjects(item.Key);
1637
            foreach (var item in branchConnectorVertices)
1638
                ReleaseCOMObjects(item.Key);
1639
        }
1640

    
1641
        /// <summary>
1642
        /// EndBreak 모델링 메서드
1643
        /// </summary>
1644
        /// <param name="endBreak"></param>
1645
        private void EndBreakModeling(EndBreak endBreak)
1646
        {
1647
            object ownerObj = SPPIDUtil.FindObjectByUID(document, endBreak.OWNER);
1648
            object connectedItem = SPPIDUtil.FindObjectByUID(document, endBreak.PROPERTIES.Find(x => x.ATTRIBUTE == "Connected Item").VALUE);
1649
            LMConnector targetLMConnector = FindBreakLineTarget(ownerObj, connectedItem);
1650

    
1651
            if (targetLMConnector != null)
1652
            {
1653
                Array array = new double[] { 0, endBreak.SPPID.ORIGINAL_X, endBreak.SPPID.ORIGINAL_Y };
1654
                LMLabelPersist _LmLabelPersist = _placement.PIDPlaceLabel(endBreak.SPPID.MAPPINGNAME, ref array, Rotation: 0, LabeledItem: targetLMConnector.AsLMRepresentation(), IsLeaderVisible: true);
1655
            }
1656
            
1657
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
1658
        }
1659

    
1660
        private LMConnector ReModelingLMConnector(LMConnector connector)
1661
        {
1662
            string symbolPath = string.Empty;
1663
            #region get symbol path
1664
            LMModelItem modelItem = dataSource.GetModelItem(connector.ModelItemID);
1665
            foreach (LMRepresentation rep in modelItem.Representations)
1666
            {
1667
                if (!DBNull.Value.Equals(rep.get_FileName()) && !string.IsNullOrEmpty(rep.get_FileName()))
1668
                {
1669
                    symbolPath = rep.get_FileName();
1670
                    break;
1671
                }
1672
            }
1673
            #endregion
1674

    
1675
            LMConnector newConnector = null;
1676
            dynamic OID = connector.get_GraphicOID();
1677
            DependencyObject drawingObject = radApp.ActiveDocument.ActiveSheet.DrawingObjects[OID];
1678
            Ingr.RAD2D.LineStringGeometry2d lineStringGeometry = drawingObject.GetGeometry() as Ingr.RAD2D.LineStringGeometry2d;
1679
            int verticesCount = lineStringGeometry.VertexCount;
1680
            PlaceRunInputs placeRunInputs = new PlaceRunInputs();
1681
            _LMAItem _LMAItem = _placement.PIDCreateItem(symbolPath);
1682

    
1683
            if (Convert.ToBoolean(connector.get_IsZeroLength()))
1684
            {
1685
                double[] vertices = null;
1686
                lineStringGeometry.GetVertices(ref verticesCount, ref vertices);
1687
                double x = 0;
1688
                double y = 0;
1689
                lineStringGeometry.GetVertex(1, ref x, ref y);
1690

    
1691
                placeRunInputs.AddSymbolTarget(connector.ConnectItem1SymbolObject, x, y);
1692
                placeRunInputs.AddSymbolTarget(connector.ConnectItem2SymbolObject, x, y);
1693

    
1694
                _placement.PIDRemovePlacement(connector.AsLMRepresentation());
1695
                newConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1696
            }
1697
            else
1698
            {
1699
                List<double[]> vertices = new List<double[]>();
1700
                for (int i = 1; i <= verticesCount; i++)
1701
                {
1702
                    double x = 0;
1703
                    double y = 0;
1704
                    lineStringGeometry.GetVertex(i, ref x, ref y);
1705
                    vertices.Add(new double[] { x, y });
1706
                }
1707

    
1708
                for (int i = 0; i < vertices.Count; i++)
1709
                {
1710
                    double[] points = vertices[i];
1711
                    if (i == 0)
1712
                    {
1713
                        if (connector.ConnectItem1SymbolObject != null)
1714
                            placeRunInputs.AddSymbolTarget(connector.ConnectItem1SymbolObject, points[0], points[1]);
1715
                        else
1716
                            placeRunInputs.AddPoint(points[0], points[1]);
1717
                    }
1718
                    else if (i == vertices.Count - 1)
1719
                    {
1720
                        if (connector.ConnectItem2SymbolObject != null)
1721
                            placeRunInputs.AddSymbolTarget(connector.ConnectItem2SymbolObject, points[0], points[1]);
1722
                        else
1723
                            placeRunInputs.AddPoint(points[0], points[1]);
1724
                    }
1725
                    else
1726
                        placeRunInputs.AddPoint(points[0], points[1]);
1727
                }
1728

    
1729
                List<Line> lines = SPPIDUtil.FindLinesByModelId(document, connector.ModelItemID);
1730

    
1731
                _placement.PIDRemovePlacement(connector.AsLMRepresentation());
1732
                newConnector = _placement.PIDPlaceRun(_LMAItem, placeRunInputs);
1733

    
1734
                foreach (var line in lines)
1735
                    line.SPPID.ModelItemId = newConnector.ModelItemID;
1736
            }
1737

    
1738

    
1739
            return newConnector;
1740
        }
1741

    
1742
        /// <summary>
1743
        /// SpecBreak Modeling 메서드
1744
        /// </summary>
1745
        /// <param name="specBreak"></param>
1746
        private void SpecBreakModeling(SpecBreak specBreak)
1747
        {
1748
            object upStreamObj = SPPIDUtil.FindObjectByUID(document, specBreak.UpStreamUID);
1749
            object downStreamObj = SPPIDUtil.FindObjectByUID(document, specBreak.DownStreamUID);
1750

    
1751
            if (upStreamObj != null &&
1752
                downStreamObj != null)
1753
            {
1754
                LMConnector targetLMConnector = FindBreakLineTarget(upStreamObj, downStreamObj);
1755

    
1756
                if (targetLMConnector != null)
1757
                {
1758
                    foreach (var attribute in specBreak.ATTRIBUTES)
1759
                    {
1760
                        AttributeMapping mapping = document.AttributeMappings.Find(x => x.UID == attribute.UID);
1761
                        if (mapping != null && !string.IsNullOrEmpty(mapping.SPPIDSYMBOLNAME) && mapping.SPPIDSYMBOLNAME != "None")
1762
                        {
1763
                            string MappingPath = mapping.SPPIDSYMBOLNAME;
1764
                            Array array = new double[] { 0, specBreak.SPPID.ORIGINAL_X, specBreak.SPPID.ORIGINAL_Y };
1765
                            LMLabelPersist _LmLabelPersist = _placement.PIDPlaceLabel(MappingPath, ref array, Rotation: specBreak.ANGLE, LabeledItem: targetLMConnector.AsLMRepresentation(), IsLeaderVisible: mapping.LeaderLine);
1766

    
1767
                            if (_LmLabelPersist != null)
1768
                            {
1769
                                ReleaseCOMObjects(_LmLabelPersist);
1770
                            }
1771
                        }
1772
                    }
1773
                    ReleaseCOMObjects(targetLMConnector);
1774
                }
1775
            }
1776
        }
1777

    
1778
        private LMConnector FindBreakLineTarget(object targetObj, object connectedObj)
1779
        {
1780
            LMConnector targetConnector = null;
1781
            Symbol targetSymbol = targetObj as Symbol;
1782
            Symbol connectedSymbol = connectedObj as Symbol;
1783
            Line targetLine = targetObj as Line;
1784
            Line connectedLine = connectedObj as Line;
1785
            if (targetSymbol != null && connectedSymbol != null)
1786
            {
1787
                LMSymbol targetLMSymbol = dataSource.GetSymbol(targetSymbol.SPPID.RepresentationId);
1788
                LMSymbol connectedLMSymbol = dataSource.GetSymbol(connectedSymbol.SPPID.RepresentationId);
1789

    
1790
                foreach (LMConnector connector in targetLMSymbol.Avoid1Connectors)
1791
                {
1792
                    if (connector.get_ItemStatus() != "Active")
1793
                        continue;
1794

    
1795
                    if (connector.ConnectItem1SymbolObject.Id == connectedLMSymbol.Id)
1796
                    {
1797
                        targetConnector = connector;
1798
                        break;
1799
                    }
1800
                    else if (connector.ConnectItem2SymbolObject.Id == connectedLMSymbol.Id)
1801
                    {
1802
                        targetConnector = connector;
1803
                        break;
1804
                    }
1805
                }
1806

    
1807
                foreach (LMConnector connector in targetLMSymbol.Avoid2Connectors)
1808
                {
1809
                    if (connector.get_ItemStatus() != "Active")
1810
                        continue;
1811

    
1812
                    if (connector.ConnectItem1SymbolObject.Id == connectedLMSymbol.Id)
1813
                    {
1814
                        targetConnector = connector;
1815
                        break;
1816
                    }
1817
                    else if (connector.ConnectItem2SymbolObject.Id == connectedLMSymbol.Id)
1818
                    {
1819
                        targetConnector = connector;
1820
                        break;
1821
                    }
1822
                }
1823

    
1824
                ReleaseCOMObjects(targetLMSymbol);
1825
                ReleaseCOMObjects(connectedLMSymbol);
1826
            }
1827
            else if (targetLine != null && connectedLine != null)
1828
            {
1829
                LMModelItem targetModelItem = dataSource.GetModelItem(targetLine.SPPID.ModelItemId);
1830
                LMModelItem connectedModelItem = dataSource.GetModelItem(connectedLine.SPPID.ModelItemId);
1831

    
1832
                if (targetModelItem != null && connectedModelItem != null)
1833
                {
1834
                    foreach (LMRepresentation rep in targetModelItem.Representations)
1835
                    {
1836
                        if (targetConnector != null)
1837
                            break;
1838

    
1839
                        if (rep.Attributes["RepresentationType"].get_Value() == "Connector" && rep.Attributes["ItemStatus"].get_Value() == "Active")
1840
                        {
1841
                            LMConnector _LMConnector = dataSource.GetConnector(rep.Id);
1842

    
1843
                            if (IsConnected(_LMConnector, connectedModelItem))
1844
                                targetConnector = _LMConnector;
1845
                            else
1846
                                ReleaseCOMObjects(_LMConnector);
1847
                        }
1848
                    }
1849

    
1850
                    ReleaseCOMObjects(targetModelItem);
1851
                }
1852
            }
1853
            else
1854
            {
1855
                LMSymbol connectedLMSymbol = connectedSymbol != null ? 
1856
                    dataSource.GetSymbol(connectedSymbol.SPPID.RepresentationId) : dataSource.GetSymbol(targetSymbol.SPPID.RepresentationId);
1857
                LMModelItem targetModelItem = targetLine != null ?
1858
                    dataSource.GetModelItem(targetLine.SPPID.ModelItemId) : dataSource.GetModelItem(connectedLine.SPPID.ModelItemId);
1859
                if (connectedLMSymbol != null && targetModelItem != null)
1860
                {
1861
                    foreach (LMConnector connector in connectedLMSymbol.Avoid1Connectors)
1862
                    {
1863
                        if (IsConnected(connector, targetModelItem))
1864
                        {
1865
                            targetConnector = connector;
1866
                            break;
1867
                        }
1868
                    }
1869

    
1870
                    if (targetConnector == null)
1871
                    {
1872
                        foreach (LMConnector connector in connectedLMSymbol.Avoid2Connectors)
1873
                        {
1874
                            if (IsConnected(connector, targetModelItem))
1875
                            {
1876
                                targetConnector = connector;
1877
                                break;
1878
                            }
1879
                        }
1880
                    }
1881
                }
1882

    
1883
            }
1884

    
1885
            return targetConnector;
1886
        }
1887

    
1888
        private bool IsConnected(LMConnector connector, LMModelItem modelItem)
1889
        {
1890
            bool result = false;
1891

    
1892
            foreach (LMRepresentation rep in modelItem.Representations)
1893
            {
1894
                if (result)
1895
                    break;
1896

    
1897
                if (rep.Attributes["RepresentationType"].get_Value() == "Connector" && rep.Attributes["ItemStatus"].get_Value() == "Active")
1898
                {
1899
                    LMConnector _LMConnector = dataSource.GetConnector(rep.Id);
1900

    
1901
                    if (_LMConnector.ConnectItem1SymbolObject != null &&
1902
                        connector.ConnectItem1SymbolObject != null &&
1903
                        _LMConnector.ConnectItem1SymbolObject.Id == connector.ConnectItem1SymbolObject.Id)
1904
                    {
1905
                        result = true;
1906
                        ReleaseCOMObjects(_LMConnector);
1907
                        break;
1908
                    }
1909
                    else if (_LMConnector.ConnectItem1SymbolObject != null &&
1910
                        connector.ConnectItem2SymbolObject != null &&
1911
                        _LMConnector.ConnectItem1SymbolObject.Id == connector.ConnectItem2SymbolObject.Id)
1912
                    {
1913
                        result = true;
1914
                        ReleaseCOMObjects(_LMConnector);
1915
                        break;
1916
                    }
1917
                    else if (_LMConnector.ConnectItem2SymbolObject != null &&
1918
                        connector.ConnectItem1SymbolObject != null &&
1919
                        _LMConnector.ConnectItem2SymbolObject.Id == connector.ConnectItem1SymbolObject.Id)
1920
                    {
1921
                        result = true;
1922
                        ReleaseCOMObjects(_LMConnector);
1923
                        break;
1924
                    }
1925
                    else if (_LMConnector.ConnectItem2SymbolObject != null &&
1926
                        connector.ConnectItem2SymbolObject != null &&
1927
                        _LMConnector.ConnectItem2SymbolObject.Id == connector.ConnectItem2SymbolObject.Id)
1928
                    {
1929
                        result = true;
1930
                        ReleaseCOMObjects(_LMConnector);
1931
                        break;
1932
                    }
1933

    
1934
                    ReleaseCOMObjects(_LMConnector);
1935
                }
1936
            }
1937

    
1938

    
1939
            return result;
1940
        }
1941

    
1942
        /// <summary>
1943
        /// FromModelItem을 ToModelItem으로 PipeRunJoin하는 메서드
1944
        /// </summary>
1945
        /// <param name="fromModelItemId"></param>
1946
        /// <param name="toModelItemId"></param>
1947
        private void JoinPipeRun(string fromModelItemId, string toModelItemId)
1948
        {
1949
            LMModelItem modelItem1 = dataSource.GetModelItem(toModelItemId);
1950
            _LMAItem item1 = modelItem1.AsLMAItem();
1951
            LMModelItem modelItem2 = dataSource.GetModelItem(fromModelItemId);
1952
            _LMAItem item2 = modelItem2.AsLMAItem();
1953
            
1954
            // item2가 item1으로 조인
1955
            try
1956
            {
1957
                _placement.PIDJoinRuns(ref item1, ref item2);
1958
                item1.Commit();
1959
                item2.Commit();
1960

    
1961
                List<Line> lines = SPPIDUtil.FindLinesByModelId(document, fromModelItemId);
1962
                foreach (var line in lines)
1963
                    line.SPPID.ModelItemId = toModelItemId;
1964
            }
1965
            catch (Exception ex)
1966
            {
1967
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
1968
            }
1969
            finally
1970
            {
1971
                ReleaseCOMObjects(modelItem1);
1972
                ReleaseCOMObjects(item1);
1973
                ReleaseCOMObjects(modelItem2);
1974
                ReleaseCOMObjects(item2);
1975
            }
1976
        }
1977

    
1978
        /// <summary>
1979
        /// PipeRun을 자동으로 Join하는 메서드
1980
        /// </summary>
1981
        /// <param name="modelItemId"></param>
1982
        private void AutoJoinPipeRun(string modelItemId)
1983
        {
1984
            LMModelItem modelItem = dataSource.GetModelItem(modelItemId);
1985
            _LMAItem item = modelItem.AsLMAItem();
1986
            try
1987
            {
1988
                if (modelItem.get_ItemStatus() == "Active")
1989
                {
1990
                    string modelitemID = item.Id;
1991
                    _placement.PIDAutoJoin(item, AutoJoinEndConstants.autoJoin_Both, ref item);
1992
                    string afterModelItemID = item.Id;
1993

    
1994
                    if (modelitemID != afterModelItemID)
1995
                    {
1996
                        List<Line> lines = SPPIDUtil.FindLinesByModelId(document, modelitemID);
1997
                        foreach (var line in lines)
1998
                            line.SPPID.ModelItemId = afterModelItemID;
1999
                    }
2000
                    item.Commit();
2001
                }
2002
            }
2003
            catch (Exception ex)
2004
            {
2005
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
2006
            }
2007
            finally
2008
            {
2009
                ReleaseCOMObjects(modelItem);
2010
                ReleaseCOMObjects(item);
2011
            }
2012
        }
2013

    
2014
        /// <summary>
2015
        /// LineRun에 있는 Line들을 Join하는 진입 메서드
2016
        /// </summary>
2017
        /// <param name="run"></param>
2018
        private void JoinRunLine(LineRun run)
2019
        {
2020
            string modelItemId = string.Empty;
2021
            foreach (var item in run.RUNITEMS)
2022
            {
2023
                if (item.GetType() == typeof(Line))
2024
                {
2025
                    Line line = item as Line;
2026
                    AutoJoinPipeRun(line.SPPID.ModelItemId);
2027
                    modelItemId = line.SPPID.ModelItemId;
2028

    
2029
                    SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2030
                }
2031
            }
2032
        }
2033

    
2034
        /// <summary>
2035
        /// PipeRun의 좌표를 가져오는 메서드
2036
        /// </summary>
2037
        /// <param name="modelId"></param>
2038
        /// <returns></returns>
2039
        private Dictionary<LMConnector, List<double[]>> GetPipeRunVertices(string modelId)
2040
        {
2041
            Dictionary<LMConnector, List<double[]>> connectorVertices = new Dictionary<LMConnector, List<double[]>>();
2042
            LMModelItem modelItem = dataSource.GetModelItem(modelId);
2043

    
2044
            if (modelItem != null)
2045
            {
2046
                foreach (LMRepresentation rep in modelItem.Representations)
2047
                {
2048
                    if (rep.Attributes["RepresentationType"].get_Value() == "Connector" && rep.Attributes["ItemStatus"].get_Value() == "Active")
2049
                    {
2050
                        LMConnector _LMConnector = dataSource.GetConnector(rep.Id);
2051
                        connectorVertices.Add(_LMConnector, new List<double[]>());
2052
                        dynamic OID = rep.get_GraphicOID();
2053
                        DependencyObject drawingObject = radApp.ActiveDocument.ActiveSheet.DrawingObjects[OID];
2054
                        Ingr.RAD2D.LineStringGeometry2d lineStringGeometry = drawingObject.GetGeometry() as Ingr.RAD2D.LineStringGeometry2d;
2055
                        int verticesCount = lineStringGeometry.VertexCount;
2056
                        double[] vertices = null;
2057
                        lineStringGeometry.GetVertices(ref verticesCount, ref vertices);
2058
                        for (int i = 0; i < verticesCount; i++)
2059
                        {
2060
                            double x = 0;
2061
                            double y = 0;
2062
                            lineStringGeometry.GetVertex(i + 1, ref x, ref y);
2063
                            connectorVertices[_LMConnector].Add(new double[] { Math.Round(x, 10), Math.Round(y, 10) });
2064
                        }
2065
                    }
2066
                }
2067

    
2068
                ReleaseCOMObjects(modelItem);
2069
            }
2070

    
2071
            return connectorVertices;
2072
        }
2073

    
2074
        /// <summary>
2075
        /// LMConnector들을 가져온다.
2076
        /// </summary>
2077
        /// <param name="modelId"></param>
2078
        /// <returns></returns>
2079
        private List<LMConnector> GetConnectors(string modelId)
2080
        {
2081
            List<LMConnector> connectors = new List<LMConnector>();
2082
            LMModelItem modelItem = dataSource.GetModelItem(modelId);
2083

    
2084
            if (modelItem != null)
2085
            {
2086
                foreach (LMRepresentation rep in modelItem.Representations)
2087
                {
2088
                    if (rep.Attributes["RepresentationType"].get_Value() == "Connector" && rep.Attributes["ItemStatus"].get_Value() == "Active")
2089
                    {
2090
                        LMConnector _LMConnector = dataSource.GetConnector(rep.Id);
2091
                        connectors.Add(_LMConnector);
2092
                    }
2093
                }
2094

    
2095
                ReleaseCOMObjects(modelItem);
2096
            }
2097

    
2098
            return connectors;
2099
        }
2100

    
2101
        /// <summary>
2102
        /// 좌표로 PipeRun의 Connector중에 어느 Connector에 가까운지/붙을지 가져오는 메서드 - 두점으로 라인의 교차점을 기준으로 구함
2103
        /// </summary>
2104
        /// <param name="connectorVertices"></param>
2105
        /// <param name="connX"></param>
2106
        /// <param name="connY"></param>
2107
        /// <param name="x2"></param>
2108
        /// <param name="y2"></param>
2109
        /// <returns></returns>
2110
        private LMConnector FindTargetLMConnector(Dictionary<LMConnector, List<double[]>> connectorVertices, double connX, double connY, double x2, double y2)
2111
        {
2112
            double length = double.MaxValue;
2113
            LMConnector targetConnector = null;
2114
            foreach (var item in connectorVertices)
2115
            {
2116
                List<double[]> points = item.Value;
2117
                for (int i = 0; i < points.Count - 1; i++)
2118
                {
2119
                    double[] point1 = points[i];
2120
                    double[] point2 = points[i + 1];
2121

    
2122
                    double maxLineX = Math.Max(point1[0], point2[0]);
2123
                    double minLineX = Math.Min(point1[0], point2[0]);
2124
                    double maxLineY = Math.Max(point1[1], point2[1]);
2125
                    double minLineY = Math.Min(point1[1], point2[1]);
2126

    
2127
                    SlopeType slope = SPPIDUtil.CalcSlope(minLineX, minLineY, maxLineX, maxLineY);
2128

    
2129
                    // 두직선의 교차점
2130
                    double[] crossingPoint = SPPIDUtil.CalcLineCrossingPoint(connX, connY, x2, y2, point1[0], point1[1], point2[0], point2[1]);
2131
                    if (crossingPoint != null)
2132
                    {
2133
                        double distance = SPPIDUtil.CalcPointToPointdDistance(connX, connY, crossingPoint[0], crossingPoint[1]);
2134
                        if (length >= distance)
2135
                        {
2136
                            if (slope == SlopeType.Slope &&
2137
                                minLineX <= crossingPoint[0] && maxLineX >= crossingPoint[0] &&
2138
                                minLineY <= crossingPoint[1] && maxLineY >= crossingPoint[1])
2139
                            {
2140
                                targetConnector = item.Key;
2141
                                length = distance;
2142
                            }
2143
                            else if (slope == SlopeType.HORIZONTAL &&
2144
                                minLineX <= crossingPoint[0] && maxLineX >= crossingPoint[0])
2145
                            {
2146
                                targetConnector = item.Key;
2147
                                length = distance;
2148
                            }
2149
                            else if (slope == SlopeType.VERTICAL &&
2150
                               minLineY <= crossingPoint[1] && maxLineY >= crossingPoint[1])
2151
                            {
2152
                                targetConnector = item.Key;
2153
                                length = distance;
2154
                            }
2155
                        }
2156
                    }
2157
                }
2158

    
2159

    
2160
            }
2161

    
2162
            if (targetConnector == null)
2163
            {
2164
                foreach (var item in connectorVertices)
2165
                {
2166
                    List<double[]> points = item.Value;
2167
                    foreach (var point in points)
2168
                    {
2169
                        double distance = SPPIDUtil.CalcPointToPointdDistance(connX, connY, point[0], point[1]);
2170
                        if (length >= distance)
2171
                        {
2172
                            targetConnector = item.Key;
2173
                            length = distance;
2174
                        }
2175
                    }
2176
                }
2177

    
2178
            }
2179

    
2180
            return targetConnector;
2181
        }
2182

    
2183
        /// <summary>
2184
        /// 좌표로 PipeRun의 Connector중에 어느 Connector에 가까운지/붙을지 가져오는 메서드 - 한점으로 제일 가까운 기준으로 구함(단순)
2185
        /// </summary>
2186
        /// <param name="connectorVertices"></param>
2187
        /// <param name="connX"></param>
2188
        /// <param name="connY"></param>
2189
        /// <returns></returns>
2190
        private LMConnector FindTargetLMConnectorByPoint(Dictionary<LMConnector, List<double[]>> connectorVertices, double connX, double connY)
2191
        {
2192
            double length = double.MaxValue;
2193
            LMConnector targetConnector = null;
2194
            foreach (var item in connectorVertices)
2195
            {
2196
                List<double[]> points = item.Value;
2197

    
2198
                foreach (double[] point in points)
2199
                {
2200
                    double distance = SPPIDUtil.CalcPointToPointdDistance(point[0], point[1], connX, connY);
2201
                    if (length >= distance)
2202
                    {
2203
                        targetConnector = item.Key;
2204
                        length = distance;
2205
                    }
2206
                }
2207
            }
2208

    
2209
            return targetConnector;
2210
        }
2211

    
2212
        /// <summary>
2213
        /// 좌표로 PipeRun의 Connector중에 어느 Connector에 가까운지/붙을지 가져오는 메서드 - 조건에 안맞아서 못찾을시 제일 가까운 점으로 가져오는 방식
2214
        /// </summary>
2215
        /// <param name="connectorVertices"></param>
2216
        /// <param name="connX"></param>
2217
        /// <param name="connY"></param>
2218
        /// <returns></returns>
2219
        private LMConnector FindTargetLMConnectorForLabel(Dictionary<LMConnector, List<double[]>> connectorVertices, double connX, double connY)
2220
        {
2221
            double length = double.MaxValue;
2222
            LMConnector targetConnector = null;
2223
            foreach (var item in connectorVertices)
2224
            {
2225
                List<double[]> points = item.Value;
2226
                for (int i = 0; i < points.Count - 1; i++)
2227
                {
2228
                    double[] point1 = points[i];
2229
                    double[] point2 = points[i + 1];
2230
                    double x1 = Math.Min(point1[0], point2[0]);
2231
                    double y1 = Math.Min(point1[1], point2[1]);
2232
                    double x2 = Math.Max(point1[0], point2[0]);
2233
                    double y2 = Math.Max(point1[1], point2[1]);
2234

    
2235
                    if ((x1 <= connX && x2 >= connX) ||
2236
                        (y1 <= connY && y2 >= connY))
2237
                    {
2238
                        double distance = SPPIDUtil.CalcPointToPointdDistance(point1[0], point1[1], connX, connY);
2239
                        if (length >= distance)
2240
                        {
2241
                            targetConnector = item.Key;
2242
                            length = distance;
2243
                        }
2244

    
2245
                        distance = SPPIDUtil.CalcPointToPointdDistance(point2[0], point2[1], connX, connY);
2246
                        if (length >= distance)
2247
                        {
2248
                            targetConnector = item.Key;
2249
                            length = distance;
2250
                        }
2251
                    }
2252
                }
2253
            }
2254

    
2255
            // 못찾았을때.
2256
            length = double.MaxValue;
2257
            if (targetConnector == null)
2258
            {
2259
                foreach (var item in connectorVertices)
2260
                {
2261
                    List<double[]> points = item.Value;
2262

    
2263
                    foreach (double[] point in points)
2264
                    {
2265
                        double distance = SPPIDUtil.CalcPointToPointdDistance(point[0], point[1], connX, connY);
2266
                        if (length >= distance)
2267
                        {
2268
                            targetConnector = item.Key;
2269
                            length = distance;
2270
                        }
2271
                    }
2272
                }
2273
            }
2274

    
2275
            return targetConnector;
2276
        }
2277

    
2278
        /// <summary>
2279
        /// Line Number Symbol을 실제로 Modeling하는 메서드
2280
        /// </summary>
2281
        /// <param name="lineNumber"></param>
2282
        private void LineNumberModeling(LineNumber lineNumber)
2283
        {
2284
            Line line = SPPIDUtil.FindObjectByUID(document, lineNumber.CONNLINE) as Line;
2285
            Dictionary<LMConnector, List<double[]>> connectorVertices = GetPipeRunVertices(line.SPPID.ModelItemId);
2286
            LMConnector connectedLMConnector = FindTargetLMConnectorForLabel(connectorVertices, lineNumber.SPPID.ORIGINAL_X, lineNumber.SPPID.ORIGINAL_Y);
2287
            if (connectedLMConnector != null)
2288
            {
2289
                double x = 0;
2290
                double y = 0;
2291
                CalcLabelLocation(ref x, ref y, lineNumber.SPPID.ORIGINAL_X, lineNumber.SPPID.ORIGINAL_Y, lineNumber.SPPIDLabelLocation, _ETCSetting.LineNumberLocation);
2292

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

    
2296
                foreach (var item in connectorVertices)
2297
                    ReleaseCOMObjects(item.Key);
2298
                if (_LmLabelPresist != null)
2299
                {
2300
                    _LmLabelPresist.Commit();
2301
                    lineNumber.SPPID.RepresentationId = _LmLabelPresist.AsLMRepresentation().Id;
2302
                    ReleaseCOMObjects(_LmLabelPresist);
2303
                }
2304
                else
2305
                {
2306

    
2307
                }
2308
            }
2309

    
2310
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2311
        }
2312

    
2313
        /// <summary>
2314
        /// Flow Mark Modeling
2315
        /// </summary>
2316
        /// <param name="line"></param>
2317
        private void FlowMarkModeling(Line line)
2318
        {
2319
            if (line.FLOWMARK && !string.IsNullOrEmpty(line.SPPID.ModelItemId) && !string.IsNullOrEmpty(_ETCSetting.FlowMarkSymbolPath))
2320
            {
2321
                SlopeType targetSlopeType = SPPIDUtil.CalcSlope(line.SPPID.START_X, line.SPPID.START_Y, line.SPPID.END_X, line.SPPID.END_Y);
2322
                string mappingPath = _ETCSetting.FlowMarkSymbolPath;
2323
                double percent = line.FLOWMARK_PERCENT;
2324
                double tempX = 0;
2325
                double tempY = 0;
2326

    
2327
                double gapX;
2328
                double gapY;
2329
                // ID2 기준의 Gap을 구함
2330
                if (percent == 0)
2331
                {
2332
                    gapX = 0;
2333
                    gapY = 0;
2334
                }
2335
                else
2336
                {
2337
                    gapX = Math.Abs(line.SPPID.START_X - line.SPPID.END_X) / 100 * percent;
2338
                    gapY = Math.Abs(line.SPPID.START_Y - line.SPPID.END_Y) / 100 * percent;
2339
                }
2340

    
2341
                if (line.SPPID.START_X < line.SPPID.END_X)
2342
                    tempX = line.SPPID.START_X + gapX;
2343
                else
2344
                    tempX = line.SPPID.START_X - gapX;
2345

    
2346
                if (line.SPPID.START_Y < line.SPPID.END_Y)
2347
                    tempY = line.SPPID.START_Y + gapY;
2348
                else
2349
                    tempY = line.SPPID.START_Y - gapY;
2350

    
2351
                
2352
               
2353
                Dictionary<LMConnector, List<double[]>> connectorVertices = GetPipeRunVertices(line.SPPID.ModelItemId);
2354
                LMConnector _TargetItem = null;
2355
                double distance = double.MaxValue;
2356
                double[] startPoint = null;
2357
                double[] endPoint = null;
2358
                // ID2의 기준 Gap으로 제일 가까운 Line 찾음(Slope도 같은조건)
2359
                foreach (var item in connectorVertices)
2360
                {
2361
                    for (int i = 0; i < item.Value.Count - 1; i++)
2362
                    {
2363
                        List<double[]> points = item.Value;
2364
                        double[] point1 = points[i];
2365
                        double[] point2 = points[i + 1];
2366

    
2367
                        SlopeType slopeType = SPPIDUtil.CalcSlope(point1[0], point1[1], point2[0], point2[1]);
2368
                        if (slopeType == targetSlopeType)
2369
                        {
2370
                            double result = SPPIDUtil.CalcPointToPointdDistance(point1[0], point1[1], tempX, tempY);
2371
                            if (result < distance)
2372
                            {
2373
                                distance = result;
2374
                                _TargetItem = item.Key;
2375

    
2376
                                startPoint = point1;
2377
                                endPoint = point2;
2378
                            }
2379

    
2380
                            result = SPPIDUtil.CalcPointToPointdDistance(point2[0], point2[1], tempX, tempY);
2381
                            if (result < distance)
2382
                            {
2383
                                distance = result;
2384
                                _TargetItem = item.Key;
2385

    
2386
                                startPoint = point1;
2387
                                endPoint = point2;
2388
                            }
2389
                        }
2390
                    }
2391
                }
2392

    
2393
                if (_TargetItem != null)
2394
                {
2395
                    double x = 0;
2396
                    double y = 0;
2397
                    double angle = 0;
2398
                    // SPPID 기준의 Gap으로 실 좌표를 구함
2399
                    if (percent == 0)
2400
                    {
2401
                        gapX = 0;
2402
                        gapY = 0;
2403
                    }
2404
                    else
2405
                    {
2406
                        gapX = Math.Abs(startPoint[0] - endPoint[0]) / 100 * percent;
2407
                        gapY = Math.Abs(startPoint[1] - endPoint[1]) / 100 * percent;
2408
                    }
2409

    
2410
                    if (startPoint[0] < endPoint[0])
2411
                        x = startPoint[0] + gapX;
2412
                    else
2413
                        x = startPoint[0] - gapX;
2414

    
2415
                    if (startPoint[1] < endPoint[1])
2416
                        y = startPoint[1] + gapY;
2417
                    else
2418
                        y = startPoint[1] - gapY;
2419
                    
2420
                    if (targetSlopeType == SlopeType.HORIZONTAL)
2421
                    {
2422
                        if (startPoint[0] < endPoint[0])
2423
                            angle = 0;
2424
                        else
2425
                            angle = Math.PI;
2426
                    }
2427
                    // 90 270
2428
                    else if (targetSlopeType == SlopeType.VERTICAL)
2429
                    {
2430
                        if (startPoint[1] < endPoint[1])
2431
                            angle = 90 * Math.PI / 180;
2432
                        else
2433
                            angle = 270 * Math.PI / 180;
2434
                    }
2435

    
2436
                    LMSymbol _LMSymbol = _placement.PIDPlaceSymbol(mappingPath, x, y, Mirror: 0, Rotation: angle, TargetItem: _TargetItem);
2437
                    
2438
                    if (_LMSymbol != null)
2439
                    {
2440
                        ReleaseCOMObjects(_LMSymbol);
2441
                    }
2442
                        
2443
                }
2444

    
2445
                foreach (var item in connectorVertices)
2446
                    ReleaseCOMObjects(item.Key);
2447
            }
2448
        }
2449

    
2450
        /// <summary>
2451
        /// Line Number 기준으로 모든 Item에 Line Number의 Attribute Input
2452
        /// </summary>
2453
        /// <param name="lineNumber"></param>
2454
        private void InputLineNumberAttribute(LineNumber lineNumber)
2455
        {
2456
            foreach (LineRun run in lineNumber.RUNS)
2457
            {
2458
                foreach (var item in run.RUNITEMS)
2459
                {
2460
                    if (item.GetType() == typeof(Symbol))
2461
                    {
2462
                        Symbol symbol = item as Symbol;
2463
                        LMSymbol _LMSymbol = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
2464
                        LMModelItem _LMModelItem = _LMSymbol.ModelItemObject;
2465

    
2466
                        if (_LMModelItem != null && _LMModelItem.get_ItemStatus() == "Active")
2467
                        {
2468
                            foreach (var attribute in lineNumber.ATTRIBUTES)
2469
                            {
2470
                                LineNumberMapping mapping = document.LineNumberMappings.Find(x => x.UID == attribute.UID);
2471
                                if (mapping != null && !string.IsNullOrEmpty(attribute.VALUE) && attribute.VALUE != "None")
2472
                                {
2473
                                    LMAAttribute _LMAAttribute = _LMModelItem.Attributes[mapping.SPPIDATTRIBUTENAME];
2474
                                    if (_LMAAttribute != null)
2475
                                    {
2476
                                        if (DBNull.Value.Equals(_LMAAttribute.get_Value()))
2477
                                            _LMAAttribute.set_Value(attribute.VALUE);
2478
                                        else if (_LMAAttribute.get_Value() != attribute.VALUE)
2479
                                            _LMAAttribute.set_Value(attribute.VALUE);
2480
                                    }
2481
                                }
2482
                            }
2483
                            _LMModelItem.Commit();
2484
                        }
2485
                        if (_LMModelItem != null)
2486
                            ReleaseCOMObjects(_LMModelItem);
2487
                        if (_LMSymbol != null)
2488
                            ReleaseCOMObjects(_LMSymbol);
2489
                    }
2490
                    else if (item.GetType() == typeof(Line))
2491
                    {
2492
                        Line line = item as Line;
2493
                        if (line != null)
2494
                        {
2495
                            LMModelItem _LMModelItem = dataSource.GetModelItem(line.SPPID.ModelItemId);
2496
                            if (_LMModelItem != null && _LMModelItem.get_ItemStatus() == "Active")
2497
                            {
2498
                                foreach (var attribute in lineNumber.ATTRIBUTES)
2499
                                {
2500
                                    LineNumberMapping mapping = document.LineNumberMappings.Find(x => x.UID == attribute.UID);
2501
                                    if (mapping != null && !string.IsNullOrEmpty(attribute.VALUE) && attribute.VALUE != "None")
2502
                                    {
2503
                                        LMAAttribute _LMAAttribute = _LMModelItem.Attributes[mapping.SPPIDATTRIBUTENAME];
2504
                                        if (_LMAAttribute != null)
2505
                                        {
2506
                                            if (DBNull.Value.Equals(_LMAAttribute.get_Value()))
2507
                                                _LMAAttribute.set_Value(attribute.VALUE);
2508
                                            else if (_LMAAttribute.get_Value() != attribute.VALUE)
2509
                                                _LMAAttribute.set_Value(attribute.VALUE);
2510
                                            
2511
                                        }
2512
                                    }
2513
                                }
2514
                                _LMModelItem.Commit();
2515
                            }
2516
                            if (_LMModelItem != null)
2517
                                ReleaseCOMObjects(_LMModelItem);
2518
                        }
2519
                    }
2520
                }
2521
            }
2522

    
2523
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2524
        }
2525

    
2526
        /// <summary>
2527
        /// Symbol Attribute 입력 메서드
2528
        /// </summary>
2529
        /// <param name="item"></param>
2530
        private void InputSymbolAttribute(object targetItem, List<BaseModel.Attribute> targetAttributes)
2531
        {
2532
            try
2533
            {
2534
                // Object 아이템이 Symbol일 경우 Equipment일 경우 
2535
                string sRep = null;
2536
                if (targetItem.GetType() == typeof(Symbol))
2537
                    sRep = ((Symbol)targetItem).SPPID.RepresentationId;
2538
                else if (targetItem.GetType() == typeof(Equipment))
2539
                    sRep = ((Equipment)targetItem).SPPID.RepresentationId;
2540
                    
2541
                if (!string.IsNullOrEmpty(sRep))
2542
                {
2543
                    LMSymbol _LMSymbol = dataSource.GetSymbol(sRep);
2544
                    LMModelItem _LMModelItem = _LMSymbol.ModelItemObject;
2545
                    LMAAttributes _Attributes = _LMModelItem.Attributes;
2546

    
2547
                    foreach (var item in targetAttributes)
2548
                    {
2549
                        AttributeMapping mapping = document.AttributeMappings.Find(x => x.UID == item.UID);
2550
                        if (mapping != null && !string.IsNullOrEmpty(item.VALUE) && item.VALUE != "None")
2551
                        {
2552
                            LMAAttribute _Attribute = _Attributes[mapping.SPPIDATTRIBUTENAME];
2553
                            if (_Attribute != null)
2554
                                _Attribute.set_Value(item.VALUE);
2555
                        }
2556
                    }
2557
                    _LMModelItem.Commit();
2558
                    
2559
                    ReleaseCOMObjects(_Attributes);
2560
                    ReleaseCOMObjects(_LMModelItem);
2561
                    ReleaseCOMObjects(_LMSymbol);
2562
                }
2563
            }
2564
            catch (Exception ex)
2565
            {
2566
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
2567
            }
2568

    
2569
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2570
        }
2571

    
2572
        /// <summary>
2573
        /// Input SpecBreak Attribute
2574
        /// </summary>
2575
        /// <param name="specBreak"></param>
2576
        private void InputSpecBreakAttribute(SpecBreak specBreak)
2577
        {
2578
            try
2579
            {
2580
                object upStreamObj = SPPIDUtil.FindObjectByUID(document, specBreak.UpStreamUID);
2581
                object downStreamObj = SPPIDUtil.FindObjectByUID(document, specBreak.DownStreamUID);
2582

    
2583
                if (upStreamObj != null &&
2584
                    downStreamObj != null)
2585
                {
2586
                    LMConnector targetLMConnector = FindBreakLineTarget(upStreamObj, downStreamObj);
2587

    
2588
                    if (targetLMConnector != null)
2589
                    {
2590
                        foreach (LMLabelPersist _LMLabelPersist in targetLMConnector.LabelPersists)
2591
                        {
2592
                            string symbolPath = _LMLabelPersist.get_FileName();
2593
                            AttributeMapping mapping = document.AttributeMappings.Find(x => x.SPPIDSYMBOLNAME == symbolPath);
2594
                            if (mapping != null)
2595
                            {
2596
                                BaseModel.Attribute attribute = specBreak.ATTRIBUTES.Find(y => y.UID == mapping.UID);
2597
                                if (attribute != null && !string.IsNullOrEmpty(attribute.VALUE) && attribute.VALUE != "None")
2598
                                {
2599
                                    string[] values = attribute.VALUE.Split(new char[] { ',' });
2600
                                    if (values.Length == 2)
2601
                                    {
2602
                                        string upStreamValue = values[0];
2603
                                        string downStreamValue = values[1];
2604

    
2605
                                        InputAttributeForSpecBreak(upStreamObj, downStreamObj, upStreamValue, downStreamValue, mapping.SPPIDATTRIBUTENAME);
2606
                                    }
2607
                                }
2608
                            }
2609
                        }
2610

    
2611
                        ReleaseCOMObjects(targetLMConnector);
2612
                    }
2613
                }
2614
            }
2615
            catch (Exception ex)
2616
            {
2617
                System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
2618
            }
2619

    
2620
            #region 내부에서만 쓰는 메서드
2621
            void InputAttributeForSpecBreak(object upStreamObj, object downStreamObj, string upStreamValue, string downStreamValue, string sppidAttributeName)
2622
            {
2623
                try
2624
                {
2625
                    Symbol upStreamSymbol = upStreamObj as Symbol;
2626
                    Line upStreamLine = upStreamObj as Line;
2627
                    Symbol downStreamSymbol = downStreamObj as Symbol;
2628
                    Line downStreamLine = downStreamObj as Line;
2629
                    // 둘다 Line일 경우
2630
                    if (upStreamLine != null && downStreamLine != null)
2631
                    {
2632
                        InputLineAttributeForSpecBreakLine(upStreamLine, sppidAttributeName, upStreamValue);
2633
                        InputLineAttributeForSpecBreakLine(downStreamLine, sppidAttributeName, downStreamValue);
2634
                    }
2635
                    // 둘다 Symbol일 경우
2636
                    else if (upStreamSymbol != null && downStreamSymbol != null)
2637
                    {
2638
                        LMConnector zeroLenthConnector = FindBreakLineTarget(upStreamSymbol, downStreamSymbol);
2639
                        LMSymbol upStreamLMSymbol = dataSource.GetSymbol(upStreamSymbol.SPPID.RepresentationId);
2640
                        LMSymbol downStreamLMSymbol = dataSource.GetSymbol(downStreamSymbol.SPPID.RepresentationId);
2641

    
2642
                        foreach (LMConnector connector in upStreamLMSymbol.Avoid1Connectors)
2643
                        {
2644
                            if (connector.get_ItemStatus() != "Active")
2645
                                continue;
2646

    
2647
                            if (connector.Id != zeroLenthConnector.Id)
2648
                                InputLineAttributeForSpecBreakLMConnector(connector, sppidAttributeName, upStreamValue);
2649
                        }
2650

    
2651
                        foreach (LMConnector connector in upStreamLMSymbol.Avoid2Connectors)
2652
                        {
2653
                            if (connector.get_ItemStatus() != "Active")
2654
                                continue;
2655

    
2656
                            if (connector.Id != zeroLenthConnector.Id)
2657
                                InputLineAttributeForSpecBreakLMConnector(connector, sppidAttributeName, upStreamValue);
2658
                        }
2659

    
2660
                        foreach (LMConnector connector in downStreamLMSymbol.Avoid1Connectors)
2661
                        {
2662
                            if (connector.get_ItemStatus() != "Active")
2663
                                continue;
2664

    
2665
                            if (connector.Id != zeroLenthConnector.Id)
2666
                                InputLineAttributeForSpecBreakLMConnector(connector, sppidAttributeName, downStreamValue);
2667
                        }
2668

    
2669
                        foreach (LMConnector connector in downStreamLMSymbol.Avoid2Connectors)
2670
                        {
2671
                            if (connector.get_ItemStatus() != "Active")
2672
                                continue;
2673

    
2674
                            if (connector.Id != zeroLenthConnector.Id)
2675
                                InputLineAttributeForSpecBreakLMConnector(connector, sppidAttributeName, downStreamValue);
2676
                        }
2677

    
2678
                        ReleaseCOMObjects(zeroLenthConnector);
2679
                        ReleaseCOMObjects(upStreamLMSymbol);
2680
                        ReleaseCOMObjects(downStreamLMSymbol);
2681
                    }
2682
                    else if (upStreamSymbol != null && downStreamLine != null)
2683
                    {
2684
                        LMConnector zeroLenthConnector = FindBreakLineTarget(upStreamSymbol, downStreamLine);
2685
                        InputLineAttributeForSpecBreakLine(downStreamLine, sppidAttributeName, downStreamValue);
2686
                        LMSymbol upStreamLMSymbol = dataSource.GetSymbol(upStreamSymbol.SPPID.RepresentationId);
2687

    
2688
                        foreach (LMConnector connector in upStreamLMSymbol.Avoid1Connectors)
2689
                        {
2690
                            if (connector.get_ItemStatus() != "Active")
2691
                                continue;
2692

    
2693
                            if (connector.Id != zeroLenthConnector.Id)
2694
                                InputLineAttributeForSpecBreakLMConnector(connector, sppidAttributeName, upStreamValue);
2695
                        }
2696

    
2697
                        foreach (LMConnector connector in upStreamLMSymbol.Avoid2Connectors)
2698
                        {
2699
                            if (connector.get_ItemStatus() != "Active")
2700
                                continue;
2701

    
2702
                            if (connector.Id != zeroLenthConnector.Id)
2703
                                InputLineAttributeForSpecBreakLMConnector(connector, sppidAttributeName, upStreamValue);
2704
                        }
2705

    
2706
                        ReleaseCOMObjects(zeroLenthConnector);
2707
                        ReleaseCOMObjects(upStreamLMSymbol);
2708
                    }
2709
                    else if (upStreamLine != null && downStreamSymbol != null)
2710
                    {
2711
                        LMConnector zeroLenthConnector = FindBreakLineTarget(upStreamLine, downStreamSymbol);
2712
                        InputLineAttributeForSpecBreakLine(upStreamLine, sppidAttributeName, upStreamValue);
2713
                        LMSymbol downStreamLMSymbol = dataSource.GetSymbol(downStreamSymbol.SPPID.RepresentationId);
2714

    
2715
                        foreach (LMConnector connector in downStreamLMSymbol.Avoid1Connectors)
2716
                        {
2717
                            if (connector.get_ItemStatus() != "Active")
2718
                                continue;
2719

    
2720
                            if (connector.Id != zeroLenthConnector.Id)
2721
                                InputLineAttributeForSpecBreakLMConnector(connector, sppidAttributeName, downStreamValue);
2722
                        }
2723

    
2724
                        foreach (LMConnector connector in downStreamLMSymbol.Avoid2Connectors)
2725
                        {
2726
                            if (connector.get_ItemStatus() != "Active")
2727
                                continue;
2728

    
2729
                            if (connector.Id != zeroLenthConnector.Id)
2730
                                InputLineAttributeForSpecBreakLMConnector(connector, sppidAttributeName, downStreamValue);
2731
                        }
2732

    
2733
                        ReleaseCOMObjects(zeroLenthConnector);
2734
                        ReleaseCOMObjects(downStreamLMSymbol);
2735
                    }
2736
                }
2737
                catch (Exception ex)
2738
                {
2739
                    System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
2740
                }
2741
            }
2742

    
2743
            void InputLineAttributeForSpecBreakLine(Line line, string attrName, string value)
2744
            {
2745
                try
2746
                {
2747
                    LMModelItem _LMModelItem = dataSource.GetModelItem(line.SPPID.ModelItemId);
2748
                    if (_LMModelItem != null && _LMModelItem.get_ItemStatus() == "Active")
2749
                    {
2750
                        LMAAttribute _LMAAttribute = _LMModelItem.Attributes[attrName];
2751
                        if (_LMAAttribute != null)
2752
                        {
2753
                            if (DBNull.Value.Equals(_LMAAttribute.get_Value()))
2754
                                _LMAAttribute.set_Value(value);
2755
                            else if (_LMAAttribute.get_Value() != value)
2756
                                _LMAAttribute.set_Value(value);
2757
                        }
2758

    
2759
                        _LMModelItem.Commit();
2760
                    }
2761
                    if (_LMModelItem != null)
2762
                        ReleaseCOMObjects(_LMModelItem);
2763
                }
2764
                catch (Exception ex)
2765
                {
2766
                    System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
2767
                }
2768
            }
2769

    
2770
            void InputLineAttributeForSpecBreakLMConnector(LMConnector connector, string attrName, string value)
2771
            {
2772
                try
2773
                {
2774
                    LMModelItem _LMModelItem = dataSource.GetModelItem(connector.ModelItemID);
2775
                    if (_LMModelItem != null && _LMModelItem.get_ItemStatus() == "Active")
2776
                    {
2777
                        LMAAttribute _LMAAttribute = _LMModelItem.Attributes[attrName];
2778
                        if (_LMAAttribute != null)
2779
                        {
2780
                            if (DBNull.Value.Equals(_LMAAttribute.get_Value()))
2781
                                _LMAAttribute.set_Value(value);
2782
                            else if (_LMAAttribute.get_Value() != value)
2783
                                _LMAAttribute.set_Value(value);
2784
                        }
2785

    
2786
                        _LMModelItem.Commit();
2787
                    }
2788
                    if (_LMModelItem != null)
2789
                        ReleaseCOMObjects(_LMModelItem);
2790
                }
2791
                catch (Exception ex)
2792
                {
2793
                    System.Windows.Forms.MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
2794
                }
2795
            }
2796
            #endregion
2797
        }
2798

    
2799
        /// <summary>
2800
        /// Text Modeling - Association일 경우는 Text대신 해당 맵핑된 Symbol로 모델링
2801
        /// </summary>
2802
        /// <param name="text"></param>
2803
        private void TextModeling(Text text)
2804
        {
2805
            LMSymbol _LMSymbol = null;
2806
            try
2807
            {
2808
                //if (text.ASSOCIATION && !string.IsNullOrEmpty(text.OWNER) && text.OWNER != "None")
2809
                if (text.ASSOCIATION)
2810
                {
2811
                    object owner = SPPIDUtil.FindObjectByUID(document, text.OWNER);
2812
                    if (owner.GetType() == typeof(Symbol))
2813
                    {
2814
                        Symbol symbol = owner as Symbol;
2815
                        _LMSymbol = dataSource.GetSymbol(symbol.SPPID.RepresentationId);
2816
                        if (_LMSymbol != null)
2817
                        {
2818
                            Association association = symbol.ASSOCIATIONS.Find(x => x.VALUE == text.UID);
2819
                            List<BaseModel.Attribute> attributes = symbol.ATTRIBUTES.FindAll(x => x.ATTRIBUTETYPE == association.TYPE);
2820
                            AttributeMapping mapping = null;
2821
                            foreach (var attribute in attributes)
2822
                            {
2823
                                if (string.IsNullOrEmpty(attribute.VALUE) || attribute.VALUE == "None")
2824
                                    continue;
2825

    
2826
                                 mapping = document.AttributeMappings.Find(x => x.UID == attribute.UID && !string.IsNullOrEmpty(x.SPPIDSYMBOLNAME));
2827
                                if (mapping != null)
2828
                                    break;  
2829
                            }
2830

    
2831
                            if (mapping != null)
2832
                            {
2833
                                double x = 0;
2834
                                double y = 0;
2835

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

    
2839
                                LMLabelPersist _LMLabelPersist = _placement.PIDPlaceLabel(mapping.SPPIDSYMBOLNAME, ref array, Rotation: text.ANGLE, LabeledItem: _LMSymbol.AsLMRepresentation(), IsLeaderVisible: mapping.LeaderLine);
2840
                                if (_LMLabelPersist!=null)
2841
                                {
2842
                                    _LMLabelPersist.Commit();
2843
                                    ReleaseCOMObjects(_LMLabelPersist);
2844
                                }
2845
                            }
2846
                        }
2847
                    }
2848
                    else if (owner.GetType() == typeof(Line))
2849
                    {
2850

    
2851
                    }
2852
                }
2853
                else
2854
                {
2855
                    LMItemNote _LMItemNote = null;
2856
                    LMAAttribute _LMAAttribute = null;
2857

    
2858
                    double x = 0;
2859
                    double y = 0;
2860

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

    
2863
                    _LMSymbol = _placement.PIDPlaceSymbol(text.SPPID.MAPPINGNAME, x, y);
2864
                    _LMSymbol.Commit();
2865
                    _LMItemNote = _placement.PIDDataSource.GetItemNote(_LMSymbol.ModelItemID);
2866
                    _LMItemNote.Commit();
2867
                    _LMAAttribute = _LMItemNote.Attributes["Note.Body"];
2868
                    _LMAAttribute.set_Value(text.VALUE);
2869
                    _LMItemNote.Commit();
2870

    
2871
                    if (_LMAAttribute != null)
2872
                        ReleaseCOMObjects(_LMAAttribute);
2873
                    if (_LMItemNote != null)
2874
                        ReleaseCOMObjects(_LMItemNote);
2875
                }
2876
            }
2877
            catch (Exception ex)
2878
            {
2879

    
2880
            }
2881
            finally
2882
            {
2883
                if (_LMSymbol != null)
2884
                    ReleaseCOMObjects(_LMSymbol);
2885
            }
2886

    
2887
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2888
        }
2889

    
2890
        /// <summary>
2891
        /// Note Modeling
2892
        /// </summary>
2893
        /// <param name="note"></param>
2894
        private void NoteModeling(Note note)
2895
        {
2896
            LMSymbol _LMSymbol = null;
2897
            LMItemNote _LMItemNote = null;
2898
            LMAAttribute _LMAAttribute = null;
2899

    
2900
            try
2901
            {
2902
                double x = 0;
2903
                double y = 0;
2904

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

    
2907
                _LMSymbol = _placement.PIDPlaceSymbol(note.SPPID.MAPPINGNAME, x, y);
2908
                _LMSymbol.Commit();
2909
                _LMItemNote = _placement.PIDDataSource.GetItemNote(_LMSymbol.ModelItemID);
2910
                _LMItemNote.Commit();
2911
                _LMAAttribute = _LMItemNote.Attributes["Note.Body"];
2912
                _LMAAttribute.set_Value(note.VALUE);
2913
                _LMItemNote.Commit();
2914
            }
2915
            catch (Exception ex)
2916
            {
2917

    
2918
            }
2919
            finally
2920
            {
2921
                if (_LMAAttribute != null)
2922
                    ReleaseCOMObjects(_LMAAttribute);
2923
                if (_LMItemNote != null)
2924
                    ReleaseCOMObjects(_LMItemNote);
2925
                if (_LMSymbol != null)
2926
                    ReleaseCOMObjects(_LMSymbol);
2927
            }
2928

    
2929
            SplashScreenManager.Default.SendCommand(SPPIDSplashScreen.SplashScreenCommand.SetProgress, ++CurrentCount);
2930
        }
2931

    
2932
        /// <summary>
2933
        /// Label의 좌표를 구하는 메서드(ID2 기준의 좌표 -> SPPID 좌표)
2934
        /// </summary>
2935
        /// <param name="x"></param>
2936
        /// <param name="y"></param>
2937
        /// <param name="originX"></param>
2938
        /// <param name="originY"></param>
2939
        /// <param name="SPPIDLabelLocation"></param>
2940
        /// <param name="location"></param>
2941
        private void CalcLabelLocation(ref double x, ref double y, double originX, double originY, SPPIDLabelLocationInfo SPPIDLabelLocation, Location location)
2942
        {
2943
            if (location == Location.None)
2944
            {
2945
                x = originX;
2946
                y = originY;
2947
            }
2948
            else
2949
            {
2950
                if (location.HasFlag(Location.Center))
2951
                {
2952
                    x = (SPPIDLabelLocation.X1 + SPPIDLabelLocation.X2) / 2;
2953
                    y = (SPPIDLabelLocation.Y1 + SPPIDLabelLocation.Y2) / 2;
2954
                }
2955

    
2956
                if (location.HasFlag(Location.Left))
2957
                    x = SPPIDLabelLocation.X1;
2958
                else if (location.HasFlag(Location.Right))
2959
                    x = SPPIDLabelLocation.X2;
2960

    
2961
                if (location.HasFlag(Location.Down))
2962
                    y = SPPIDLabelLocation.Y1;
2963
                else if (location.HasFlag(Location.Up))
2964
                    y = SPPIDLabelLocation.Y2;
2965
            }
2966
        }
2967

    
2968
        /// <summary>
2969
        /// Symbol의 우선순위 Modeling 목록을 가져온다.
2970
        /// 1. Angle Valve
2971
        /// 2. 3개로 이루어진 Symbol Group
2972
        /// </summary>
2973
        /// <returns></returns>
2974
        private List<Symbol> GetPrioritySymbol()
2975
        {
2976
            DataTable symbolTable = document.SymbolTable;
2977

    
2978
            // List에 순서대로 쌓는다.
2979
            List<Symbol> symbols = new List<Symbol>();
2980
            // Angle Valve 부터
2981
            foreach (var symbol in document.SYMBOLS.FindAll(x => x.CONNECTORS.Count == 2))
2982
            {
2983
                if (!symbols.Contains(symbol))
2984
                {
2985
                    double originX = 0;
2986
                    double originY = 0;
2987

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

    
2992
                    SlopeType slopeType1 = SlopeType.None;
2993
                    SlopeType slopeType2 = SlopeType.None;
2994
                    foreach (Connector connector in symbol.CONNECTORS)
2995
                    {
2996
                        double connectorX = 0;
2997
                        double connectorY = 0;
2998
                        SPPIDUtil.ConvertPointBystring(connector.CONNECTPOINT, ref connectorX, ref connectorY);
2999
                        if (slopeType1 == SlopeType.None)
3000
                            slopeType1 = SPPIDUtil.CalcSlope(originX, originY, connectorX, connectorY);
3001
                        else
3002
                            slopeType2 = SPPIDUtil.CalcSlope(originX, originY, connectorX, connectorY);
3003
                    }
3004

    
3005
                    if ((slopeType1 == SlopeType.VERTICAL && slopeType2 == SlopeType.HORIZONTAL) ||
3006
                        (slopeType2 == SlopeType.VERTICAL && slopeType1 == SlopeType.HORIZONTAL))
3007
                        symbols.Add(symbol);
3008
                }
3009
            }
3010

    
3011
            // 3개의 Symbol이 뭉쳐 있을 때
3012
            foreach (var item in document.SYMBOLS)
3013
            {
3014
                List<Symbol> group = new List<Symbol>();
3015
                SPPIDUtil.FindConnectedSymbolGroup(document, item, group);
3016
                if (group.Count == 3)
3017
                {
3018
                    Symbol symbol = SPPIDUtil.FindCenterAtThreeSymbols(document, group);
3019
                    if (!symbols.Contains(symbol))
3020
                        symbols.Add(symbol);
3021
                }
3022
            }
3023

    
3024
            // Connection Point가 3개 이상
3025
            foreach (var symbol in document.SYMBOLS)
3026
                if (symbol.CONNECTORS.Count > 2 && !symbols.Contains(symbol))
3027
                    symbols.Add(symbol);
3028

    
3029
            return symbols;
3030
        }
3031

    
3032
        /// <summary>
3033
        /// Graphic OID로 해당 Symbol의 크기를 구하여 Zoom
3034
        /// </summary>
3035
        /// <param name="graphicOID"></param>
3036
        /// <param name="milliseconds"></param>
3037
        private void ZoomObjectByGraphicOID(string graphicOID, int milliseconds = 150)
3038
        {
3039
            if (radApp.ActiveDocument.ActiveSheet.DrawingObjects[graphicOID] != null)
3040
            {
3041
                double minX = 0;
3042
                double minY = 0;
3043
                double maxX = 0;
3044
                double maxY = 0;
3045
                radApp.ActiveDocument.ActiveSheet.DrawingObjects[graphicOID].Range(out minX, out minY, out maxX, out maxY);
3046
                radApp.ActiveWindow.ZoomArea2(minX - 0.007, minY - 0.007, maxX + 0.007, maxY + 0.007, null);
3047

    
3048
                Thread.Sleep(milliseconds);
3049
            }
3050
        }
3051

    
3052
        /// <summary>
3053
        /// ComObject를 Release
3054
        /// </summary>
3055
        /// <param name="objVars"></param>
3056
        public void ReleaseCOMObjects(params object[] objVars)
3057
        {
3058
            int intNewRefCount = 0;
3059
            foreach (object obj in objVars)
3060
            {
3061
                if (!Information.IsNothing(obj) && System.Runtime.InteropServices.Marshal.IsComObject(obj))
3062
                    intNewRefCount = intNewRefCount + System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj);
3063
            }
3064
        }
3065

    
3066
        public void JoinZeroLengthLine()
3067
        {
3068
            foreach (var sModelID in ZeroLengthModelItemID)
3069
            {
3070
                LMModelItem modelItem = dataSource.GetModelItem(sModelID);
3071
                int connectorCount = 0;
3072
                string representationID = string.Empty;
3073

    
3074
                if (modelItem != null && modelItem.get_ItemStatus() == "Active")
3075
                {
3076
                    foreach (LMRepresentation rep in modelItem.Representations)
3077
                    {
3078
                        if (rep.Attributes["RepresentationType"].get_Value() == "Connector" && rep.Attributes["ItemStatus"].get_Value() == "Active")
3079
                        {
3080
                            connectorCount++;
3081
                            representationID = rep.Id;
3082
                        }
3083
                    }
3084
                }
3085

    
3086
                ReleaseCOMObjects(modelItem);
3087

    
3088
                if (connectorCount == 1)
3089
                {
3090
                    LMConnector _LMConnector = dataSource.GetConnector(representationID);
3091
                    if (_LMConnector.LabelPersists.Count == 0)
3092
                    {
3093
                        LMSymbol symbol2 = _LMConnector.ConnectItem2SymbolObject;
3094

    
3095
                        LMConnector targetLine = null;
3096
                        if (symbol2 != null && symbol2.get_RepresentationType() == "Branch")
3097
                        {
3098
                            foreach (LMConnector connector in symbol2.Connect1Connectors)
3099
                            {
3100
                                if (connector.get_ItemStatus() == "Active" && _LMConnector.Id != connector.Id)
3101
                                    targetLine = connector;
3102
                            }
3103

    
3104
                            foreach (LMConnector connector in symbol2.Connect2Connectors)
3105
                            {
3106
                                if (connector.get_ItemStatus() == "Active" && _LMConnector.Id != connector.Id)
3107
                                    targetLine = connector;
3108
                            }
3109
                        }
3110

    
3111
                        JoinPipeRun(_LMConnector.ModelItemID, targetLine.ModelItemID);
3112
                    }
3113
                        
3114
                    ReleaseCOMObjects(_LMConnector);
3115
                }
3116
            }
3117

    
3118
            return;
3119
        }
3120
    }
3121
}
클립보드 이미지 추가 (최대 크기: 500 MB)