FlyCube/FlieOperate/FileBase.cs
2023-12-26 22:27:58 +08:00

313 lines
13 KiB
C#

using FlightRouteV2;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace FlieOperate
{
/// <summary>
/// 关于文件的 操作类
/// </summary>
public static class FileBase
{
/// <summary>
/// 逐行读取 文档
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
private static string[] ReadFile(string path)
{
StreamReader sr = new StreamReader(path, Encoding.Default);
String line;
ArrayList arrlist = new ArrayList();
while ((line = sr.ReadLine()) != null)
{
arrlist.Add(line);
}
if (arrlist.Count == 1)//判断 svg的文件内容 是否写在一行里面
{
string temp = (string)arrlist[0];
string[] strArray = Regex.Split(temp, "/>");
return strArray;
}
string[] arr = new string[arrlist.Count];
int key = 0;
foreach (var item in arrlist)
{
arr[key] = (string)item;
key++;
}
return arr;
}
/// <summary>
/// svg航点坐标文档 转坐标集合 PS:灯光映射 支持格式
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static Vector3[] SvgToPosForLight(string path)
{
//读取文档内容
string[] arr;
arr = ReadFile(path);
//获取飞机x轴 z轴 坐标
ArrayList tempVec = new ArrayList();//记录飞机坐标
string cx = @"cx=""(?<mark>\-{0,1}\d*\.{0,1}\d*)""";
string cy = @"cy=""(?<mark>\-{0,1}\d*\.{0,1}\d*)""";
string r = @"r=""(?<mark>\d*\.{0,1}\d*)""";
foreach (string item in arr)
{
if (item.IndexOf("<circle") >= 0)//找到svg里面<circle>标签
{
Regex reg = new Regex(cx);
string strX = reg.Match(item).Groups["mark"].ToString();//正则匹配获取x轴
reg = new Regex(cy);
string strZ = reg.Match(item).Groups["mark"].ToString();//正则匹配获取y轴 在三维里面用作z轴
double x = Convert.ToDouble(strX);
double z = Convert.ToDouble(strZ);
tempVec.Add(new Vector3(x, 0, z));
}
}
Vector3[] vec = FlyVecFun.ArrToVec(tempVec);//把arrlist转换成坐标集合
return vec;//返回坐标集合
}
/// <summary>
/// txt航点坐标文档 转坐标集合 PS:目前是C4D坐标文档
/// </summary>
/// <param name="path">文件路径</param>
/// <param name="flightPointNames">参数形式返回航点名称集合</param>
/// <returns>航点集合</returns>
public static List<Vector3[]> TxtToPos(string path, out string[] flightPointNames)
{
//读取文档内容
string[] arr;
arr = ReadFile(path);
//处理文档内容
int group = 0;//获取有几组坐标
foreach (string item in arr)
{
if (item.IndexOf(" ") <= 0)//找到航点名称
{
group++;
}
}
int planesCou = (arr.Length - group) / group;//获取飞机总数
flightPointNames = new string[group];//记录航点名称
int gKey = 0;//航点名称数组下标
int pKey = 0;//所有坐标序号
Vector3[] pos = new Vector3[planesCou];//临时记录飞机坐标
List<Vector3[]> re = new List<Vector3[]>();//返回值
for (int i = 0; i < arr.Length; i++)
{
if (i % (planesCou + 1) == 0)//分析是否是航点名称 行
{
flightPointNames[gKey] = arr[i];//记录航点名称
gKey++;
}
else//否则 当坐标行处理
{
string[] tempArr = arr[i].Split(' ');//每行坐标分割
pos[pKey % planesCou] = new Vector3(Convert.ToDouble(tempArr[1]), Convert.ToDouble(tempArr[2]), Convert.ToDouble(tempArr[3]));
if (pKey % planesCou == planesCou - 1)//当一组组标循环完成 之后记录到返回组
{
re.Add(pos);
pos = new Vector3[planesCou];//重新new一下 更新内存地址
}
pKey++;
}
}
return re;//out flightPointNames 输出航点名称,re返回值 返回航点集合
}
/// <summary>
/// svg航点坐标文档 转坐标集合
/// </summary>
/// <param name="path">文件路径</param>
/// <returns>坐标集合</returns>
public static Vector3[] SvgToPos(string path)
{
//读取文档内容
string[] arr;
arr = ReadFile(path);
//获取飞机x轴 z轴 坐标
ArrayList tempVec = new ArrayList();//记录飞机坐标
string cx = @"cx=""(?<mark>\-{0,1}\d*\.{0,1}\d*)""";
string cy = @"cy=""(?<mark>\-{0,1}\d*\.{0,1}\d*)""";
string r = @"r=""(?<mark>\d*\.{0,1}\d*)""";
foreach (string item in arr)
{
if (item.IndexOf("<circle") >= 0)//找到svg里面<circle>标签
{
Regex reg = new Regex(cx);
string strX = reg.Match(item).Groups["mark"].ToString();//正则匹配获取x轴
reg = new Regex(cy);
string strZ = reg.Match(item).Groups["mark"].ToString();//正则匹配获取y轴 在三维里面用作z轴
reg = new Regex(r);
string radius = reg.Match(item).Groups["mark"].ToString();//正则匹配获取球半径
//按比例缩放(半径为100公分) 获取世界坐标
double Rate = 100 / Convert.ToDouble(radius);
double x = Rate * Convert.ToDouble(strX);
double z = Rate * Convert.ToDouble(strZ) * -1;
tempVec.Add(new Vector3(x, 0, z));
}
}
//坐标集原点相对位置 移到坐标集质心
Vector3[] vec = FlyVecFun.ArrToVec(tempVec);//把arrlist转换成坐标集合
Vector3 centerPos = FlyVecFun.GetPosCenter(vec);//获取中心点
int key = 0;
foreach (Vector3 item in vec)
{
item.SetZero(centerPos);
vec[key] = item;
key++;
}
return vec;//返回坐标集合
}
/// <summary>
/// obj航点坐标文档 转坐标集合
/// </summary>
/// <param name="path">文件路径</param>
/// <returns>坐标集合</returns>
public static Vector3[] ObjToPos(string path)
{
//读取文档内容
string[] arr;
arr =ReadFile(path);
//获取飞机x轴 z轴 坐标
string pCou = @"#\s+(?<mark>\d*)\s+vertices";//匹配obj里面标记点的数量
string pPos = @"v\s+(?<markX>\-{0,1}\d*\.{0,1}\d*)\s+(?<markY>\-{0,1}\d*\.{0,1}\d*)\s+(?<markZ>\-{0,1}\d*\.{0,1}\d*)";
int linage = 0;//行数
string tempPos;//临时记录一下 xyz坐标
ArrayList tempVec = new ArrayList();//记录飞机坐标
foreach (string item in arr)
{
Regex reg = new Regex(pCou);
string cou = reg.Match(item).Groups["mark"].ToString();//正则匹配获取x轴
if (cou != "")
{
for (int i = Convert.ToInt32(cou); i > 0; i--)
{
tempPos = arr[linage - i];
reg = new Regex(pPos);
string strX = reg.Match(tempPos).Groups["markX"].ToString();
string strY = reg.Match(tempPos).Groups["markY"].ToString();
string strZ = reg.Match(tempPos).Groups["markZ"].ToString();
tempVec.Add(new Vector3(Convert.ToDouble(strX), Convert.ToDouble(strY), Convert.ToDouble(strZ)));
}
}
linage++;
}
//坐标集原点相对位置 移到坐标集质心
Vector3[] vec = FlyVecFun.ArrToVec(tempVec);//把arrlist转换成坐标集合
//重新定义中心点为原点
//Vector3 centerPos = getPosCenter(vec);//获取中心点
//int key = 0;
//foreach (Vector3 item in vec)
//{
// item.setZero(centerPos);
// vec[key] = item;
// key++;
//}
return vec;//返回坐标集合
}
/// <summary>
/// 资源管理器 文件类型 中文说明 和扩展名是 成对关系 数组长度要一致
/// </summary>
public static string[] FileClass { get; set; } = new string[] { "航点文件" };
/// <summary>
/// 扩展名 ps: "*.jpg;*.png" 这个格式算一组
/// </summary>
public static string[] Pascal { get; set; } = new string[] { "*.fcgm;" };
/// <summary>
/// 整合文件类型及扩展名
/// "航点文件|*.fcgm;*.txt|航点文件|*.fcgm;*.*";//资源管理器限制扩展名 例子
/// </summary>
/// <returns>文件类型及扩展名</returns>
private static string SetFileClass()
{
string str = "";
for (int i = 0; i < FileClass.Length; i++)
{
str += FileClass[i] + "|" + Pascal[i];
if (i + 1 != FileClass.Length)//最后一次 不加|
{
str += "|";
}
}
return str;
}
/// <summary>
/// 读取文件 存到字符串
/// </summary>
/// <param name="FliePath">文件路径</param>
/// <returns>文件内容 字符串</returns>
public static string ReadFlieToStr(string FliePath)
{
FileStream fs = new FileStream(FliePath, FileMode.Open);
StreamReader fileStream = new StreamReader(fs);
string str = "";
string line;
while ((line = fileStream.ReadLine()) != null)
{
str += line;
}
return str;
}
/// <summary>
/// 字符串 保存到指定文件
/// </summary>
/// <param name="filePath">指定文件和路径</param>
/// <param name="str">字符串</param>
private static void SaveStrToFile(string filePath, string str)
{
str = str.TrimEnd((char[])"\n\r".ToCharArray());//去除最后的回车符
string stream = null;
if (File.Exists(filePath))
{
StreamReader reader = new StreamReader(filePath);
stream = reader.ReadToEnd();
reader.Close();
}
FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(fs);
sw.Write(str);
sw.Close();
fs.Close();
}
public static void SaveExplorer(string str)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = SetFileClass();//设置文件类型
sfd.AddExtension = true;//设置自动在文件名中添加扩展名
if (sfd.ShowDialog() == DialogResult.OK)
{
SaveStrToFile(sfd.FileName, str);
}
}
/// <summary>
/// 资源管理器 获取文件路径
/// </summary>
/// <param name="titName">资源管理器标题栏</param>
/// <param name="isSelect">out参数 判断是否获取到文件路径</param>
/// <returns>文件路径</returns>
public static string OpenExplorer(string titName, out bool isSelect)
{
Microsoft.Win32.OpenFileDialog ofdl = new Microsoft.Win32.OpenFileDialog();//打开资源管理器
ofdl.Filter = SetFileClass();//设置文件类型
ofdl.Title = titName;
if (ofdl.ShowDialog() == true)//执行打开资源管理器 并判断有没有获取到文件名
{
isSelect = true;
}
else
{
isSelect = false;
}
return ofdl.FileName;
}
}
}