/// <summary>
        /// Ver1.2.0.0形式の図面ファイルから読み込み(Ver1.2.0.0→Ver1.3.0.0の変換あり)
        /// </summary>
        /// <param name="in_filename"></param>
        /// <param name="isBackupFile">バックアップファイル?</param>
        /// <param name="out_cad2d">格納先Cadオブジェクトのリファレンス</param>
        /// <param name="out_LoopList">ループ情報のリスト</param>
        /// <param name="out_edgeCollectionList">ポートのエッジコレクションのリスト</param>
        /// <param name="out_incidentPortNo">入射ポート番号</param>
        /// <param name="out_medias">媒質情報リストのリファレンス(比誘電率、比透磁率だけセットされる)</param>
        /// <returns></returns>
        public static bool LoadFromFile_Ver_1_2(
            string in_filename,
            out bool isBackupFile,
            ref CCadObj2D out_cad2d,
            ref IList<CadLogic.Loop> out_LoopList,
            ref IList<EdgeCollection> out_edgeCollectionList,
            out int out_incidentPortNo,
            ref MediaInfo[] out_medias
            )
        {
            bool success = false;

            ////////////////////////////////////////////////////////
            // 出力データの初期化

            // バックアップファイル?
            isBackupFile = false;
            // 図面のクリア
            out_cad2d.Clear();
            // ループ情報リストの初期化
            out_LoopList.Clear();
            // 入射ポートの初期化
            out_incidentPortNo = 1;
            // ポートのエッジコレクションのリストを初期化
            out_edgeCollectionList.Clear();
            // 媒質の比誘電率、比透磁率の逆数の初期化
            foreach (MediaInfo media in out_medias)
            {
                // 比透磁率の逆数
                media.SetP(new double[,]
                    {
                        {1.0, 0.0, 0.0},
                        {0.0, 1.0, 0.0},
                        {0.0, 0.0, 1.0}
                    });
                // 比誘電率
                media.SetQ(new double[,]
                    {
                        {1.0, 0.0, 0.0},
                        {0.0, 1.0, 0.0},
                        {0.0, 0.0, 1.0}
                    });
            }

            ////////////////////////////////////////////////////////
            // バックアップファイルの作成
            string filename = "";
            if (in_filename.IndexOf(Ver1_2_Backup_Suffix) >= 0)
            {
                isBackupFile = true;
                MessageBox.Show("このファイルはバックアップファイルです。このファイルを上書き保存しないようご注意ください。",
                    "旧データ形式からの変換", MessageBoxButtons.OK, MessageBoxIcon.Information);

                // 入力ファイル名をそのまま利用
                filename = in_filename;
            }
            else
            {
                // 指定されたCadファイルとその入出力データをリネームする
                string basename = Path.GetDirectoryName(in_filename) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(in_filename);
                string inputfilename = basename + Constants.FemInputExt;
                string outputfilename = basename + Constants.FemOutputExt;
                string indexfilename = outputfilename + Constants.FemOutputIndexExt;
                //ReadOnlyにするのを止める
                ////FEM入出力データは移動しない(Ver1.2のアプリで再計算すると落ちるので止めます:データ削除でtry catchしていないのが原因だと思われる)
                //string[] tagtfilenames = { in_filename };
                // 全ファイルを移動する
                string[] tagtfilenames = { in_filename, inputfilename, outputfilename, indexfilename };
                foreach (string tagtfilename in tagtfilenames)
                {
                    string fname = Path.GetFileNameWithoutExtension(tagtfilename);
                    string ext = Path.GetExtension(tagtfilename);
                    if (fname != Path.GetFileNameWithoutExtension(fname)) // .out.idxの場合、ファイル名に.outまで入るので小細工する
                    {
                        string ext2 = Path.GetExtension(fname);
                        string fname2 = Path.GetFileNameWithoutExtension(fname);
                        ext = ext2 + ext;
                        fname = fname2;
                    }
                    string tagtbasename = Path.GetDirectoryName(tagtfilename) + Path.DirectorySeparatorChar + fname;
                    string backupFilename = tagtbasename + Ver1_2_Backup_Suffix + ext;
                    if (File.Exists(tagtfilename))
                    {
                        if (!File.Exists(backupFilename))
                        {
                            // 対象ファイルが存在し、かつバックアップファイルが存在しないとき
                            //バックアップファイルの作成
                            //MyUtilLib.MyUtil.MoveFileWithReadOnly(tagtfilename, backupFilename);
                            try
                            {
                                // そのまま移動(更新時刻等の再設定が面倒なのでコピーでなく移動する)
                                File.Move(tagtfilename, backupFilename);

                                // コピーとして戻す
                                File.Copy(backupFilename, tagtfilename);
                            }
                            catch (Exception exception)
                            {
                                System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace);
                                MessageBox.Show(exception.Message);
                            }
                        }
                        else
                        {
                            // 対象ファイルは存在し、バックアップが存在するとき
                            // バックアップを作成できない
                            MessageBox.Show("すでに別のバックアップファイルがあるので、バックアップを作成できません。このファイルを上書き保存しないようご注意ください。",
                                "旧データ形式からの変換", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                    }
                }

                // バックアップファイルに移動したので、バックアップファイルから読み込む
                filename = basename + Ver1_2_Backup_Suffix + Constants.CadExt;
            }

            // Ver1.2.0.0形式のファイルの読み込み
            Size maxDiv;
            bool[,] areaSelection;
            int[,] areaToMediaIndex;
            IList<CadDatFile_Ver_1_2.Edge_Ver_1_2> edgeList_Ver_1_2;
            bool[,] yBoundarySelection;
            bool[,] xBoundarySelection;
            int incidentPortNo_Ver_1_2;
            MediaInfo[] medias_Ver_1_2;

            bool loadSuccess = false;
            loadSuccess = CadDatFile_Ver_1_2.LoadFromFile_Ver_1_2(
                filename, out maxDiv, out areaSelection, out areaToMediaIndex,
                out edgeList_Ver_1_2, out yBoundarySelection, out xBoundarySelection,
                out incidentPortNo_Ver_1_2, out medias_Ver_1_2
                );
            if (!loadSuccess)
            {
                return success;
            }

            /////////////////////////////////////////////////////////////////////////////////
            // 本バージョンへのデータ変換
            /////////////////////////////////////////////////////////////////////////////////

            /////////////////////////////////////////////////////////////////////////////////
            // そのまま使用できる情報
            out_incidentPortNo = incidentPortNo_Ver_1_2;

            /////////////////////////////////////////////////////////////////////////////////
            // 変換が必要な情報
            // Medias --> インデックスを1加算
            // AreaToMediaIndex --> インデックスを1加算
            // AreaSelection, AreaToMediaIndex  --> loop
            // EdgeVer1_2 --> EdgeCollection

            //////////////////////////
            // 媒質情報は、Ver1.2→Ver1.3で媒質インデックスが1つずれる(導体が追加されたため)
            for (int oldMediaIndex = 0; oldMediaIndex < medias_Ver_1_2.Length; oldMediaIndex++)
            {
                if (oldMediaIndex + 1 < out_medias.Length)
                {
                    int mediaIndex = oldMediaIndex + 1;  //インデックスを1加算
                    out_medias[mediaIndex].SetP(medias_Ver_1_2[oldMediaIndex].P);
                    out_medias[mediaIndex].SetQ(medias_Ver_1_2[oldMediaIndex].Q);
                }
            }
            for (int y = 0; y < maxDiv.Height; y++)
            {
                for (int x = 0; x < maxDiv.Width; x++)
                {
                    areaToMediaIndex[y, x]++; //インデックスを1加算
                }
            }

            ///////////////////////////
            // 変換準備
            /*
            // 領域選択情報を媒質情報にマージする(非選択の場合もインデックスは0が設定されているがこれを-1に変更)
            for (int y = 0; y < maxDiv.Height; y++)
            {
                for (int x = 0; x < maxDiv.Width; x++)
                {
                    if (!areaSelection[y, x])
                    {
                        // エリアが選択されていない
                        areaToMediaIndex[y, x] = -1; // 未指定に設定する
                    }
                }
            }
             */
            // 非選択部分は導体媒質を設定する
            for (int y = 0; y < maxDiv.Height; y++)
            {
                for (int x = 0; x < maxDiv.Width; x++)
                {
                    if (!areaSelection[y, x])
                    {
                        // エリアが選択されていない
                        areaToMediaIndex[y, x] = CadLogic.MetalMediaIndex; // 導体を指定する
                    }
                }
            }

            // ループの取得
            IList<DelFEM4NetCom.Pair<int, IList<Point>>> loopList = getLoopList(maxDiv, areaToMediaIndex);

            // ループをエッジに変換
            IList<IList<CadDatFile_Ver_1_2.Edge_Ver_1_2>> loopEdgeListList = getLoopEdgeList(loopList);

            // ポート境界のエッジリスト分、エッジコレクションを先に作成する(複数のループにまたがる場合があるため)
            foreach (CadDatFile_Ver_1_2.Edge_Ver_1_2 portEdge in edgeList_Ver_1_2)
            {
                EdgeCollection edgeCollection = new EdgeCollection();
                edgeCollection.No = portEdge.No;
                out_edgeCollectionList.Add(edgeCollection);
            }

            var newLoopEdgeListList = new List<IList<CadDatFile_Ver_1_2.Edge_Ver_1_2>>();
            // ループ数分チェック
            foreach (IList<CadDatFile_Ver_1_2.Edge_Ver_1_2> loopEdgeList in loopEdgeListList)
            {
                // 1つのループ
                var newLoopEdgeList = new List<CadDatFile_Ver_1_2.Edge_Ver_1_2>();
                foreach (CadDatFile_Ver_1_2.Edge_Ver_1_2 loopEdge in loopEdgeList)
                {
                    // 1つのエッジ

                    // ポート境界を含んでいれば分解する
                    // 頂点リスト
                    IList<Point> vertexPts = new List<Point>();
                    // 頂点にポートが対応していれば、ポート番号を格納
                    // 既定値は -1
                    IList<int> toPortNo = new List<int>();

                    // エッジの最初の頂点を追加
                    vertexPts.Add(loopEdge.Points[0]);
                    toPortNo.Add(-1);

                    // ポート境界のエッジリストを走査
                    foreach (CadDatFile_Ver_1_2.Edge_Ver_1_2 portEdge in edgeList_Ver_1_2)
                    {
                        // contains?
                        Point minPt;
                        Point maxPt;
                        if (loopEdge.Contains(portEdge, out minPt, out maxPt))
                        {
                            // ポート境界が含まれていた
                            // ポート境界の頂点を追加
                            //vertexPts.Add(portEdge.Points[0]); // 始点
                            //vertexPts.Add(portEdge.Points[1]); // 終点
                            vertexPts.Add(minPt); // 始点
                            vertexPts.Add(maxPt); // 終点
                            // ポート番号を頂点にあわせて追加
                            toPortNo.Add(portEdge.No);
                            toPortNo.Add(portEdge.No);
                        }
                        else if (loopEdge.GetSimpleSwap().Contains(portEdge, out minPt, out maxPt))
                        {
                            // ポート境界の頂点を追加
                            //vertexPts.Add(portEdge.Points[1]);  // swap 終点
                            //vertexPts.Add(portEdge.Points[0]);  // swap 始点
                            vertexPts.Add(maxPt);  // swap 終点
                            vertexPts.Add(minPt);  // swap 始点
                            // ポート番号を頂点にあわせて追加
                            toPortNo.Add(portEdge.No);
                            toPortNo.Add(portEdge.No);
                        }
                    }
                    // 最後の頂点を追加
                    vertexPts.Add(loopEdge.Points[1]);
                    toPortNo.Add(-1);

                    // 頂点を元にしてエッジを再構築
                    for (int ino = 0; ino < vertexPts.Count - 1; ino++)
                    {
                        CadDatFile_Ver_1_2.Edge_Ver_1_2 work = new CadDatFile_Ver_1_2.Edge_Ver_1_2();
                        // ポート番号があれば格納
                        if (toPortNo[ino] != -1)
                        {
                            work.No = toPortNo[ino];
                        }
                        else
                        {
                            work.No = 0;
                        }
                        // 辺の始点、終点
                        work.Points[0] = vertexPts[ino];
                        work.Points[1] = vertexPts[ino + 1];
                        // Deltaの計算&格納
                        Point p1 = work.Points[0];
                        Point p2 = work.Points[1];
                        work.Delta = CadDatFile_Ver_1_2.Edge_Ver_1_2.CalcDelta(p1, p2);

                        // 空チェック
                        if (work.IsEmpty())
                        {
                            // 空の場合追加しない
                        }
                        else
                        {
                            // 追加
                            newLoopEdgeList.Add(work);
                        }
                    }
                    // 1つのエッジ再構築終了

                } // エッジ

                // 1つのループのエッジリストをリストに追加
                newLoopEdgeListList.Add(newLoopEdgeList);
            } // ループ

            ///////////////////////////////////////////////////////////////////
            // version1.3.0.0のデータ構造に反映する
            bool errorCCadObj = false;

            // ループ領域を作成
            //uint baseLoopId = 0;
            for (int loopIndex = 0; loopIndex < loopList.Count; loopIndex++)
            {
                System.Diagnostics.Debug.WriteLine("loopIndex: {0}", loopIndex);
                DelFEM4NetCom.Pair<int, IList<Point>> loop = loopList[loopIndex];
                // 媒質インデックス
                int mediaIndex = loop.First;
                // ループを構成する頂点
                IList<Point> pts = loop.Second;

                IList<CVector2D> pps = new List<CVector2D>();
                /*
                foreach (Point pt in pts)
                {
                    double xx = pt.X - maxDiv.Width * 0.5;
                    double yy = maxDiv.Height - pt.Y - maxDiv.Height * 0.5;
                    pps.Add(new CVector2D(xx, yy));
                }
                 */
                // このループのエッジリストを取得する
                IList<CadDatFile_Ver_1_2.Edge_Ver_1_2> loopEdgeList = newLoopEdgeListList[loopIndex];

                // エッジのリストインデックス→エッジコレクションのリストのインデックス変換マップ
                IList<int> loopEdgeIndexToEdgeCollectionIndex = new List<int>();

                // OpenGlの頂点リストを作成
                for (int loopEdgeIndex = 0; loopEdgeIndex < loopEdgeList.Count; loopEdgeIndex++)
                {
                    // エッジ
                    CadDatFile_Ver_1_2.Edge_Ver_1_2 work = loopEdgeList[loopEdgeIndex];

                    ////////////////////////////////
                    // OpenGlの頂点作成
                    double xx;
                    double yy;
                    Point pt;
                    pt = work.Points[0]; //始点を追加していく
                    xx = pt.X - maxDiv.Width * 0.5;
                    yy = maxDiv.Height - pt.Y - maxDiv.Height * 0.5;
                    pps.Add(new CVector2D(xx, yy));
                    System.Diagnostics.Debug.WriteLine("pps[{0}]: {1}, {2}", pps.Count - 1, pps[pps.Count - 1].x, pps[pps.Count - 1].y);

                    // check: 終点は次のエッジの始点のはず
                    if (loopEdgeIndex < loopEdgeList.Count - 1)
                    {
                        CadDatFile_Ver_1_2.Edge_Ver_1_2 next = loopEdgeList[loopEdgeIndex + 1];
                        System.Diagnostics.Debug.Assert(work.Points[1].Equals(next.Points[0]));
                    }

                    /* ループの最後の点は追加しない
                    if (loopEdgeIndex == loopEdgeList.Count - 1)
                    {
                        // 最後だけ終点を追加
                        pt = work.Points[1];
                        xx = pt.X - maxDiv.Width * 0.5;
                        yy = maxDiv.Height - pt.Y - maxDiv.Height * 0.5;
                        pps.Add(new CVector2D(xx, yy));
                    }
                    */

                    int edgeCollectionIndex = -1;
                    if (work.No != 0)
                    {
                        ////////////////////////////////////////////////////////
                        // ポート情報がある場合
                        // check
                        {
                            EdgeCollection edgeCollection = out_edgeCollectionList[work.No - 1];
                            System.Diagnostics.Debug.Assert(work.No == edgeCollection.No);
                        }
                        // エッジコレクションリストのインデックスをセット
                        edgeCollectionIndex = work.No - 1;
                    }
                    // エッジのリストインデックス→エッジコレクションのリストのインデックス変換マップ(ポートがない場合も-1で追加する)
                    loopEdgeIndexToEdgeCollectionIndex.Add(edgeCollectionIndex);
                } // loopEdgeIndex

                uint id_l = 0;
                // 多角形でループを作成するのを止める
                //uint id_l = out_cad2d.AddPolygon(pps, baseLoopId).id_l_add;
                // 自力でループ作成
                System.Diagnostics.Debug.WriteLine("makeLoop: loopIndex: {0}", loopIndex);
                id_l = CadLogic.makeLoop(out_cad2d, pps, out_LoopList, false);
                if (id_l == 0)
                {
                    // 領域分割でできた領域は、現状取り込みを実装していません。
                    MessageBox.Show("領域の追加に失敗しました。");
                    errorCCadObj = true;
                }
                else
                {
                    //////////////////////////////////////////////////////////////////////
                    // 辺と頂点を取得
                    IList<uint> vIdList = null;
                    IList<uint> eIdList = null;
                    CadLogic.GetEdgeVertexListOfLoop(out_cad2d, id_l, out vIdList, out eIdList);
                    // 元々の辺のインデックスに対して生成された辺のIDのリストを要素とするリスト
                    IList<IList<uint>> generatedEIdsList = new List<IList<uint>>();
                    // ループ作成時に辺が分割された場合も考慮
                    int eIdIndexOfs = 0;
                    System.Diagnostics.Debug.WriteLine("pps[0]: {0},{1}", pps[0].x, pps[0].y);
                    {
                        Edge_Ver_1_2 loopEdge0 = loopEdgeList[0];
                        CVector2D loopEdge0_pp_v1;
                        CVector2D loopEdge0_pp_v2;
                        {
                            double xx;
                            double yy;
                            Point pt;
                            pt = loopEdge0.Points[0];
                            xx = pt.X - maxDiv.Width * 0.5;
                            yy = maxDiv.Height - pt.Y - maxDiv.Height * 0.5;
                            loopEdge0_pp_v1 = new CVector2D(xx, yy);
                            pt = loopEdge0.Points[1];
                            xx = pt.X - maxDiv.Width * 0.5;
                            yy = maxDiv.Height - pt.Y - maxDiv.Height * 0.5;
                            loopEdge0_pp_v2 = new CVector2D(xx, yy);
                        }
                        System.Diagnostics.Debug.WriteLine("loopEdge0_pp_v1: {0},{1} loopEdge0_pp_v2: {2},{3}", loopEdge0_pp_v1.x, loopEdge0_pp_v1.y, loopEdge0_pp_v2.x, loopEdge0_pp_v2.y);
                        for (int eIdIndexSearch = 0; eIdIndexSearch < eIdList.Count; eIdIndexSearch++)
                        {
                            uint id_e = eIdList[eIdIndexSearch];
                            bool isIncluding = CadLogic.isEdgeIncludingEdge(out_cad2d, loopEdge0_pp_v1, loopEdge0_pp_v2, id_e);
                            if (isIncluding)
                            {
                                eIdIndexOfs = eIdIndexSearch;
                                break;
                            }
                        }
                    }
                    System.Diagnostics.Debug.WriteLine("eIdIndexOfs:{0}", eIdIndexOfs);

                    for (int loopEdgeIndex = 0; loopEdgeIndex < loopEdgeList.Count; loopEdgeIndex++)
                    {
                        IList<uint> generatedEIds = new List<uint>();
                        Edge_Ver_1_2 loopEdge = loopEdgeList[loopEdgeIndex];
                        CVector2D loopEdge_pp_v1;
                        CVector2D loopEdge_pp_v2;
                        {
                            double xx;
                            double yy;
                            Point pt;
                            pt = loopEdge.Points[0];
                            xx = pt.X - maxDiv.Width * 0.5;
                            yy = maxDiv.Height - pt.Y - maxDiv.Height * 0.5;
                            loopEdge_pp_v1 = new CVector2D(xx, yy);
                            pt = loopEdge.Points[1];
                            xx = pt.X - maxDiv.Width * 0.5;
                            yy = maxDiv.Height - pt.Y - maxDiv.Height * 0.5;
                            loopEdge_pp_v2 = new CVector2D(xx, yy);
                        }
                        System.Diagnostics.Debug.WriteLine("  loopEdgeIndex:{0}", loopEdgeIndex);
                        System.Diagnostics.Debug.WriteLine("    loopEdge_pp_v1: {0},{1} loopEdge0_pp_v2: {2},{3}", loopEdge_pp_v1.x, loopEdge_pp_v1.y, loopEdge_pp_v2.x, loopEdge_pp_v2.y);
                        for (int eIdIndex = 0; eIdIndex < eIdList.Count; eIdIndex++)
                        {
                            uint id_e = eIdList[(eIdIndex + eIdIndexOfs) % eIdList.Count]; // 1つずらして取得
                            //System.Diagnostics.Debug.WriteLine("            {0} id_e:{1}", (eIdIndex + eIdIndexOfs) % eIdList.Count, id_e);
                            bool isIncluding = CadLogic.isEdgeIncludingEdge(out_cad2d, loopEdge_pp_v1, loopEdge_pp_v2, id_e);
                            if (!isIncluding)
                            {
                                continue;
                            }
                            generatedEIds.Add(id_e);
                            // check
                            {
                                uint id_v1 = 0;
                                uint id_v2 = 0;
                                CadLogic.getVertexIdsOfEdgeId(out_cad2d, id_e, out id_v1, out id_v2);
                                CVector2D pp_v1 = out_cad2d.GetVertexCoord(id_v1);
                                CVector2D pp_v2 = out_cad2d.GetVertexCoord(id_v2);
                                System.Diagnostics.Debug.WriteLine("    eId: {0}, pp_v1: {1},{2} pp_v2: {3},{4}", id_e, pp_v1.x, pp_v1.y, pp_v2.x, pp_v2.y);
                            }
                        }
                        generatedEIdsList.Add(generatedEIds);
                    }

                    ///////////////////////////////////////////////////////////////////////
                    // エッジコレクションにポート境界に対応する辺のIDをセットする
                    //IList<EdgeCollection> workEdgeCollectionList = new List<EdgeCollection>();  // ここで辺のIDをセットしたコレクションを辺の色付けのために一時保管する
                    for (int loopEdgeIndex = 0; loopEdgeIndex < loopEdgeList.Count; loopEdgeIndex++)
                    {
                        int edgeCollectionIndex = loopEdgeIndexToEdgeCollectionIndex[loopEdgeIndex];
                        if (edgeCollectionIndex != -1)
                        {
                            //
                            EdgeCollection edgeCollection = out_edgeCollectionList[edgeCollectionIndex];
                            IList<uint> generatedEIds = generatedEIdsList[loopEdgeIndex];
                            foreach (uint id_e in generatedEIds)
                            {
                                // 辺のIDをエッジコレクションにセット
                                // 辺の連続性はここではチェックしない(ばらばらで追加されるので)
                                bool chkFlg = false;
                                if (!edgeCollection.ContainsEdgeId(id_e))
                                {
                                    bool ret = edgeCollection.AddEdgeId(id_e, out_cad2d, chkFlg);
                                }
                            }

                            // 一時保管
                            //workEdgeCollectionList.Add(edgeCollection);
                        }
                    }
                    ////////////////////////////////////////////////////////////////////////
                    // 最初のループならばそのIdを記録する
                    //if (baseLoopId == 0)
                    //{
                    //    baseLoopId = id_l;
                    //}
                    // ループの情報を追加する
                    out_LoopList.Add(new CadLogic.Loop(id_l, mediaIndex));

                    // まだ処理が完全でないので下記は処理しない
                    // ループの内側にあるループを子ループに設定する
                    //CadLogic.reconstructLoopsInsideLoopAsChild(out_cad2d, id_l, ref out_LoopList, ref out_edgeCollectionList, out_medias, ref out_incidentPortNo);

                    ////////////////////////////////////////////////////////////////////////
                    // Cadオブジェクトの色をセットする
                    // ループとその辺、頂点の色をセット
                    MediaInfo media = out_medias[mediaIndex];
                    Color backColor = media.BackColor;
                    CadLogic.SetupColorOfCadObjectsForOneLoop(out_cad2d, id_l, backColor);
                    // ポートの色をセットする
                    //CadLogic.SetupColorOfPortEdgeCollection(out_cad2d, workEdgeCollectionList, incidentPortNo_Ver_1_2);
                } // if id_l != 0
            } // loopIndex

            // 番号順に並び替え
            ((List<EdgeCollection>)out_edgeCollectionList).Sort();
            // エッジコレクションの辺IDリストをソートする
            foreach (EdgeCollection workEdgeCollection in out_edgeCollectionList)
            {
                bool ret = workEdgeCollection.SortEdgeIds(out_cad2d);
            }

            // ポートの色をセットする
            CadLogic.SetupColorOfPortEdgeCollection(out_cad2d, out_edgeCollectionList, out_incidentPortNo);

            /////////////////////////////////////////////
            // 外側の導体媒質ループ削除処理
            //
            // 外側の導体媒質ループを取得する
            IList<CadLogic.Loop> delLoopList = new List<CadLogic.Loop>();
            foreach (CadLogic.Loop loop in out_LoopList)
            {
                if (loop.MediaIndex == CadLogic.MetalMediaIndex) // 導体の場合のみ実行
                {
                    // 外側の判定 --->他のループと共有していない辺が存在する
                    IList<uint> vIdList = null;
                    IList<uint> eIdList = null;
                    CadLogic.GetEdgeVertexListOfLoop(out_cad2d, loop.LoopId, out vIdList, out eIdList);

                    bool notSharedEdgeExists = false;
                    foreach (uint eId in eIdList)
                    {
                        if (CadLogic.isEdgeSharedByLoops(out_cad2d, eId))
                        {
                            // 辺を2つのループで共有している
                        }
                        else
                        {
                            // 辺を共有していない
                            notSharedEdgeExists = true;
                            break;
                        }
                    }
                    if (notSharedEdgeExists)
                    {
                        delLoopList.Add(loop);
                    }
                }
            }
            // 外側の導体媒質ループを削除
            foreach (CadLogic.Loop deltarget in delLoopList)
            {
                CadLogic.delLoop(out_cad2d, deltarget.LoopId, ref out_LoopList, ref out_edgeCollectionList, out_medias, ref out_incidentPortNo);
            }

            if (errorCCadObj)
            {
                success = false;
            }
            else
            {
                success = true;
            }
            return success;
        }
        /// <summary>
        /// Ver1.2.0.0形式のCadファイルフォーマットで図面情報を読み込む
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="maxDiv"></param>
        /// <param name="areaSelection"></param>
        /// <param name="areaToMediaIndex"></param>
        /// <param name="edgeList"></param>
        /// <param name="yBoundarySelection">2次的な情報(edgeListから生成される)</param>
        /// <param name="xBoundarySelection">2次的な情報(edgeListから生成される)</param>
        /// <param name="incidentPortNo"></param>
        /// <param name="medias"></param>
        /// <returns></returns>
        public static bool LoadFromFile_Ver_1_2(
            string filename,
            out Size maxDiv, out bool[,] areaSelection, out int[,] areaToMediaIndex,
            out IList<CadDatFile_Ver_1_2.Edge_Ver_1_2> edgeList, out bool[,] yBoundarySelection, out bool[,] xBoundarySelection,
            out int incidentPortNo,
            out MediaInfo[] medias
            )
        {
            bool success = false;

            // ver1.2.0.0の設定値
            int maxMediaCount = 3;
            maxDiv = new Size(30, 30);

            // 初期化
            areaSelection = new bool[maxDiv.Width, maxDiv.Height];
            areaToMediaIndex = new int[maxDiv.Width, maxDiv.Height];
            for (int y = 0; y < maxDiv.Height; y++)
            {
                for (int x = 0; x < maxDiv.Width; x++)
                {
                    areaSelection[y, x] = false;
                    areaToMediaIndex[y, x] = 0;
                }
            }
            edgeList = new List<CadDatFile_Ver_1_2.Edge_Ver_1_2>();
            yBoundarySelection = new bool[maxDiv.Height, maxDiv.Width + 1];
            xBoundarySelection = new bool[maxDiv.Height + 1, maxDiv.Width];
            for (int x = 0; x < maxDiv.Width + 1; x++)
            {
                for (int y = 0; y < maxDiv.Height; y++)
                {
                    yBoundarySelection[y, x] = false;
                }
            }
            for (int y = 0; y < maxDiv.Height + 1; y++)
            {
                for (int x = 0; x < maxDiv.Width; x++)
                {
                    xBoundarySelection[y, x] = false;
                }
            }
            incidentPortNo = 1;
            medias = new MediaInfo[maxMediaCount];
            for (int i = 0; i < medias.Length; i++)
            {
                MediaInfo media = new MediaInfo();
                media.BackColor = CadLogic.MediaBackColors[i];
                medias[i] = media;
            }

            try
            {
                using (StreamReader sr = new StreamReader(filename))
                {
                    string line;
                    string[] tokens;
                    const char delimiter = ',';
                    int cnt = 0;

                    // 領域選択
                    line = sr.ReadLine();
                    tokens = line.Split(delimiter);
                    if (tokens[0] != "AreaSelection")
                    {
                        MessageBox.Show("領域選択情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return success;
                    }
                    cnt = int.Parse(tokens[1]);
                    for (int i = 0; i < cnt; i++)
                    {
                        line = sr.ReadLine();
                        tokens = line.Split(delimiter);
                        if (tokens.Length != 2 && tokens.Length != 3)  // ver1.1.0.0で媒質インデックス追加
                        {
                            MessageBox.Show("領域選択情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return success;
                        }
                        int x = int.Parse(tokens[0]);
                        int y = int.Parse(tokens[1]);
                        int mediaIndex = 0;//CadLogic.DefMediaIndex;
                        if (tokens.Length == 3)
                        {
                            mediaIndex = int.Parse(tokens[2]);
                        }
                        if ((x >= 0 && x < maxDiv.Width) && (y >= 0 && y < maxDiv.Height))
                        {
                            areaSelection[y, x] = true;
                        }
                        else
                        {
                            MessageBox.Show("領域選択座標値が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return success;
                        }
                        // ver1.1.0.0で追加
                        areaToMediaIndex[y, x] = mediaIndex;
                    }

                    // ポート境界
                    line = sr.ReadLine();
                    tokens = line.Split(delimiter);
                    if (tokens[0] != "EdgeList")
                    {
                        MessageBox.Show("境界選択情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return success;
                    }
                    cnt = int.Parse(tokens[1]);
                    for (int i = 0; i < cnt; i++)
                    {
                        line = sr.ReadLine();
                        tokens = line.Split(delimiter);
                        if (tokens.Length != 5)
                        {
                            MessageBox.Show("境界選択情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return success;
                        }
                        int edgeNo = int.Parse(tokens[0]);
                        Point[] p = new Point[2];
                        for (int k = 0; k < p.Length; k++)
                        {
                            p[k] = new Point();
                            p[k].X = int.Parse(tokens[1 + k * 2]);
                            p[k].Y = int.Parse(tokens[1 + k * 2 + 1]);

                        }
                        Size delta = new Size(0, 0);
                        if (p[0].X == p[1].X)
                        {
                            // Y方向境界
                            delta = new Size(0, 1);
                        }
                        else if (p[0].Y == p[1].Y)
                        {
                            // X方向境界
                            delta = new Size(1, 0);
                        }
                        else
                        {
                            MessageBox.Show("境界選択情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return success;
                        }
                        CadDatFile_Ver_1_2.Edge_Ver_1_2 edge = new CadDatFile_Ver_1_2.Edge_Ver_1_2();
                        edge.Delta = delta;
                        edge.No = edgeNo;
                        edge.Points[0] = p[0];
                        edge.Points[1] = p[1];
                        edgeList.Add(edge);
                    }
                    // 2次的な情報(edgeListから生成される)
                    foreach (CadDatFile_Ver_1_2.Edge_Ver_1_2 edge in edgeList)
                    {
                        if (edge.Delta.Width == 0)
                        {
                            // Y方向境界
                            int x = edge.Points[0].X;
                            int sty = edge.Points[0].Y;
                            int edy = edge.Points[1].Y;
                            for (int y = sty; y < edy; y++)
                            {
                                yBoundarySelection[y, x] = true;
                            }
                        }
                        else if (edge.Delta.Height == 0)
                        {
                            // X方向境界
                            int y = edge.Points[0].Y;
                            int stx = edge.Points[0].X;
                            int edx = edge.Points[1].X;
                            for (int x = stx; x < edx; x++)
                            {
                                xBoundarySelection[y, x] = true;
                            }
                        }
                        else
                        {
                            MessageBox.Show("Not implemented");
                        }
                    }

                    line = sr.ReadLine();
                    if (line.Length == 0)
                    {
                        MessageBox.Show("入射ポート番号がありません");
                        return success;
                    }
                    tokens = line.Split(delimiter);
                    if (tokens[0] != "IncidentPortNo")
                    {
                        MessageBox.Show("入射ポート番号がありません");
                        return success;
                    }
                    incidentPortNo = int.Parse(tokens[1]);

                    //////////////////////////////////////////
                    //// Ver1.1.0.0からの追加情報
                    //////////////////////////////////////////
                    line = sr.ReadLine();
                    if (line == null || line.Length == 0)
                    {
                        // 媒質情報なし
                        // ver1.0.0.0
                    }
                    else
                    {
                        // 媒質情報?
                        // ver1.1.0.0
                        tokens = line.Split(delimiter);
                        if (tokens[0] != "Medias")
                        {
                            MessageBox.Show("媒質情報がありません");
                            return success;
                        }
                        cnt = int.Parse(tokens[1]);
                        if (cnt > maxMediaCount)
                        {
                            MessageBox.Show("媒質情報の個数が不正です");
                            return success;
                        }
                        for (int i = 0; i < cnt; i++)
                        {
                            line = sr.ReadLine();
                            if (line.Length == 0)
                            {
                                MessageBox.Show("媒質情報が不正です");
                                return success;
                            }
                            tokens = line.Split(delimiter);
                            if (tokens.Length != 1 + 9 + 9)
                            {
                                MessageBox.Show("媒質情報が不正です");
                                return success;
                            }
                            int mediaIndex = int.Parse(tokens[0]);
                            System.Diagnostics.Debug.Assert(mediaIndex == i);

                            double[,] p = new double[3, 3];
                            for (int m = 0; m < p.GetLength(0); m++)
                            {
                                for (int n = 0; n < p.GetLength(1); n++)
                                {
                                    p[m, n] = double.Parse(tokens[1 + m * p.GetLength(1) + n]);
                                }
                            }
                            medias[i].SetP(p);

                            double[,] q = new double[3, 3];
                            for (int m = 0; m < q.GetLength(0); m++)
                            {
                                for (int n = 0; n < q.GetLength(1); n++)
                                {
                                    q[m, n] = double.Parse(tokens[1 + 9 + m * q.GetLength(1) + n]);
                                }
                            }
                            medias[i].SetQ(q);
                        }
                    }
                }
                success = true;
            }
            catch (Exception exception)
            {
                System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace);
                MessageBox.Show(exception.Message);
            }

            return success;
        }
        /// <summary>
        /// ループをエッジに分解
        /// Note: CadDatFile.Edge_Ver1_2の定義と異なる使用方法をとります。
        ///       Points[0]には始点、Points[1]には終点を格納します
        ///       Deltaにはnew Size(1, 0), new Size(0, 1)に加えて、new Size(-1, 0), new Size(0, -1)が格納されます。
        /// </summary>
        /// <param name="loopList"></param>
        /// <returns></returns>
        private static IList<IList<CadDatFile_Ver_1_2.Edge_Ver_1_2>> getLoopEdgeList(IList<DelFEM4NetCom.Pair<int, IList<Point>>> loopList)
        {
            IList<IList<CadDatFile_Ver_1_2.Edge_Ver_1_2>> loopEdgeListList = new List<IList<CadDatFile_Ver_1_2.Edge_Ver_1_2>>();
            // ループをエッジに分解
            // Note: CadDatFile.Edge_Ver1_2の定義と異なる使用方法をとります。
            //       Points[0]には始点、Points[1]には終点を格納します
            //       Deltaにはnew Size(1, 0), new Size(0, 1)に加えて、new Size(-1, 0), new Size(0, -1)が格納されます。
            foreach (DelFEM4NetCom.Pair<int, IList<Point>> loop in loopList)
            {
                // ループの媒質インデックス
                int mediaIndex = loop.First;
                // ループの頂点のリスト  終点=始点は含まれない
                IList<Point> pts_org = loop.Second;
                IList<Point> pts = new List<Point>();
                // 最後の頂点を追加したリストを作成
                foreach (Point pp in pts_org)
                {
                    pts.Add(pp);
                }
                pts.Add(pts[0]); // 最後に終点=始点を追加

                IList<CadDatFile_Ver_1_2.Edge_Ver_1_2> loopEdgeList = new List<CadDatFile_Ver_1_2.Edge_Ver_1_2>();
                CadDatFile_Ver_1_2.Edge_Ver_1_2 workEdge = null;
                workEdge = new CadDatFile_Ver_1_2.Edge_Ver_1_2();
                workEdge.Delta = new Size(0, 0);
                workEdge.Points[0] = pts[0];
                workEdge.Points[1] = pts[0];
                for (int ino = 1; ino < pts.Count; ino++)
                {
                    Point p1 = workEdge.Points[1];
                    Point p2 = pts[ino];
                    Size delta = CadDatFile_Ver_1_2.Edge_Ver_1_2.CalcDelta(p1, p2);
                    if (workEdge.Delta.Equals(new Size(0, 0)))
                    {
                        workEdge.Delta = delta;
                        workEdge.Points[1] = p2;
                    }
                    else
                    {
                        if (delta.Equals(workEdge.Delta))
                        {
                            workEdge.Points[1] = p2;
                        }
                        else
                        {
                            loopEdgeList.Add(workEdge);

                            workEdge = new CadDatFile_Ver_1_2.Edge_Ver_1_2();
                            //workEdge.Delta = new Size(0, 0);
                            workEdge.Delta = delta;
                            workEdge.Points[0] = p1;
                            workEdge.Points[1] = p2;
                        }
                    }
                    if (ino == pts.Count - 1)
                    {
                        loopEdgeList.Add(workEdge);
                    }
                }
                loopEdgeListList.Add(loopEdgeList);
            }
            return loopEdgeListList;
        }