예제 #1
0
        private static bool isBorderByPosition(int vertex, V2FDict ref_dict)
        {
#if IGNORE_NEAR
            if (checkNear(vertex) >= 0)
            {
                return(false);
            }
#endif
            if (ref_dict[vertex].Count < MIN_FACES)
            {
                return(true);
            }
            PEPlugin.SDX.V3 around = new PEPlugin.SDX.V3(0.0f, 0.0f, 0.0f);
            foreach (int[] face in ref_dict[vertex])
            {
                int             pos = Array.IndexOf(face, vertex);
                int             v1  = face[(pos + 1) % 3];
                int             v2  = face[(pos + 2) % 3];
                PEPlugin.SDX.V3 sub =
                    all_vertex_list[v2].Position -
                    all_vertex_list[v1].Position;
                around = around + sub;
            }
            return(norm2(around) > NEAR * NEAR);
        }
예제 #2
0
        // key: 頂点番号, value: key頂点を含む面のリスト
        private static V2FDict makeRefDict(IList <IPXFace> faces)
        {
            V2FDict ref_dict = new V2FDict();

            foreach (IPXFace face in faces)
            {
                int[] v_list = new int[3] {
                    v2i(face.Vertex1), v2i(face.Vertex2), v2i(face.Vertex3)
                };
                foreach (int v in v_list)
                {
                    if (!ref_dict.ContainsKey(v))
                    {
                        ref_dict[v] = new List <int[]>();
                    }
                    ref_dict[v].Add(v_list);
                }
            }

#if IGNORE_NEAR
            // 材質が持つ頂点のソート情報グローバル変数を更新
            int[] param = ref_dict.Keys.ToArray();
            Tuple <int[], Dictionary <int, int> > t = sortVertexList(param);
            sorted_v  = t.Item1;
            reverse_v = t.Item2;
#endif
            return(ref_dict);
        }
예제 #3
0
        private static List <int> selectConnectedBorderWrapper(
            IList <int> target_list, V2FDict ref_dict)
        {
            HashSet <int> vset    = new HashSet <int>();
            HashSet <int> visited = new HashSet <int>();

            foreach (int selected_v in target_list)
            {
                vset = selectConnectedBorder(
                    selected_v, ref_dict, vset, visited);
            }
            return(new List <int>(vset));
        }
예제 #4
0
        // 材質が持つ全ての頂点を判定
        private static List <int> selectAllBorder(V2FDict ref_dict)
        {
            List <int> vlist = new List <int>();

            foreach (int vertex in ref_dict.Keys)
            {
                if (isBorder(vertex, ref_dict))
                {
                    vlist.Add(vertex);
                }
            }
            return(vlist);
        }
예제 #5
0
        private static void plugin_main(
            IPXPmx pmx, IPEViewConnector view, IPEFormConnector form)
        {
            int selected_m = form.SelectedMaterialIndex;

            //int selected_v = form.SelectedVertexIndex;
            int [] selected_vs = view.PMDView.GetSelectedVertexIndices();
            if (selected_m >= 0)
            {
                IList <IPXFace> faces    = pmx.Material[selected_m].Faces;
                V2FDict         ref_dict = makeRefDict(faces);
                List <int>      filtered = new List <int>();
                foreach (int selected_v in selected_vs)
                {
                    if (selected_v >= 0 && ref_dict.ContainsKey(selected_v))
                    {
                        filtered.Add(selected_v);
                    }
                }
                if (selected_vs.Length > 0 && filtered.Count <= 0)
                {
                    MessageBox.Show(
                        "選択した頂点は選択した材質に含まれていません");
                }
                List <int> vlist;
                if (filtered.Count > 0)
                {
                    vlist = selectConnectedBorderWrapper(filtered, ref_dict);
                }
                else     // all
                {
                    vlist = selectAllBorder(ref_dict);
                }
                var vedit = view.PMDViewHelper.VertexEdit;
#if USE_MEM_SLOT
                vedit.SetVertexMemory(MEMORY_SLOT, vlist.ToArray());
#endif
                view.PMDView.SetSelectedVertexIndices(vlist.ToArray());
            }
            else
            {
                throw new System.Exception("材質を選択してください");
            }
        }
예제 #6
0
 // 面の接続を辿って判定
 private static HashSet <int> selectConnectedBorder(
     int vertex, V2FDict ref_dict,
     HashSet <int> result = null, HashSet <int> visited = null)
 {
     if (null == result)
     {
         result = new HashSet <int>();
     }
     if (null == visited)
     {
         visited = new HashSet <int>();
     }
     if (visited.Contains(vertex))
     {
         return(result);
     }
     else
     {
         visited.Add(vertex);
     }
     if (isBorder(vertex, ref_dict))
     {
         result.Add(vertex);
         var conn = new HashSet <int>();
         // 面で繋がっている頂点群を把握
         foreach (int[] face in ref_dict[vertex])
         {
             int pos = Array.IndexOf(face, vertex);
             conn.Add(face[(pos + 1) % 3]);
             conn.Add(face[(pos + 2) % 3]);
         }
         foreach (int v in conn)
         {
             if (!visited.Contains(v))
             {
                 selectConnectedBorder(
                     v, ref_dict, result, visited);
             }
         }
     }
     return(result);
 }
예제 #7
0
        private static bool isBorderByLink(int vertex, V2FDict ref_dict)
        {
#if IGNORE_NEAR
            // 重複頂点を境界扱いしない(探索中止)
            if (checkNear(vertex) >= 0)
            {
                return(false);
            }
#endif
            if (ref_dict[vertex].Count < MIN_FACES)
            {
                return(true);
            }
            List <int> from_v = new List <int>();
            List <int> to_v   = new List <int>();
            foreach (int[] face in ref_dict[vertex])
            {
                int pos = Array.IndexOf(face, vertex);
                from_v.Add(face[(pos + 1) % 3]);
                to_v.Add(face[(pos + 2) % 3]);
            }
            int i     = 0;
            int start = from_v[i];
            while (true)
            {
                int to_node = to_v[i];
                from_v.RemoveAt(i);
                to_v.RemoveAt(i);
                i = from_v.IndexOf(to_node);
                if (i < 0)
                {
                    // [(0 -> 1), (3 -> 4), (1 -> 2), (4 -> 5), (5 -> 0)]
                    return(true);
                }
                if (from_v.Count == 1)
                {
                    // [(0 -> 1), (3 -> 4), (2 -> 3), (1 -> 2), (4 -> ?)]
                    return(to_v[0] != start);
                }
            }
        }