feat:3D模型修改

master
tongg 7 months ago
parent 2c2044e1b0
commit 75db3d1db4
  1. 1
      SparkClient.sln.DotSettings.user
  2. 2
      Views/Configuration/SettingPages/ModelColorSetPage.xaml
  3. 8
      Views/UserControl/Viewport3D.xaml.cs
  4. 285
      Views/UserControl/ViewportData/Entity/ColorConfigEntity.cs
  5. 58
      Views/UserControl/ViewportData/Helper/CommonHelper.cs
  6. 171
      Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs
  7. 43
      Views/UserControl/ViewportData/Helper/ViewportManager.cs

@ -35,6 +35,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARoutedEventArgs_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F1a88b4a860176dd5f825206bbebf3ee3d44ff3f058ceed9eb693c1eaa018_003FRoutedEventArgs_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARoutedEventArgs_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F1a88b4a860176dd5f825206bbebf3ee3d44ff3f058ceed9eb693c1eaa018_003FRoutedEventArgs_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARuntimeType_002ECoreCLR_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F955ec549fe664629353c3b5424b6ad6c7dfcec4ab59bae709ab962c228cf45_003FRuntimeType_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARuntimeType_002ECoreCLR_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F955ec549fe664629353c3b5424b6ad6c7dfcec4ab59bae709ab962c228cf45_003FRuntimeType_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATaskCompletionSource_00601_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5147b10c5a8c4522b56fba0a889139cfc8f908_003Ffc_003Fe9092391_003FTaskCompletionSource_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATaskCompletionSource_00601_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5147b10c5a8c4522b56fba0a889139cfc8f908_003Ffc_003Fe9092391_003FTaskCompletionSource_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATextInfo_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F68d37d16685244cf9996bf767117a771210200_003F3a_003Ff14dd285_003FTextInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcca5cfb955e146648d91eb22ffe4627a84930_003F7a_003F2d86be72_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcca5cfb955e146648d91eb22ffe4627a84930_003F7a_003F2d86be72_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F2c8e7ca976f350cba9836d5565dac56b11e0b56656fa786460eb1395857a6fa_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F2c8e7ca976f350cba9836d5565dac56b11e0b56656fa786460eb1395857a6fa_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATriggerAction_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F95b2fd5cb826a0d61aff88f87b258644cfe6df15959e521eb9d6cc8da70dc52_003FTriggerAction_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATriggerAction_002Ecs_002Fl_003AC_0021_003FUsers_003Ftongg_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F95b2fd5cb826a0d61aff88f87b258644cfe6df15959e521eb9d6cc8da70dc52_003FTriggerAction_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

@ -6,7 +6,7 @@
xmlns:local="clr-namespace:SparkClient.Views.Configuration.SettingPages" xmlns:local="clr-namespace:SparkClient.Views.Configuration.SettingPages"
xmlns:hc="https://handyorg.github.io/handycontrol" xmlns:hc="https://handyorg.github.io/handycontrol"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="1000"> d:DesignHeight="400" d:DesignWidth="1000">
<Border.Resources> <Border.Resources>
<Style x:Key="BorderRowStyle" TargetType="Border"> <Style x:Key="BorderRowStyle" TargetType="Border">
<Setter Property="CornerRadius" Value="15" /> <Setter Property="CornerRadius" Value="15" />

@ -11,6 +11,11 @@ using SparkClient.Model.Helper;
using SparkClient.Views.UserControl.ViewportData.Entity; using SparkClient.Views.UserControl.ViewportData.Entity;
using SparkClient.Views.UserControl.ViewportData.Enum; using SparkClient.Views.UserControl.ViewportData.Enum;
using SparkClient.Views.UserControl.ViewportData.Helper; using SparkClient.Views.UserControl.ViewportData.Helper;
using HelixToolkit.Wpf.SharpDX;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
namespace SparkClient.Views.UserControl; namespace SparkClient.Views.UserControl;
@ -51,8 +56,11 @@ public partial class Viewport3D
ViewportRightMenuSelectFaceAngleText.IsChecked = ViewportManager.DoubleClickSelectShowBorderAngle; ViewportRightMenuSelectFaceAngleText.IsChecked = ViewportManager.DoubleClickSelectShowBorderAngle;
ViewportRightMenuSelectFaceKind.IsChecked = ViewportManager.DoubleClickSelectShowPlaneType; ViewportRightMenuSelectFaceKind.IsChecked = ViewportManager.DoubleClickSelectShowPlaneType;
var a = Viewport3Dx.Items; var a = Viewport3Dx.Items;
} }
/// <summary> /// <summary>
/// 双击选择面 /// 双击选择面
/// </summary> /// </summary>

