public void OpenMeshFile()
        {
            openFileDialog1.FileName = "";
            openFileDialog1.Filter = "Mesh files (*.obj)|*.obj";
            openFileDialog1.CheckFileExists = true;

            DialogResult ret = openFileDialog1.ShowDialog(this);

            if (ret == DialogResult.OK)
            {
                StreamReader sr = new StreamReader(openFileDialog1.FileName);
                Mesh m = new Mesh(sr);
                sr.Close();
                MeshRecord rec = new MeshRecord(openFileDialog1.FileName, m);

                meshes.Add(rec);
                currentMeshRecord = rec;
                TabPage page = new TabPage(rec.ToString());
                page.Tag = rec;
                tabControlModelList.TabPages.Add(page);
                tabControlModelList.SelectedTab = page;
                meshView1.SetModel(rec);
                propertyGridModel.SelectedObject = rec;
                PrintText("Loaded mesh " + openFileDialog1.FileName + "\n");

                // ----------------------------------------------------------------------
                // initialize the harminic field
                // ----------------------------------------------------------------------
                CrossBoundaryBrushes.Option opt = new CrossBoundaryBrushes.Option();
                opt.Part_Type = true;
                currentMeshRecord.CrossBoundaryBrushes =
                    new CrossBoundaryBrushes(currentMeshRecord.Mesh, opt);
                currentMeshRecord.CrossBoundaryBrushes.InitialHarminicField();

                this.meshView1.Refresh();

            }
        }
        private void CreateHarmonicSolver(bool part_type)
        {
            if (currentMeshRecord.CrossBoundaryBrushes != null || // -- already created --
                this.meshView1.Strokes.Count < 1)
            {
                currentMeshRecord.CrossBoundaryBrushes.opt.Part_Type = part_type;
                return;
            }
            if (currentMeshRecord == null || currentMeshRecord.Mesh == null)
                return;
            CrossBoundaryBrushes.Option opt = new CrossBoundaryBrushes.Option();
            opt.Part_Type = part_type;
            currentMeshRecord.CrossBoundaryBrushes =
                new CrossBoundaryBrushes(currentMeshRecord.Mesh, opt);
            currentMeshRecord.CrossBoundaryBrushes.ObtainConstraints(
                this.meshView1.Strokes,
                this.meshView1.FacesOnStrokes
            );

            currentMeshRecord.CrossBoundaryBrushes.Cut();
        }