OSDN Git Service

1.105.3-SNAPSHOT版開発開始
[mikutoga/TogaGem.git] / src / main / java / jp / sourceforge / mikutoga / pmd / PmdModel.java
index d6dd882..25aebb5 100644 (file)
-/*\r
- * PMD model\r
- *\r
- * License : The MIT License\r
- * Copyright(c) 2010 MikuToga Partners\r
- */\r
-\r
-package jp.sourceforge.mikutoga.pmd;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.EnumMap;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.LinkedList;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.RandomAccess;\r
-import java.util.Set;\r
-import jp.sourceforge.mikutoga.corelib.I18nText;\r
-\r
-/**\r
- * PMDモデルファイル一式に相当するもの。\r
- * 様々な基本構造のリストの集合から構成される。\r
- */\r
-public class PmdModel {\r
-\r
-    /** デフォルトのヘッダバージョン。 */\r
-    public static final float DEF_HEADERVER = 1.0f;\r
-\r
-    private float headerVersion = DEF_HEADERVER;\r
-\r
-    private final I18nText modelName = new I18nText();\r
-    private final I18nText description = new I18nText();\r
-\r
-    private final List<Vertex> vertexList = new ArrayList<Vertex>();\r
-    private final List<Surface> surfaceList = new ArrayList<Surface>();\r
-    private final List<Material> materialList = new LinkedList<Material>();\r
-\r
-    private final List<BoneInfo> boneList = new ArrayList<BoneInfo>();\r
-    private final List<BoneGroup> boneGroupList = new ArrayList<BoneGroup>();\r
-\r
-    private final List<IKChain> ikChainList = new ArrayList<IKChain>();\r
-\r
-    private final Map<MorphType, List<MorphPart>> morphMap =\r
-            new EnumMap<MorphType, List<MorphPart>>(MorphType.class);\r
-\r
-    private final List<RigidInfo> rigidList = new ArrayList<RigidInfo>();\r
-    private final List<RigidGroup> rigidGroupList =\r
-            new ArrayList<RigidGroup>();\r
-\r
-    private final List<JointInfo> jointList = new ArrayList<JointInfo>();\r
-\r
-    private ToonMap toonMap = new ToonMap();\r
-\r
-    /**\r
-     * コンストラクタ。\r
-     */\r
-    public PmdModel(){\r
-        super();\r
-\r
-        assert this.vertexList instanceof RandomAccess;\r
-        assert this.surfaceList instanceof RandomAccess;\r
-\r
-        this.morphMap.put(MorphType.EYEBROW, new ArrayList<MorphPart>());\r
-        this.morphMap.put(MorphType.EYE,     new ArrayList<MorphPart>());\r
-        this.morphMap.put(MorphType.LIP,     new ArrayList<MorphPart>());\r
-        this.morphMap.put(MorphType.EXTRA,   new ArrayList<MorphPart>());\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * PMDファイルのヘッダバージョンを返す。\r
-     * @return PMDファイルのヘッダバージョン\r
-     */\r
-    public float getHeaderVersion(){\r
-        return this.headerVersion;\r
-    }\r
-\r
-    /**\r
-     * PMDファイルのヘッダバージョンを設定する。\r
-     * @param ver PMDファイルのヘッダバージョン\r
-     */\r
-    public void setHeaderVersion(float ver){\r
-        this.headerVersion = ver;\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * モデル名を返す。\r
-     * @return モデル名\r
-     */\r
-    public I18nText getModelName(){\r
-        return this.modelName;\r
-    }\r
-\r
-    /**\r
-     * モデル説明文を返す。\r
-     * 改行表現には{@literal \n}が用いられる\r
-     * @return モデル説明文\r
-     */\r
-    public I18nText getDescription(){\r
-        return this.description;\r
-    }\r
-\r
-    /**\r
-     * 頂点リストを返す。\r
-     * @return 頂点リスト。\r
-     */\r
-    public List<Vertex> getVertexList(){\r
-        return this.vertexList;\r
-    }\r
-\r
-    /**\r
-     * 面リストを返す。\r
-     * @return 面リスト\r
-     */\r
-    public List<Surface> getSurfaceList(){\r
-        return this.surfaceList;\r
-    }\r
-\r
-    /**\r
-     * 素材リストを返す。\r
-     * @return 素材リスト\r
-     */\r
-    public List<Material> getMaterialList(){\r
-        return this.materialList;\r
-    }\r
-\r
-    /**\r
-     * ボーンリストを返す。\r
-     * @return ボーンリスト\r
-     */\r
-    public List<BoneInfo> getBoneList(){\r
-        return this.boneList;\r
-    }\r
-\r
-    /**\r
-     * ボーングループリストを返す。\r
-     * @return ボーングループリスト\r
-     */\r
-    public List<BoneGroup> getBoneGroupList(){\r
-        return this.boneGroupList;\r
-    }\r
-\r
-    /**\r
-     * IKチェーンリストを返す。\r
-     * @return IKチェーンリスト\r
-     */\r
-    public List<IKChain> getIKChainList(){\r
-        return this.ikChainList;\r
-    }\r
-\r
-    /**\r
-     * 種類別モーフリストのマップを返す。\r
-     * @return 種類別モーフリストのマップ\r
-     */\r
-    public Map<MorphType, List<MorphPart>> getMorphMap(){\r
-        return this.morphMap;\r
-    }\r
-\r
-    /**\r
-     * 剛体リストを返す。\r
-     * @return 剛体リスト\r
-     */\r
-    public List<RigidInfo> getRigidList(){\r
-        return this.rigidList;\r
-    }\r
-\r
-    /**\r
-     * 剛体グループリストを返す。\r
-     * @return 剛体グループリスト。\r
-     */\r
-    public List<RigidGroup> getRigidGroupList(){\r
-        return this.rigidGroupList;\r
-    }\r
-\r
-    /**\r
-     * 剛体間ジョイントリストを返す。\r
-     * @return 剛体間ジョイントリスト\r
-     */\r
-    public List<JointInfo> getJointList(){\r
-        return this.jointList;\r
-    }\r
-\r
-    /**\r
-     * トゥーンファイルマップを返す。\r
-     * @return トゥーンファイルマップ\r
-     */\r
-    public ToonMap getToonMap(){\r
-        return this.toonMap;\r
-    }\r
-\r
-    /**\r
-     * トゥーンファイルマップを設定する。\r
-     * 各素材のシェーディングで参照するトゥーンファイルマップも更新される。\r
-     * @param map トゥーンファイルマップ\r
-     */\r
-    public void setToonMap(ToonMap map){\r
-        this.toonMap = map;\r
-        for(Material material : this.materialList){\r
-            ShadeInfo info = material.getShadeInfo();\r
-            info.setToonMap(this.toonMap);\r
-        }\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * このモデルがグローバル名を含むか判定する。\r
-     * ボーン名、ボーングループ名、モーフ名、モデル説明文が判定対象。\r
-     * @return グローバル名を持つならtrue\r
-     */\r
-    public boolean hasGlobalText(){\r
-        if(this.modelName.hasGlobalText()) return true;\r
-        if(this.description.hasGlobalText()) return true;\r
-\r
-        for(BoneInfo bone : this.boneList){\r
-            if(bone.getBoneName().hasGlobalText()) return true;\r
-        }\r
-\r
-        List<MorphType> typeList = new ArrayList<MorphType>();\r
-        typeList.addAll(this.morphMap.keySet());\r
-        for(MorphType type : typeList){\r
-            List<MorphPart> partList = this.morphMap.get(type);\r
-            for(MorphPart part : partList){\r
-                if(part.getMorphName().hasGlobalText()) return true;\r
-            }\r
-        }\r
-\r
-        for(BoneGroup group : this.boneGroupList){\r
-            if(group.getGroupName().hasGlobalText()) return true;\r
-        }\r
-\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * モーフで使われる全てのモーフ頂点のリストを返す。\r
-     * モーフ間で重複する頂点はマージされる。\r
-     * 頂点IDでソートされる。\r
-     * <p>\r
-     * 0から始まる通し番号がリナンバリングされる。\r
-     * 通し番号は返されるモーフ頂点リストの添え字番号と一致する。\r
-     * @return モーフに使われるモーフ頂点のリスト\r
-     */\r
-    public List<MorphVertex> mergeMorphVertex(){\r
-        List<MorphVertex> result = new ArrayList<MorphVertex>();\r
-\r
-        Set<Vertex> mergedVertexSet = new HashSet<Vertex>();\r
-        for(MorphType type : this.morphMap.keySet()){\r
-            if(type.isBase()) continue;\r
-            List<MorphPart> partList = this.morphMap.get(type);\r
-            if(partList == null) continue;\r
-            for(MorphPart part : partList){\r
-                for(MorphVertex morphVertex : part){\r
-                    Vertex vertex = morphVertex.getBaseVertex();\r
-                    if(mergedVertexSet.contains(vertex)) continue;\r
-                    mergedVertexSet.add(vertex);\r
-                    result.add(morphVertex);\r
-                }\r
-            }\r
-        }\r
-\r
-        Collections.sort(result, MorphVertex.VIDCOMPARATOR);\r
-        for(int idx = 0; idx < result.size(); idx++){\r
-            MorphVertex morphVertex = result.get(idx);\r
-            morphVertex.setSerialNumber(idx);\r
-        }\r
-\r
-        Map<Vertex, MorphVertex> numberedMap =\r
-                new HashMap<Vertex, MorphVertex>();\r
-        for(MorphVertex morphVertex : result){\r
-            numberedMap.put(morphVertex.getBaseVertex(), morphVertex);\r
-        }\r
-\r
-        for(MorphType type : this.morphMap.keySet()){\r
-            if(type.isBase()) continue;\r
-            List<MorphPart> partList = this.morphMap.get(type);\r
-            if(partList == null) continue;\r
-            for(MorphPart part : partList){\r
-                for(MorphVertex morphVertex : part){\r
-                    Vertex vertex = morphVertex.getBaseVertex();\r
-                    MorphVertex numbered = numberedMap.get(vertex);\r
-                    assert numbered != null;\r
-                    morphVertex.setSerialNumber(numbered.getSerialNumber());\r
-                }\r
-            }\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * 永続化可能な状態へトリミングする。\r
-     * 各種オブジェクトの通し番号が変化する可能性がある。\r
-     */\r
-    public void trimming(){\r
-        List<Surface> trimmedSurfaceList = trimmingSurfaceList();\r
-        this.surfaceList.clear();\r
-        this.surfaceList.addAll(trimmedSurfaceList);\r
-\r
-        List<Vertex> trimmedVertexList = trimmingVertexList();\r
-        this.vertexList.clear();\r
-        this.vertexList.addAll(trimmedVertexList);\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * 面リストをトリミングする。\r
-     * 所属マテリアル順に再配置し、通し番号を割り振り直す。\r
-     * 所属マテリアルの無い面はリストの末端に配置される。\r
-     * 面リスト中のnullは削除され詰められる。\r
-     * @return トリミングされた面リスト\r
-     */\r
-    private List<Surface> trimmingSurfaceList(){\r
-        Set<Surface> materialedSurfaceSet = new HashSet<Surface>();\r
-        for(Material material : this.materialList){\r
-            if(material == null) continue;\r
-            for(Surface surface : material){\r
-                if(surface == null) continue;\r
-                materialedSurfaceSet.add(surface);\r
-            }\r
-        }\r
-\r
-        materialedSurfaceSet.removeAll(this.surfaceList);\r
-\r
-        List<Surface> result = new ArrayList<Surface>();\r
-        for(Surface surface : this.surfaceList){\r
-            if(surface == null) continue;\r
-            result.add(surface);\r
-        }\r
-\r
-        result.addAll(materialedSurfaceSet);\r
-\r
-        int serialNum = 0;\r
-        for(Surface surface : result){\r
-            surface.setSerialNumber(serialNum);\r
-            serialNum++;\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * 頂点リストをトリミングする。\r
-     * 通し番号を振り直す。\r
-     * 所属面の無い頂点はリストの末端に配置される。\r
-     * 頂点リスト中のnullは削除され詰められる。\r
-     * @return トリミングされた頂点リスト\r
-     */\r
-    private List<Vertex> trimmingVertexList(){\r
-        Set<Vertex> surfacedVertexSet = new HashSet<Vertex>();\r
-        for(Surface surface : this.surfaceList){\r
-            if(surface == null) continue;\r
-            for(Vertex vertex : surface){\r
-                surfacedVertexSet.add(vertex);\r
-            }\r
-        }\r
-\r
-        surfacedVertexSet.removeAll(this.vertexList);\r
-\r
-        List<Vertex> result = new ArrayList<Vertex>();\r
-        for(Vertex vertex : this.vertexList){\r
-            if(vertex == null) continue;\r
-            result.add(vertex);\r
-        }\r
-\r
-        result.addAll(surfacedVertexSet);\r
-\r
-        int serialNum = 0;\r
-        for(Vertex vertex : result){\r
-            vertex.setSerialNumber(serialNum);\r
-            serialNum++;\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-}\r
+/*
+ * PMD model
+ *
+ * License : The MIT License
+ * Copyright(c) 2010 MikuToga Partners
+ */
+
+package jp.sourceforge.mikutoga.pmd;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.RandomAccess;
+import java.util.Set;
+import jp.sourceforge.mikutoga.corelib.I18nText;
+
+/**
+ * PMDモデルファイル一式に相当するもの。
+ * 様々な基本構造のリストの集合から構成される。
+ */
+public class PmdModel {
+
+    /** デフォルトのヘッダバージョン。 */
+    public static final float DEF_HEADERVER = 1.0f;
+
+    private float headerVersion = DEF_HEADERVER;
+
+    private final I18nText modelName = new I18nText();
+    private final I18nText description = new I18nText();
+
+    private final List<Vertex> vertexList = new ArrayList<Vertex>();
+    private final List<Surface> surfaceList = new ArrayList<Surface>();
+    private final List<Material> materialList = new LinkedList<Material>();
+
+    private final List<BoneInfo> boneList = new ArrayList<BoneInfo>();
+    private final List<BoneGroup> boneGroupList = new ArrayList<BoneGroup>();
+
+    private final List<IKChain> ikChainList = new ArrayList<IKChain>();
+
+    private final Map<MorphType, List<MorphPart>> morphMap =
+            new EnumMap<MorphType, List<MorphPart>>(MorphType.class);
+
+    private final List<RigidInfo> rigidList = new ArrayList<RigidInfo>();
+    private final List<RigidGroup> rigidGroupList =
+            new ArrayList<RigidGroup>();
+
+    private final List<JointInfo> jointList = new ArrayList<JointInfo>();
+
+    private ToonMap toonMap = new ToonMap();
+
+    /**
+     * コンストラクタ。
+     */
+    public PmdModel(){
+        super();
+
+        assert this.vertexList instanceof RandomAccess;
+        assert this.surfaceList instanceof RandomAccess;
+
+        this.morphMap.put(MorphType.EYEBROW, new ArrayList<MorphPart>());
+        this.morphMap.put(MorphType.EYE,     new ArrayList<MorphPart>());
+        this.morphMap.put(MorphType.LIP,     new ArrayList<MorphPart>());
+        this.morphMap.put(MorphType.EXTRA,   new ArrayList<MorphPart>());
+
+        return;
+    }
+
+    /**
+     * PMDファイルのヘッダバージョンを返す。
+     * @return PMDファイルのヘッダバージョン
+     */
+    public float getHeaderVersion(){
+        return this.headerVersion;
+    }
+
+    /**
+     * PMDファイルのヘッダバージョンを設定する。
+     * @param ver PMDファイルのヘッダバージョン
+     */
+    public void setHeaderVersion(float ver){
+        this.headerVersion = ver;
+        return;
+    }
+
+    /**
+     * モデル名を返す。
+     * @return モデル名
+     */
+    public I18nText getModelName(){
+        return this.modelName;
+    }
+
+    /**
+     * モデル説明文を返す。
+     * 改行表現には{@literal \n}が用いられる
+     * @return モデル説明文
+     */
+    public I18nText getDescription(){
+        return this.description;
+    }
+
+    /**
+     * 頂点リストを返す。
+     * @return 頂点リスト。
+     */
+    public List<Vertex> getVertexList(){
+        return this.vertexList;
+    }
+
+    /**
+     * 面リストを返す。
+     * @return 面リスト
+     */
+    public List<Surface> getSurfaceList(){
+        return this.surfaceList;
+    }
+
+    /**
+     * 素材リストを返す。
+     * @return 素材リスト
+     */
+    public List<Material> getMaterialList(){
+        return this.materialList;
+    }
+
+    /**
+     * ボーンリストを返す。
+     * @return ボーンリスト
+     */
+    public List<BoneInfo> getBoneList(){
+        return this.boneList;
+    }
+
+    /**
+     * ボーングループリストを返す。
+     * @return ボーングループリスト
+     */
+    public List<BoneGroup> getBoneGroupList(){
+        return this.boneGroupList;
+    }
+
+    /**
+     * IKチェーンリストを返す。
+     * @return IKチェーンリスト
+     */
+    public List<IKChain> getIKChainList(){
+        return this.ikChainList;
+    }
+
+    /**
+     * 種類別モーフリストのマップを返す。
+     * @return 種類別モーフリストのマップ
+     */
+    public Map<MorphType, List<MorphPart>> getMorphMap(){
+        return this.morphMap;
+    }
+
+    /**
+     * 剛体リストを返す。
+     * @return 剛体リスト
+     */
+    public List<RigidInfo> getRigidList(){
+        return this.rigidList;
+    }
+
+    /**
+     * 剛体グループリストを返す。
+     * @return 剛体グループリスト。
+     */
+    public List<RigidGroup> getRigidGroupList(){
+        return this.rigidGroupList;
+    }
+
+    /**
+     * 剛体間ジョイントリストを返す。
+     * @return 剛体間ジョイントリスト
+     */
+    public List<JointInfo> getJointList(){
+        return this.jointList;
+    }
+
+    /**
+     * トゥーンファイルマップを返す。
+     * @return トゥーンファイルマップ
+     */
+    public ToonMap getToonMap(){
+        return this.toonMap;
+    }
+
+    /**
+     * トゥーンファイルマップを設定する。
+     * 各素材のシェーディングで参照するトゥーンファイルマップも更新される。
+     * @param map トゥーンファイルマップ
+     */
+    public void setToonMap(ToonMap map){
+        this.toonMap = map;
+        for(Material material : this.materialList){
+            ShadeInfo info = material.getShadeInfo();
+            info.setToonMap(this.toonMap);
+        }
+        return;
+    }
+
+    /**
+     * このモデルがグローバル名を含むか判定する。
+     * ボーン名、ボーングループ名、モーフ名、モデル説明文が判定対象。
+     * @return グローバル名を持つならtrue
+     */
+    public boolean hasGlobalText(){
+        if(this.modelName.hasGlobalText()) return true;
+        if(this.description.hasGlobalText()) return true;
+
+        for(BoneInfo bone : this.boneList){
+            if(bone.getBoneName().hasGlobalText()) return true;
+        }
+
+        List<MorphType> typeList = new ArrayList<MorphType>();
+        typeList.addAll(this.morphMap.keySet());
+        for(MorphType type : typeList){
+            List<MorphPart> partList = this.morphMap.get(type);
+            for(MorphPart part : partList){
+                if(part.getMorphName().hasGlobalText()) return true;
+            }
+        }
+
+        for(BoneGroup group : this.boneGroupList){
+            if(group.getGroupName().hasGlobalText()) return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * モーフで使われる全てのモーフ頂点のリストを返す。
+     * モーフ間で重複する頂点はマージされる。
+     * 頂点IDでソートされる。
+     * <p>
+     * 0から始まる通し番号がリナンバリングされる。
+     * 通し番号は返されるモーフ頂点リストの添え字番号と一致する。
+     * @return モーフに使われるモーフ頂点のリスト
+     */
+    public List<MorphVertex> mergeMorphVertex(){
+        List<MorphVertex> result = new ArrayList<MorphVertex>();
+
+        Set<Vertex> mergedVertexSet = new HashSet<Vertex>();
+        for(MorphType type : this.morphMap.keySet()){
+            if(type.isBase()) continue;
+            List<MorphPart> partList = this.morphMap.get(type);
+            if(partList == null) continue;
+            for(MorphPart part : partList){
+                for(MorphVertex morphVertex : part){
+                    Vertex vertex = morphVertex.getBaseVertex();
+                    if(mergedVertexSet.contains(vertex)) continue;
+                    mergedVertexSet.add(vertex);
+                    result.add(morphVertex);
+                }
+            }
+        }
+
+        Collections.sort(result, MorphVertex.VIDCOMPARATOR);
+        for(int idx = 0; idx < result.size(); idx++){
+            MorphVertex morphVertex = result.get(idx);
+            morphVertex.setSerialNumber(idx);
+        }
+
+        Map<Vertex, MorphVertex> numberedMap =
+                new HashMap<Vertex, MorphVertex>();
+        for(MorphVertex morphVertex : result){
+            numberedMap.put(morphVertex.getBaseVertex(), morphVertex);
+        }
+
+        for(MorphType type : this.morphMap.keySet()){
+            if(type.isBase()) continue;
+            List<MorphPart> partList = this.morphMap.get(type);
+            if(partList == null) continue;
+            for(MorphPart part : partList){
+                for(MorphVertex morphVertex : part){
+                    Vertex vertex = morphVertex.getBaseVertex();
+                    MorphVertex numbered = numberedMap.get(vertex);
+                    assert numbered != null;
+                    morphVertex.setSerialNumber(numbered.getSerialNumber());
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 永続化可能な状態へトリミングする。
+     * 各種オブジェクトの通し番号が変化する可能性がある。
+     */
+    public void trimming(){
+        List<Surface> trimmedSurfaceList = trimmingSurfaceList();
+        this.surfaceList.clear();
+        this.surfaceList.addAll(trimmedSurfaceList);
+
+        List<Vertex> trimmedVertexList = trimmingVertexList();
+        this.vertexList.clear();
+        this.vertexList.addAll(trimmedVertexList);
+
+        return;
+    }
+
+    /**
+     * 面リストをトリミングする。
+     * 所属マテリアル順に再配置し、通し番号を割り振り直す。
+     * 所属マテリアルの無い面はリストの末端に配置される。
+     * 面リスト中のnullは削除され詰められる。
+     * @return トリミングされた面リスト
+     */
+    private List<Surface> trimmingSurfaceList(){
+        Set<Surface> materialedSurfaceSet = new HashSet<Surface>();
+        for(Material material : this.materialList){
+            if(material == null) continue;
+            for(Surface surface : material){
+                if(surface == null) continue;
+                materialedSurfaceSet.add(surface);
+            }
+        }
+
+        materialedSurfaceSet.removeAll(this.surfaceList);
+
+        List<Surface> result = new ArrayList<Surface>();
+        for(Surface surface : this.surfaceList){
+            if(surface == null) continue;
+            result.add(surface);
+        }
+
+        result.addAll(materialedSurfaceSet);
+
+        int serialNum = 0;
+        for(Surface surface : result){
+            surface.setSerialNumber(serialNum);
+            serialNum++;
+        }
+
+        return result;
+    }
+
+    /**
+     * 頂点リストをトリミングする。
+     * 通し番号を振り直す。
+     * 所属面の無い頂点はリストの末端に配置される。
+     * 頂点リスト中のnullは削除され詰められる。
+     * @return トリミングされた頂点リスト
+     */
+    private List<Vertex> trimmingVertexList(){
+        Set<Vertex> surfacedVertexSet = new HashSet<Vertex>();
+        for(Surface surface : this.surfaceList){
+            if(surface == null) continue;
+            for(Vertex vertex : surface){
+                surfacedVertexSet.add(vertex);
+            }
+        }
+
+        surfacedVertexSet.removeAll(this.vertexList);
+
+        List<Vertex> result = new ArrayList<Vertex>();
+        for(Vertex vertex : this.vertexList){
+            if(vertex == null) continue;
+            result.add(vertex);
+        }
+
+        result.addAll(surfacedVertexSet);
+
+        int serialNum = 0;
+        for(Vertex vertex : result){
+            vertex.setSerialNumber(serialNum);
+            serialNum++;
+        }
+
+        return result;
+    }
+
+}