@ -0,0 +1,285 @@
using SharpDX;
using SparkClient.Views.UserControl.ViewportData.Helper;
namespace SparkClient.Views.UserControl.ViewportData.Entity;
/// <summary>
/// 颜色配置实体
/// </summary>
public class ColorConfigEntity
{
private string _mainFacetColor = "#FFBDD2ED";
private string _mainBorderColor = "#FF6959CC";
private string _selFacetColor = "#FFBDB759";
private string _selBordertColor = "#FF000000";
private string _selTypeColor = "#FFFCFCD1";
private string _selFontColor = "#FFF4A061";
private string _selLineColor;
private string _selFrontColor = "FFFF0000";
private string _errFacetColor;
private string _tableFacetColor;
private string _upperMainFacetColor;
private string _starFacetColor;
private string _upperGridleFacetColor;
private string _girdleFacetColor;
private string _pavilionFacetColor;
private string _lowerGridleFacetColor;
private string _culetFacetColor;
/// <summary>
/// 面部颜色
/// </summary>
public Color4 MainFacetColor
{
get
{
return CommonHelper.HexToColor4(_mainFacetColor);
}
set
{
_mainFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 边框颜色
/// </summary>
public Color4 MainBorderColor
{
get
{
return CommonHelper.HexToColor4(_mainBorderColor);
}
set
{
_mainBorderColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 选中面部颜色
/// </summary>
public Color4 SelFacetColor
{
get
{
return CommonHelper.HexToColor4(_selFacetColor);
}
set
{
_selFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 选中边框颜色
/// </summary>
public Color4 SelBordertColor
{
get
{
return CommonHelper.HexToColor4(_selBordertColor);
}
set
{
_selBordertColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 选中同类型颜色
/// </summary>
public Color4 SelTypeColor
{
get
{
return CommonHelper.HexToColor4(_selTypeColor);
}
set
{
_selTypeColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 选中面相关文字颜色
/// </summary>
public Color4 SelFontColor
{
get
{
return CommonHelper.HexToColor4(_selFontColor);
}
set
{
_selFontColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 标识线条颜色
/// </summary>
public Color4 SelLineColor
{
get
{
return CommonHelper.HexToColor4(_selLineColor);
}
set
{
_selLineColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 正方向标记颜色
/// </summary>
public Color4 SelFrontColor
{
get
{
return CommonHelper.HexToColor4(_selFrontColor);
}
set
{
_selFrontColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 错误面部颜色
/// </summary>
public Color4 ErrFacetColor
{
get
{
return CommonHelper.HexToColor4(_errFacetColor);
}
set
{
_errFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 台面颜色
/// </summary>
public Color4 TableFacetColor
{
get
{
return CommonHelper.HexToColor4(_tableFacetColor);
}
set
{
_tableFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 风筝面颜色
/// </summary>
public Color4 UpperMainFacetColor
{
get
{
return CommonHelper.HexToColor4(_upperMainFacetColor);
}
set
{
_upperMainFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 星刻面颜色
/// </summary>
public Color4 StarFacetColor
{
get
{
return CommonHelper.HexToColor4(_starFacetColor);
}
set
{
_starFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 上腰面颜色
/// </summary>
public Color4 UpperGridleFacetColor
{
get
{
return CommonHelper.HexToColor4(_upperGridleFacetColor);
}
set
{
_upperGridleFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 腰颜色
/// </summary>
public Color4 GirdleFacetColor
{
get
{
return CommonHelper.HexToColor4(_girdleFacetColor);
}
set
{
_girdleFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 亭部主刻面颜色
/// </summary>
public Color4 PavilionFacetColor
{
get
{
return CommonHelper.HexToColor4(_pavilionFacetColor);
}
set
{
_pavilionFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 下腰面颜色
/// </summary>
public Color4 LowerGridleFacetColor
{
get
{
return CommonHelper.HexToColor4(_lowerGridleFacetColor);
}
set
{
_lowerGridleFacetColor = CommonHelper.Color4ToHex(value);
}
}
/// <summary>
/// 底面颜色
/// </summary>
public Color4 CuletFacetColor
{
get
{
return CommonHelper.HexToColor4(_culetFacetColor);
}
set
{
_culetFacetColor = CommonHelper.Color4ToHex(value);
}
}
}

@ -1,3 +1,4 @@
using System.Globalization;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Windows.Input; using System.Windows.Input;
@ -88,4 +89,61 @@ public class CommonHelper
return string.Concat(hashBytes.Select(b => b.ToString("X2"))); return string.Concat(hashBytes.Select(b => b.ToString("X2")));
} }
} }
public static string Color4ToHex(Color4 color)
{
int a = (int)(color.Alpha * 255);
int r = (int)(color.Red * 255);
int g = (int)(color.Green * 255);
int b = (int)(color.Blue * 255);
// 返回 Hex 字符串
return $"#{a:X2}{r:X2}{g:X2}{b:X2}";
}
public static Color4 HexToColor4(string hex)
{
// 移除可能的前导 '#'
hex = hex.TrimStart('#');
// 根据长度判断是 ARGB 还是 RGB
if (hex.Length == 8)
{
// ARGB 格式:AARRGGBB
return ConvertArgb(hex);
}
else if (hex.Length == 6)
{
// RGB 格式:RRGGBB,默认 Alpha 为 255
return ConvertRgb(hex);
}
else
{
throw new ArgumentException("Hex string must be in the format #AARRGGBB or #RRGGBB.");
}
}
private static Color4 ConvertArgb(string hex)
{
// 解析 ARGB 组件
byte a = byte.Parse(hex.Substring(0, 2), NumberStyles.HexNumber);
byte r = byte.Parse(hex.Substring(2, 2), NumberStyles.HexNumber);
byte g = byte.Parse(hex.Substring(4, 2), NumberStyles.HexNumber);
byte b = byte.Parse(hex.Substring(6, 2), NumberStyles.HexNumber);
// 创建 Color4 对象,RGBA 的范围是 0 到 1,因此除以 255
return new Color4(r / 255f, g / 255f, b / 255f, a / 255f);
}
private static Color4 ConvertRgb(string hex)
{
// 解析 RGB 组件,Alpha 默认 255
byte r = byte.Parse(hex.Substring(0, 2), NumberStyles.HexNumber);
byte g = byte.Parse(hex.Substring(2, 2), NumberStyles.HexNumber);
byte b = byte.Parse(hex.Substring(4, 2), NumberStyles.HexNumber);
byte a = 255; // 默认 Alpha 为 255
// 创建 Color4 对象,RGBA 的范围是 0 到 1,因此除以 255
return new Color4(r / 255f, g / 255f, b / 255f, a / 255f);
}
} }

@ -10,8 +10,10 @@ using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D; using System.Windows.Media.Media3D;
using System.Windows.Threading; using System.Windows.Threading;
using HelixToolkit.Wpf.SharpDX; using HelixToolkit.Wpf.SharpDX;
using NPOI.OpenXmlFormats.Vml.Office;
using SharpDX; using SharpDX;
using SharpDX.Direct3D11; using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SparkClient.Views.UserControl.ViewportData.Enum; using SparkClient.Views.UserControl.ViewportData.Enum;
using SparkClient.Views.UserControl.ViewportData.Entity; using SparkClient.Views.UserControl.ViewportData.Entity;
using Color = SharpDX.Color; using Color = SharpDX.Color;
@ -30,7 +32,7 @@ public class ViewportHelperPro
public static MeshGeometryModel3D GenerateTypePanelHot(PlaneType planeType, Color4? color = null) public static MeshGeometryModel3D GenerateTypePanelHot(PlaneType planeType, Color4? color = null)
{ {
var entities = ViewportManager.ViewportTriangle.Where(e=>e.PlaneType==planeType).ToList(); var entities = ViewportManager.ViewportTriangle.Where(e=>e.PlaneType==planeType).ToList();
return GenerateModelByEntity(entities, color??ViewportManager.Red); return GenerateModelByEntity(entities, color??ViewportManager.ColorConfig.ErrFacetColor);
} }
#region 已经确定和调整好的方法 #region 已经确定和调整好的方法
@ -45,7 +47,7 @@ public class ViewportHelperPro
viewport.Items.Add(geometryModel); viewport.Items.Add(geometryModel);
return geometryModel; return geometryModel;
} }
/// <summary> /// <summary>
/// 通过三角形实体集合生成面模型(只生成不添加) /// 通过三角形实体集合生成面模型(只生成不添加)
/// </summary> /// </summary>
@ -71,8 +73,8 @@ public class ViewportHelperPro
var material = new PBRMaterial var material = new PBRMaterial
{ {
AlbedoColor = ViewportManager.Black, // 黑色,避免其他光照影响 AlbedoColor = new Color4(0.0f, 0f,0f,1f), // 黑色,避免其他光照影响
EmissiveColor =color ?? ViewportManager.LightGray , // LightGray #D3D3D3 EmissiveColor =color ?? ViewportManager.ColorConfig.MainFacetColor , // LightGray #D3D3D3
MetallicFactor = 0.0, // 非金属 MetallicFactor = 0.0, // 非金属
RoughnessFactor = 1.0, // 高粗糙度,避免反射效果 RoughnessFactor = 1.0, // 高粗糙度,避免反射效果
ReflectanceFactor = 0.0, // 无反射 ReflectanceFactor = 0.0, // 无反射
@ -309,6 +311,51 @@ public class ViewportHelperPro
return result; return result;
} }
/// <summary>
/// 通过三角形实体集合生成每个面的边框线(只生成不添加)
/// </summary>
/// <param name="entities"></param>
/// <param name="color"></param>
/// <param name="thickness"></param>
/// <returns></returns>
public static List<LineGeometryModel3D> GentrateLineGirdleByEntity(List<Viewport3DTriangleEntity> entities,
Color4? color = null, double thickness = 1.0)
{
List<LineGeometryModel3D> result = new List<LineGeometryModel3D>();
//按面分组,腰面特殊单独生成
List<Viewport3DTriangleEntity> waistList = entities
.Where(entity => entity.PlaneType == PlaneType.Girdle)
.ToList();
List<Vector3> selFaceVector = new List<Vector3>();
List<Tuple<Vector3, Vector3>> lines = new List<Tuple<Vector3, Vector3>>();
if (waistList.Count > 0)
{
foreach (var entity in waistList)
{
selFaceVector.Add(entity.Point1);
selFaceVector.Add(entity.Point2);
selFaceVector.Add(entity.Point3);
}
HashSet<Vector3> uniqueVectors = new HashSet<Vector3>(selFaceVector);
for (int i = 0; i < uniqueVectors.ToList().Count - 1; i++)
{
var nowItem = uniqueVectors.ToList()[i];
var nextItem = uniqueVectors.ToList()[i + 1];
var line = new Tuple<Vector3, Vector3>(nowItem, nextItem);
if (IsLineSegmentParallelToYAxis(line))
{
lines.Add(line);
result.Add(DisplayLineModel3D(new List<Vector3>(){nowItem,nextItem }, color??ViewportManager.ColorConfig.MainBorderColor, thickness));
}
}
}
CalculateLineSegmentStats(lines, out ViewportManager.MainModelGirdleMaxLines, out ViewportManager.MainModelGirdleMinLines, out ViewportManager.MainModelGirdleAvgLines);
ViewportManager.MainModelGirdleLines = lines;
return result;
}
/// <summary> /// <summary>
/// 通过三角形实体集合生成每个面的边框线(只生成不添加) /// 通过三角形实体集合生成每个面的边框线(只生成不添加)
/// </summary> /// </summary>
@ -339,7 +386,7 @@ public class ViewportHelperPro
temp.Add(entity.Point2); temp.Add(entity.Point2);
temp.Add(entity.Point3); temp.Add(entity.Point3);
} }
result.Add(DisplayLineModel3D(VectorClockwiseSort(new HashSet<Vector3>(temp).ToList()), color??ViewportManager.LineColor, thickness)); result.Add(DisplayLineModel3D(VectorClockwiseSort(new HashSet<Vector3>(temp).ToList()), color??ViewportManager.ColorConfig.MainBorderColor, thickness));
} }
//腰 - 特殊 //腰 - 特殊
@ -366,20 +413,9 @@ public class ViewportHelperPro
else else
ViewportManager.GirdleTopLines.Add(vector); ViewportManager.GirdleTopLines.Add(vector);
} }
result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleBottomLines), color??ViewportManager.LineColor, thickness)); result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleBottomLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness));
result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleTopLines), color??ViewportManager.LineColor, thickness)); result.Add(DisplayLineModel3D( VectorClockwiseSort(ViewportManager.GirdleTopLines), color??ViewportManager.ColorConfig.MainBorderColor, thickness));
//找到所有平行于Y轴的线
for (int i = 0; i < uniqueVectors.ToList().Count - 1; i++)
{
var nowItem = uniqueVectors.ToList()[i];
var nextItem = uniqueVectors.ToList()[i + 1];
var line = new Tuple<Vector3, Vector3>(nowItem, nextItem);
if (IsLineSegmentParallelToYAxis(line))
{
result.Add(DisplayLineModel3D(new List<Vector3>(){nowItem,nextItem }, color??ViewportManager.LineColor, thickness));
}
}
} }
return result; return result;
@ -396,30 +432,48 @@ public class ViewportHelperPro
Color4? textColor = null,bool showAll = false) Color4? textColor = null,bool showAll = false)
{ {
var result = new List<GeometryModel3D>(); var result = new List<GeometryModel3D>();
var selFaceVector = entities if (entities.Count > 0 && entities[0].PlaneType == PlaneType.Girdle)
.SelectMany(entity => new[] { entity.Point1, entity.Point2, entity.Point3 })
.Distinct()
.ToList();
var uniqueLines = new HashSet<string>();
var sortedVectors = VectorClockwiseSort(selFaceVector);
for (int i = 0; i < sortedVectors.Count; i++)
{ {
var current = sortedVectors[i]; if (ViewportManager.MainModelGirdleMaxLines != null || ViewportManager.MainModelGirdleMinLines != null ||
var next = sortedVectors[(i + 1) % sortedVectors.Count]; ViewportManager.MainModelGirdleAvgLines != null)
double length = (next - current).Length();
string lineKey = $"{length:F2}";
if (showAll == false)
{ {
if (uniqueLines.Contains(lineKey)) continue; result.Add(DisplayLineModel3D(new List<Tuple<Vector3,Vector3>>(){ViewportManager.MainModelGirdleMaxLines}, new Color4(1f, 0, 0, 1f) ));
uniqueLines.Add(lineKey); result.Add(DisplayLineModel3D(new List<Tuple<Vector3,Vector3>>(){ViewportManager.MainModelGirdleMinLines}, new Color4(0f, 1f, 0, 1f) ));
result.Add(DisplayLineModel3D(new List<Tuple<Vector3,Vector3>>(){ViewportManager.MainModelGirdleAvgLines}, new Color4(1f, 0.5f, 0, 1f) ));
result.Add(DisplayText3D($"{CalculateLength(ViewportManager.MainModelGirdleMaxLines)}mm", ViewportManager.MainModelGirdleMaxLines.Item1, textColor));
result.Add(DisplayText3D($"{CalculateLength(ViewportManager.MainModelGirdleMinLines)}mm", ViewportManager.MainModelGirdleMinLines.Item1, textColor));
result.Add(DisplayText3D($"{CalculateLength(ViewportManager.MainModelGirdleAvgLines)}mm", ViewportManager.MainModelGirdleAvgLines.Item1, textColor));
}
}
else
{
var selFaceVector = entities
.SelectMany(entity => new[] { entity.Point1, entity.Point2, entity.Point3 })
.Distinct()
.ToList();
var uniqueLines = new HashSet<string>();
var sortedVectors = VectorClockwiseSort(selFaceVector);
for (int i = 0; i < sortedVectors.Count; i++)
{
var current = sortedVectors[i];
var next = sortedVectors[(i + 1) % sortedVectors.Count];
double length = (next - current).Length();
string lineKey = $"{length:F2}";
if (showAll == false)
{
if (uniqueLines.Contains(lineKey)) continue;
uniqueLines.Add(lineKey);
}
var midPoint = (current + next) / 2;
var text = $"{length:F2}mm";
var textY = midPoint.Y > ViewportManager.CenterVector.Y ? midPoint.Y + 0.3f : midPoint.Y - 0.3f;
var lengthTextModel = DisplayText3D(text, new Vector3(midPoint.X, textY, midPoint.Z),next - current, textColor);
result.Add(lengthTextModel);
} }
var midPoint = (current + next) / 2;
var text = $"{length:F2}mm";
var textY = midPoint.Y > ViewportManager.CenterVector.Y ? midPoint.Y + 0.3f : midPoint.Y - 0.3f;
var lengthTextModel = DisplayText3D(text, new Vector3(midPoint.X, textY, midPoint.Z),next - current, textColor);
result.Add(lengthTextModel);
} }
return result; return result;
} }
@ -468,19 +522,19 @@ public class ViewportHelperPro
{ {
case SelShowType.SelPanel: case SelShowType.SelPanel:
//选中面的高亮 //选中面的高亮
result.Add(GenerateModelByEntity(selPanel, ViewportManager.DarkKhaki)); result.Add(GenerateModelByEntity(selPanel, ViewportManager.ColorConfig.SelFacetColor));
break; break;
case SelShowType.Border: case SelShowType.Border:
//选中面边框的高亮 //选中面边框的高亮
result.AddRange(GentrateLineByEntity(selPanel, ViewportManager.Black)); result.AddRange(GentrateLineByEntity(selPanel, ViewportManager.ColorConfig.SelFacetColor));
break; break;
case SelShowType.IsTypePanel: case SelShowType.IsTypePanel:
//选中面的同类面高亮 //选中面的同类面高亮
result.Add(GenerateModelByEntity(selPanelType, ViewportManager.LtGoldenrodYello)); result.Add(GenerateModelByEntity(selPanelType, ViewportManager.ColorConfig.SelTypeColor));
break; break;
case SelShowType.LengthText: case SelShowType.LengthText:
//选中面 每条边长度标记 //选中面 每条边长度标记
if(PlaneType.Girdle == entity.PlaneType)break; // if(PlaneType.Girdle == entity.PlaneType)break;
result.AddRange(GenerateLineTextModels(selPanel)); result.AddRange(GenerateLineTextModels(selPanel));
break; break;
case SelShowType.BorderAngle: case SelShowType.BorderAngle:
@ -596,8 +650,9 @@ public class ViewportHelperPro
var billboardText = new BillboardText3D(); var billboardText = new BillboardText3D();
billboardText.TextInfo.Add(new TextInfo(text, position) billboardText.TextInfo.Add(new TextInfo(text, position)
{ {
Foreground = color??ViewportManager.Red, Foreground = color??ViewportManager.ColorConfig.SelFontColor,
Scale = 0.5f, Scale = 0.8f,
}); });
billboardTextModel.Geometry = billboardText; billboardTextModel.Geometry = billboardText;
return billboardTextModel; return billboardTextModel;
@ -622,7 +677,7 @@ public class ViewportHelperPro
TextInfo = new ObservableCollection<TextInfo>() TextInfo = new ObservableCollection<TextInfo>()
{ {
new TextInfo(text, position){ new TextInfo(text, position){
Foreground = color ?? ViewportManager.Red, Foreground = color ?? ViewportManager.ColorConfig.SelFontColor,
Scale = 0.5f, Scale = 0.5f,
Offset = new Vector2(0.2f, 0.2f), Offset = new Vector2(0.2f, 0.2f),
// Angle = (float)angle // 设置文字的旋转角度 // Angle = (float)angle // 设置文字的旋转角度
@ -1033,6 +1088,30 @@ public class ViewportHelperPro
} }
return false; // 不平行于 Y 轴 return false; // 不平行于 Y 轴
} }
private static void CalculateLineSegmentStats(List<Tuple<Vector3, Vector3>> lines,
out Tuple<Vector3, Vector3> maxLine,
out Tuple<Vector3, Vector3> minLine,
out Tuple<Vector3, Vector3> avgLine)
{
// 计算所有线段的长度
var lineLengths = lines.Select(line => new
{
Line = line,
Length = CalculateLength(line)
}).ToList();
// 找到最大、最小和平均长度对应的线段
maxLine = lineLengths.OrderByDescending(l => l.Length).First().Line;
minLine = lineLengths.OrderBy(l => l.Length).First().Line;
avgLine = lineLengths.OrderBy(l => Math.Abs(l.Length - lineLengths.Average(ll => ll.Length)))
.First().Line;
}
private static float CalculateLength(Tuple<Vector3, Vector3> line)
{
Vector3 startPoint = line.Item1;
Vector3 endPoint = line.Item2;
return Vector3.Distance(startPoint, endPoint);
}
#endregion #endregion
} }

@ -42,12 +42,24 @@ public class ViewportManager
/// 模型边框线 /// 模型边框线
/// </summary> /// </summary>
public static List<LineGeometryModel3D> MainModelLines = new List<LineGeometryModel3D>(); public static List<LineGeometryModel3D> MainModelLines = new List<LineGeometryModel3D>();
/// <summary>
/// 腰垂直线
/// </summary>
public static List<Tuple<Vector3, Vector3>> MainModelGirdleLines = new List<Tuple<Vector3, Vector3>>();
public static Tuple<Vector3, Vector3> MainModelGirdleMaxLines = null;
public static Tuple<Vector3, Vector3> MainModelGirdleMinLines = null;
public static Tuple<Vector3, Vector3> MainModelGirdleAvgLines = null;
/// <summary> /// <summary>
/// 模型光照 /// 模型光照
/// </summary> /// </summary>
public static List<Light3D> MainModelLighting = new List<Light3D>(); public static List<Light3D> MainModelLighting = new List<Light3D>();
public static List<MeshGeometryModel3D> MainModelMeshes = new List<MeshGeometryModel3D>(); public static List<MeshGeometryModel3D> MainModelMeshes = new List<MeshGeometryModel3D>();
public static ColorConfigEntity ColorConfig = new ColorConfigEntity();
/// <summary> /// <summary>
/// 模型控件对象映射 /// 模型控件对象映射
/// </summary> /// </summary>
@ -177,6 +189,7 @@ public class ViewportManager
MainModelLines = ViewportHelperPro.GentrateLineByEntity(_viewport, entities); MainModelLines = ViewportHelperPro.GentrateLineByEntity(_viewport, entities);
MainModelLighting = ViewportHelperPro.GenerateLightingForModel(_viewport); MainModelLighting = ViewportHelperPro.GenerateLightingForModel(_viewport);
MainModelMeshes = ViewportHelperPro.GenerateModelByEntityGroupByType(entities); MainModelMeshes = ViewportHelperPro.GenerateModelByEntityGroupByType(entities);
MainModelLines.AddRange(ViewportHelperPro.GentrateLineGirdleByEntity(entities));
//切换相机视角 //切换相机视角
_viewport.Camera = ViewportHelperPro.CalculateCamera(PositiveDirection, ModelBounds); _viewport.Camera = ViewportHelperPro.CalculateCamera(PositiveDirection, ModelBounds);
_viewport.Camera.UpDirection = new Vector3D(0, -1, 0); _viewport.Camera.UpDirection = new Vector3D(0, -1, 0);
@ -326,32 +339,6 @@ public class ViewportManager
#region 预制颜色 #region 预制颜色
/// <summary>
/// 模型面颜色
/// </summary>
public static Color4 LightGray = new Color4(0.7372f, 0.8235f, 0.93f, 1.0f);
/// <summary>
/// 模型面边框颜色
/// </summary>
public static Color4 LineColor = new Color4(0.4117f, 0.3490f, 0.8039f, 1.0f);
/// <summary>
/// 选中面高亮色
/// </summary>
public static Color4 DarkKhaki = new Color4(0.7411f, 0.71764f, 0.4196f, 1.0f);
/// <summary>
/// 选中面同类面的高亮色
/// </summary>
public static Color4 LtGoldenrodYello = new Color4(0.98039f, 0.98039f, 0.813529f, 1.0f);
/// <summary>
/// 选中面高亮的边框色
/// </summary>
public static Color4 Black = new Color4(0f, 0f, 0f, 1.0f);
/// <summary>
/// 文字颜色
/// </summary>
public static Color4 SandyBrown = new Color4(0.95686f, 0.64313f, 0.37647f, 1.0f);
public static Color4 Red = new Color4(1f, 0.0f, 0.0f, 1.0f);
/// <summary> /// <summary>
/// 材质:半透明蓝 /// 材质:半透明蓝
/// </summary> /// </summary>
@ -381,8 +368,8 @@ public class ViewportManager
/// </summary> /// </summary>
private static PBRMaterial _material = new PBRMaterial private static PBRMaterial _material = new PBRMaterial
{ {
AlbedoColor = Black, // 黑色,避免其他光照影响 AlbedoColor = new Color4(0,0,0,1f), // 黑色,避免其他光照影响
EmissiveColor = LightGray , // LightGray #D3D3D3 EmissiveColor = ColorConfig.MainFacetColor , // LightGray #D3D3D3
MetallicFactor = 0.0, // 非金属 MetallicFactor = 0.0, // 非金属
RoughnessFactor = 1.0, // 高粗糙度,避免反射效果 RoughnessFactor = 1.0, // 高粗糙度,避免反射效果
ReflectanceFactor = 0.0, // 无反射 ReflectanceFactor = 0.0, // 无反射

Loading…
Cancel
Save