本文主要是介绍macad.core解析auxiliary、components、drawing,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.auxiliary
using System;
using System.Runtime.CompilerServices;
using Macad.Common.Serialization;
using Macad.Core.Topology;
using Macad.Occt;namespace Macad.Core.Auxiliary
{// 标记为需要被序列化的类类型[SerializeType]public class DatumPlane : InteractiveEntity, ITransformable{#region Properties// 序列化成员,表示平面的位置[SerializeMember]public Pnt Position{get{return _Position;}set{if (!_Position.IsEqual(value, double.Epsilon)){SaveUndo();_Position = value;RaisePropertyChanged();RaiseVisualChanged();}}}//--------------------------------------------------------------------------------------------------// 序列化成员,表示平面的旋转[SerializeMember]public Quaternion Rotation{get{return _Rotation;}set{if (!_Rotation.IsEqual(value)){SaveUndo();_Rotation = value;RaisePropertyChanged();RaiseVisualChanged();}}}//--------------------------------------------------------------------------------------------------// 序列化成员,表示平面的宽度[SerializeMember]public double SizeX{get { return _SizeX; }set{if (_SizeX != value){SaveUndo();_SizeX = Math.Max(0.01, value);RaisePropertyChanged();if (!IsDeserializing){if (_KeepAspectRatio){SizeY = _SizeX / _AspectRatio;}else{_AspectRatio = _SizeX / _SizeY;}}RaiseVisualChanged();}}}//--------------------------------------------------------------------------------------------------// 序列化成员,表示平面的高度[SerializeMember]public double SizeY{get { return _SizeY; }set{if (_SizeY != value){SaveUndo();_SizeY = Math.Max(0.01, value);RaisePropertyChanged();if (!IsDeserializing){if (_KeepAspectRatio){SizeX = _SizeY * _AspectRatio;}else{_AspectRatio = _SizeX / _SizeY;}}RaiseVisualChanged();}}}//--------------------------------------------------------------------------------------------------// 序列化成员,表示是否保持宽高比[SerializeMember]public bool KeepAspectRatio{get { return _KeepAspectRatio; }set{if (_KeepAspectRatio != value){SaveUndo();_KeepAspectRatio = value;Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 序列化成员,表示平面图片文件路径[SerializeMember]public string ImageFilePath{get { return _ImageFilePath; }set{if (_ImageFilePath != value){SaveUndo();_ImageFilePath = value;RaisePropertyChanged();RaiseVisualChanged();}}}//--------------------------------------------------------------------------------------------------#endregion#region Membersstring _ImageFilePath;Pnt _Position = Pnt.Origin;Quaternion _Rotation = Quaternion.Identity;double _SizeX;double _SizeY;bool _KeepAspectRatio;double _AspectRatio;//--------------------------------------------------------------------------------------------------#endregion#region Initialization// 创建一个新的 DatumPlane 实例public static DatumPlane Create(){var imagePlane = new DatumPlane(){Name = CoreContext.Current.Document?.AddNextNameSuffix(nameof(DatumPlane)) ?? nameof(DatumPlane),Layer = CoreContext.Current.Layers?.ActiveLayer,Document = CoreContext.Current.Document};imagePlane.RaiseVisualChanged();return imagePlane;}//--------------------------------------------------------------------------------------------------// 构造函数,初始化默认值public DatumPlane(){_SizeX = 100;_SizeY = 100;_KeepAspectRatio = true;_AspectRatio = _SizeX / _SizeY;}//--------------------------------------------------------------------------------------------------#endregion#region Entity// 重写属性变更通知方法,在修改属性时标记文档为未保存protected override void RaisePropertyChanged([CallerMemberName] string propertyName = ""){base.RaisePropertyChanged(propertyName);if (!IsDeserializing){if (CoreContext.Current.Workspace != null)CoreContext.Current.Workspace.MarkAsUnsaved();}}//--------------------------------------------------------------------------------------------------#endregion#region ITransformable// 获取坐标系public Ax3 GetCoordinateSystem(){return Rotation.ToAx3(Position);}//--------------------------------------------------------------------------------------------------#endregion}
}
这段代码定义了一个名为 DatumPlane
的类,用于表示一个参考平面。它包含了平面的位置、旋转、宽度、高度、是否保持宽高比以及平面图片文件路径等属性。这些属性都被标记为需要被序列化。
2.components
using System.Runtime.CompilerServices;
using Macad.Core.Topology;namespace Macad.Core.Components
{// 抽象类 Component,继承自 Entitypublic abstract class Component : Entity{// 拥有者对象IDecorable _Owner;#region Properties// 属性 Owner,表示该组件的拥有者public virtual IDecorable Owner{get { return _Owner; }set{var oldOwner = _Owner;_Owner = value;// 当拥有者发生变化时调用 OwnerChanged 方法OwnerChanged(oldOwner, _Owner);RaisePropertyChanged();}}//--------------------------------------------------------------------------------------------------// 拥有者变更时的回调方法,可在派生类中重写protected virtual void OwnerChanged(IDecorable oldOwner, IDecorable newOwner){}//--------------------------------------------------------------------------------------------------// 移除组件的操作public override void Remove(){if (_Owner != null){// 从拥有者中移除该组件_Owner.RemoveComponent(this);Owner = null;}base.Remove();}//--------------------------------------------------------------------------------------------------#endregion#region Property and Undo handling// 保存属性变更的操作到撤销栈中protected override void SaveUndo([CallerMemberName] string propertyName = "", object value = null){if (!IsDeserializing && (CoreContext.Current.UndoHandler != null) && (Owner != null)){CoreContext.Current.UndoHandler.AddPropertyChange(this, propertyName, value);}}//--------------------------------------------------------------------------------------------------// 触发属性变更事件,并标记文档为未保存protected override void RaisePropertyChanged([CallerMemberName] string propertyName = ""){base.RaisePropertyChanged(propertyName);if (!IsDeserializing){if (CoreContext.Current.Workspace != null)CoreContext.Current.Workspace.MarkAsUnsaved();}}//--------------------------------------------------------------------------------------------------#endregion}
}
这段代码定义了一个抽象类 Component
,表示一个组件,它继承自 Entity
类。其中包含了表示拥有者对象的属性 Owner
,以及处理属性变更和撤销操作的方法。
3.
using System.Collections.Generic;
using Macad.Core.Topology;namespace Macad.Core.Components
{// 定义 IDecorable 接口,表示可装饰的对象public interface IDecorable{// 获取拥有者模型Model GetOwnerModel();// 获取所有组件,可选择是否包含继承的组件IEnumerable<Component> GetComponents(bool inherited = false);// 查找指定类型的组件,可选择是否包含继承的组件T FindComponent<T>(bool inherited = false) where T : Component;// 添加组件void AddComponent(Component component);// 移除组件void RemoveComponent(Component component);}
}
这段代码定义了一个接口 IDecorable
,表示可装饰的对象。它定义了一系列方法用于获取组件、查找组件、添加组件和移除组件。
4.
using System.Diagnostics;
using Macad.Core.Topology;
using Macad.Common;
using Macad.Common.Serialization;
using Macad.Occt;namespace Macad.Core.Components
{// 定义可视化样式类,继承自 Component 类public class VisualStyle : Component{#region Properties// 颜色属性[SerializeMember]public Color Color{get { return _Color; }set{if (_Color != value){SaveUndo();_Color = value;RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 透明度属性[SerializeMember]public float Transparency{get { return _Transparency; }set{if (_Transparency != value){SaveUndo();_Transparency = value;RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 关联的 Body 属性public Body Body{get { return Owner as Body; }}//--------------------------------------------------------------------------------------------------// 重写 Owner 属性public override IDecorable Owner{get { return base.Owner; }set{if (value == Owner) return;Body?.RaiseVisualChanged(); // 触发 Body 的可视化改变事件base.Owner = value;if (value != null){Debug.Assert(Body != null);Body?.RaiseVisualChanged(); // 触发 Body 的可视化改变事件}}}//--------------------------------------------------------------------------------------------------#endregion#region Member// 颜色字段Color _Color;// 透明度字段float _Transparency;//--------------------------------------------------------------------------------------------------#endregion// 构造函数,设置默认颜色和透明度public VisualStyle() {_Color = OcctColorUtils.Color(Quantity_NameOfColor.GOLDENROD2);_Transparency = 0;}//--------------------------------------------------------------------------------------------------// Owner 属性改变事件protected override void OwnerChanged(IDecorable oldOwner, IDecorable newOwner){base.OwnerChanged(oldOwner, newOwner);if (newOwner != null){}else{//InvalidateVisual(); // 使可视化失效}}//--------------------------------------------------------------------------------------------------// 创建可视化样式public static VisualStyle Create(Body ownerBody){var component = ownerBody.FindComponent<VisualStyle>(true); // 查找是否已存在该类型的组件if ((component != null) && (component.Owner == ownerBody))return component;component = new VisualStyle();ownerBody.AddComponent(component); // 将组件添加到指定的 Body 中return component;}//--------------------------------------------------------------------------------------------------#region Events// 可视化样式改变事件public delegate void VisualStyleChangedEventHandler(Body body, VisualStyle visualStyle);public event VisualStyleChangedEventHandler VisualStyleChanged;// 触发可视化样式改变事件void _RaiseVisualStyleChanged(){VisualStyleChanged?.Invoke(Owner as Body, this);}//--------------------------------------------------------------------------------------------------#endregion}
}
这段代码定义了一个可视化样式类 VisualStyle
,它继承自 Component
类,用于描述实体的可视化样式。其中包含了颜色和透明度等属性,并提供了创建、改变样式和触发事件的方法。
5.drawing
using System;
using Macad.Common;
using Macad.Common.Serialization;
using Macad.Occt;namespace Macad.Core.Drawing
{// 角度尺寸类,继承自绘图元素类public class AngleDimension : DrawingElement{#region Properties// 第一个点[SerializeMember]public Pnt2d FirstPoint{get { return _FirstPoint; }set{if (_FirstPoint != value){SaveUndo();_FirstPoint = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 第二个点[SerializeMember]public Pnt2d SecondPoint{get { return _SecondPoint; }set{if (_SecondPoint != value){SaveUndo();_SecondPoint = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 中心点[SerializeMember]public Pnt2d CenterPoint{get { return _CenterPoint; }set{if (_CenterPoint != value){SaveUndo();_CenterPoint = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 文本[SerializeMember]public string Text{get { return _Text; }set{if (_Text != value){SaveUndo();_Text = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 自动文本[SerializeMember]public bool AutoText{get { return _AutoText; }set{if (_AutoText != value){SaveUndo();_AutoText = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 非比例尺寸[SerializeMember]public bool IsNotToScale{get { return _IsNotToScale; }set{if (_IsNotToScale != value){SaveUndo();_IsNotToScale = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------#endregion#region Members// 第二个点Pnt2d _SecondPoint;// 第一个点Pnt2d _FirstPoint;// 中心点Pnt2d _CenterPoint;// 文本string _Text;// 是否自动生成文本bool _AutoText = true;// 非比例尺寸bool _IsNotToScale;// 扩展超长const double _ExtensionOverlength = 2.0;// 调试绘制点static bool _Debug_DrawPoints = false;//--------------------------------------------------------------------------------------------------#endregion#region Rendering// 使几何失效void _Invalidate(){Extents = null;}//--------------------------------------------------------------------------------------------------// 计算尺寸protected override void CalculateExtents(){Bnd_Box2d bb = new();bb.Add(FirstPoint);bb.Add(SecondPoint);// 计算参数if (!ComputeParameters(out var parameters))return;bb.Add(_FirstPoint.Translated(parameters.FirstExtensionVector));bb.Add(SecondPoint.Translated(parameters.SecondExtensionVector));Extents = bb;}//--------------------------------------------------------------------------------------------------// 渲染public override bool Render(IDrawingRenderer renderer){// 计算参数if (!ComputeParameters(out var p))return false;if (renderer.RenderElement(this))return true;// 绘制每个元素renderer.SetStyle(new StrokeStyle(Color.Black, 0.1f, LineStyle.Solid), null, null);renderer.BeginGroup("Dimension");if (_Debug_DrawPoints){DrawingRenderHelper.RenderCross(renderer, _FirstPoint);DrawingRenderHelper.RenderCross(renderer, _SecondPoint);DrawingRenderHelper.RenderCross(renderer, _CenterPoint);DrawingRenderHelper.RenderCross(renderer, Position);}// 扩展线renderer.Line(_FirstPoint, _FirstPoint.Translated(p.FirstExtensionVector));renderer.Line(_SecondPoint, _SecondPoint.Translated(p.SecondExtensionVector));// 尺寸线BrepRenderHelper.RenderCircle(renderer, new Geom2d_Circle(new Ax2d(_CenterPoint, Dir2d.DX), p.Radius), p.StartAngle, p.EndAngle, false);DrawingRenderHelper.RenderArrow(renderer, new Ax2d(p.FirstArrowPoint, p.FirstArrowTangent), p.Scale);DrawingRenderHelper.RenderArrow(renderer, new Ax2d(p.SecondArrowPoint, p.SecondArrowTangent), p.Scale);// 尺寸文本if (!Text.IsNullOrWhiteSpace()){var fontStyle = DrawingRenderHelper.GetDefaultFontStyle();renderer.SetStyle(null, new FillStyle(Color.Black),new FontStyle(fontStyle.Family, (float)(fontStyle.Size * p.TextScale)));renderer.Text(Text, p.TextOrigin, p.TextRotation);if (_IsNotToScale){var start = p.TextOrigin.Translated(Dir2d.DX.Rotated(-p.TextRotation + Maths.HalfPI).ToVec(-0.5));renderer.Line(start, start.Translated(Dir2d.DX.Rotated(-p.TextRotation).ToVec(p.TextWidth)));}}renderer.EndGroup();return true;}//--------------------------------------------------------------------------------------------------#endregion#region Helper// 参数结构public struct Parameters{public Vec2d FirstExtensionVector;public Pnt2d FirstArrowPoint;public Dir2d FirstArrowTangent;public Vec2d SecondExtensionVector;public Pnt2d SecondArrowPoint;public Dir2d SecondArrowTangent;public double Radius;public double StartAngle;public double EndAngle;public Pnt2d TextOrigin;public double TextRotation;public double TextWidth;public double TextHeight;public double Scale;public double TextScale;}//--------------------------------------------------------------------------------------------------// 计算参数public bool ComputeParameters(out Parameters parameters){if (FirstPoint.IsEqual(SecondPoint, 0.01)){parameters = new();return false;}var arrowSize = DrawingRenderHelper.GetArrowSize();double scale = 1.0;// 尺寸线var radius = _CenterPoint.Distance(Position);// 扩展线var extDir1 = new Vec2d(_CenterPoint, _FirstPoint).ToDir();var angle1 = -extDir1.Angle(Dir2d.DX);var extVector1 = extDir1.ToVec(radius - _CenterPoint.Distance(_FirstPoint) + _ExtensionOverlength);var extDir2 = new Vec2d(_CenterPoint, _SecondPoint).ToDir();var angle2 = -extDir2.Angle(Dir2d.DX);var extVector2 = extDir2.ToVec(radius - _CenterPoint.Distance(_SecondPoint) + _ExtensionOverlength);var angle = (angle1 - angle2).Abs();if (_AutoText){Text = (angle1 - angle2).Abs().ToDeg().ToInvariantString("F0") + "°";}Geom2d_Circle circle = new(new Ax2d(_CenterPoint, Dir2d.DX), radius);var dimWidth = circle.Circ2d().Length() / circle.Period() * angle;scale = Math.Min(scale, dimWidth / (arrowSize.Length * 3));// 文本Pnt2d textOrigin = new();Vec2d textTangent = new();circle.D1(angle1.Lerp(angle2, 0.5), ref textOrigin, ref textTangent);if (textTangent.X < 0.0){textTangent.Reverse();}var textDirection = textTangent.ToDir();var textNormal = new Vec2d(_CenterPoint, textOrigin).ToDir();var textWidth = 1.0;var textHeight = 1.0;var textRotation = textDirection.Angle(Dir2d.DX);var textScale = scale;if (!Text.IsNullOrWhiteSpace()){var fontStyle = DrawingRenderHelper.GetDefaultFontStyle();var textSize = DrawingRenderHelper.MeasureText(Text, fontStyle);textScale = Math.Min(1.0, dimWidth * 0.90 / textSize.X);scale = Math.Min(scale, textScale);var textOffset = textNormal.Y < 0 ? -1.0 : 1.0; // Exact positioning on above dim linetextOrigin.Translate(textNormal.ToVec(textOffset));textOrigin.Translate(textDirection.ToVec(-textSize.X / 2 * textScale));textWidth = textSize.X * textScale;textHeight = textSize.Y * textScale;}// 箭头bool reverse = angle1 < angle2;double arrowAngle = circle.Period() / circle.Circ2d().Length() * arrowSize.Length * scale * (reverse ? 0.5 : -0.5);angle1 += arrowAngle;angle2 -= arrowAngle;Pnt2d arrowP1 = new(), arrowP2 = new();Vec2d arrowT1 = new(), arrowT2 = new();circle.D1(angle1, ref arrowP1, ref arrowT1);circle.D1(angle2, ref arrowP2, ref arrowT2);if(reverse)arrowT1.Reverse();elsearrowT2.Reverse();arrowP1.Translate(arrowT1.ToDir().ToVec(arrowSize.Length * scale * 0.5));arrowP2.Translate(arrowT2.ToDir().ToVec(arrowSize.Length * scale * 0.5)); // Move arrows slightly towards center, to compensate that the tangent is taken from the middle of the arrowdouble arrowOffset = _CenterPoint.Distance(circle.Value(angle1)) - _CenterPoint.Distance(arrowP1);arrowP1.Translate(extDir1.ToVec(arrowOffset)); arrowP2.Translate(extDir2.ToVec(arrowOffset)); parameters = new (){FirstExtensionVector = extVector1,FirstArrowPoint = arrowP1,FirstArrowTangent = arrowT1.ToDir(),SecondExtensionVector = extVector2,SecondArrowPoint = arrowP2,SecondArrowTangent = arrowT2.ToDir(),Radius = radius,StartAngle = angle1 + arrowAngle,EndAngle = angle2 - arrowAngle,TextOrigin = textOrigin,TextRotation = textRotation,TextWidth = textWidth,TextHeight = textHeight,Scale = scale,TextScale = textScale};return true;}//--------------------------------------------------------------------------------------------------#endregion}
}
这段代码定义了一个角度尺寸类 AngleDimension
,用于绘制角度尺寸标注。其中包含了描述尺寸的属性、渲染方法以及辅助计算参数的方法。
6.
using System;
using Macad.Common;
using Macad.Common.Serialization;
using Macad.Occt;namespace Macad.Core.Drawing
{// 长度尺寸类,继承自绘图元素类public class LengthDimension : DrawingElement{#region Properties// 第一个点[SerializeMember]public Pnt2d FirstPoint{get { return _FirstPoint; }set{if (_FirstPoint != value){SaveUndo();_FirstPoint = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 第二个点[SerializeMember]public Pnt2d SecondPoint{get { return _SecondPoint; }set{if (_SecondPoint != value){SaveUndo();_SecondPoint = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 文本[SerializeMember]public string Text{get { return _Text; }set{if (_Text != value){SaveUndo();_Text = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 自动文本[SerializeMember]public bool AutoText{get { return _AutoText; }set{if (_AutoText != value){SaveUndo();_AutoText = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 非比例尺寸[SerializeMember]public bool IsNotToScale{get { return _IsNotToScale; }set{if (_IsNotToScale != value){SaveUndo();_IsNotToScale = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------#endregion#region Members// 第二个点Pnt2d _SecondPoint;// 第一个点Pnt2d _FirstPoint;// 文本string _Text;// 是否自动生成文本bool _AutoText = true;// 非比例尺寸bool _IsNotToScale;// 扩展超长const double _ExtensionOverlength = 2.0;// 调试绘制点static bool _Debug_DrawPoints = false;//--------------------------------------------------------------------------------------------------#endregion#region Rendering// 使几何失效void _Invalidate(){Extents = null;}//--------------------------------------------------------------------------------------------------// 计算尺寸范围protected override void CalculateExtents(){Bnd_Box2d bb = new();bb.Add(FirstPoint);bb.Add(SecondPoint);// 计算参数if (!ComputeParameters(out var parameters))return;bb.Add(_FirstPoint.Translated(parameters.ExtensionVector));bb.Add(SecondPoint.Translated(parameters.ExtensionVector));Extents = bb;}//--------------------------------------------------------------------------------------------------// 渲染public override bool Render(IDrawingRenderer renderer){// 计算参数if (!ComputeParameters(out var p))return false;if (renderer.RenderElement(this))return true;// 绘制每个元素renderer.SetStyle(new StrokeStyle(Color.Black, 0.1f, LineStyle.Solid), null, null);renderer.BeginGroup("Dimension");if (_Debug_DrawPoints){DrawingRenderHelper.RenderCross(renderer, _FirstPoint);DrawingRenderHelper.RenderCross(renderer, _SecondPoint);DrawingRenderHelper.RenderCross(renderer, Position);}// 扩展线renderer.Line(_FirstPoint, _FirstPoint.Translated(p.ExtensionVector));renderer.Line(_SecondPoint, _SecondPoint.Translated(p.ExtensionVector));// 尺寸线var arrowSize = DrawingRenderHelper.GetArrowSize();renderer.Line(_FirstPoint.Translated(p.DimensionOffset).Translated(p.DimensionDirection.ToVec(arrowSize.Length * p.Scale)), _SecondPoint.Translated(p.DimensionOffset).Translated(p.DimensionDirection.Reversed().ToVec(arrowSize.Length * p.Scale)));DrawingRenderHelper.RenderArrow(renderer, new Ax2d(_FirstPoint.Translated(p.DimensionOffset), p.DimensionDirection.Reversed()), p.Scale);DrawingRenderHelper.RenderArrow(renderer, new Ax2d(_SecondPoint.Translated(p.DimensionOffset), p.DimensionDirection), p.Scale);// 尺寸文本if (!Text.IsNullOrWhiteSpace()){var fontStyle = DrawingRenderHelper.GetDefaultFontStyle();renderer.SetStyle(null, new FillStyle(Color.Black),new FontStyle(fontStyle.Family, (float)(fontStyle.Size * p.TextScale)));renderer.Text(Text, p.TextOrigin, p.DimensionRotation);if (_IsNotToScale){var start = p.TextOrigin.Translated(p.ExtensionVector.Normalized().Scaled(-0.5));renderer.Line(start, start.Translated(p.DimensionDirection.ToVec(p.TextWidth)));}}renderer.EndGroup();return true;}//--------------------------------------------------------------------------------------------------#endregion#region Helper// 参数结构public struct Parameters{public Vec2d ExtensionVector;public Dir2d DimensionDirection;public Vec2d DimensionOffset;public double DimensionRotation;public Pnt2d TextOrigin;public double TextWidth;public double TextHeight;public double Scale;public double TextScale;}//--------------------------------------------------------------------------------------------------// 计算参数public bool ComputeParameters(out Parameters parameters){if (FirstPoint.IsEqual(SecondPoint, 0.01)){parameters = new();return false;}double scale = 1.0;// 尺寸线方向var dimDir = new Vec2d(_FirstPoint, _SecondPoint).ToDir();var dimMid = _FirstPoint.Lerped(_SecondPoint, 0.5);var dimWidth = _FirstPoint.Distance(_SecondPoint);scale = Math.Min(scale, dimWidth / (DrawingRenderHelper.GetArrowSize().Length * 3));if (_AutoText){Text = dimWidth.ToInvariantString("F1");}var rotation = dimDir.Angle(Dir2d.DX);bool dimRightToLeft = false;if (rotation < -Maths.HalfPI){rotation += Maths.PI;dimRightToLeft = true;}else if (rotation > Maths.HalfPI){rotation -= Maths.PI;dimRightToLeft = true;}// 扩展线var extDir = new Dir2d(dimDir.Y, -dimDir.X);if (dimDir.Angle(new Vec2d(dimMid, Position).ToDir()) > 0){extDir.Reverse();}var dimToPos = new gp_Lin2d(_FirstPoint, dimDir).Distance(Position);var extVector = extDir.ToVec(dimToPos + _ExtensionOverlength);var dimOffset = extDir.ToVec(dimToPos);// 文本var textOrigin = _FirstPoint.Lerped(_SecondPoint, 0.5).Translated(dimOffset);var textWidth = 1.0;var textHeight = 1.0;var textScale = scale;if (!Text.IsNullOrWhiteSpace()){var fontStyle = DrawingRenderHelper.GetDefaultFontStyle();var textSize = DrawingRenderHelper.MeasureText(Text, fontStyle);textScale = Math.Min(1.0, dimWidth * 0.90 / textSize.X);scale = Math.Min(scale, textScale);// 在尺寸线上的精确定位var textOffset = dimDir.Angle(extDir) > 0 ? 1.0 : -1.0;if (dimRightToLeft){textOffset *= -1;}textOrigin.Translate(extDir.ToVec(textOffset));// 居中textOrigin.Translate(dimDir.ToVec((dimRightToLeft ? 1.0 : -1.0) * textSize.X / 2 * textScale));textWidth = textSize.X * textScale;textHeight = textSize.Y * textScale;}parameters = new Parameters(){ExtensionVector = extVector,DimensionDirection = dimDir,DimensionOffset = dimOffset,DimensionRotation = rotation,TextOrigin = textOrigin,TextWidth = textWidth,TextHeight = textHeight,Scale = scale,TextScale = textScale};return true;}//--------------------------------------------------------------------------------------------------#endregion}
}
这段代码定义了一个长度尺寸类 LengthDimension
,用于绘制长度尺寸标注。其中包含了描述尺寸的属性、渲染方法以及辅助计算参数的方法。
8.
using System.Linq;
using Macad.Common.Serialization;
using Macad.Occt;namespace Macad.Core.Drawing
{// BRep绘图类,继承自绘图元素类public class BRepDrawing : DrawingElement{// 描边样式[SerializeMember]public StrokeStyle Stroke{get { return _Stroke; }set{if (_Stroke != value){SaveUndo();_Stroke = value;RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 填充样式[SerializeMember]public FillStyle Fill{get { return _Fill; }set{if (_Fill != value){SaveUndo();_Fill = value;RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// BRep数据源[SerializeMember]public IBrepSource Source{get { return _Source; }set{if (_Source != value){SaveUndo();_Source = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 描边样式StrokeStyle _Stroke;// 填充样式FillStyle _Fill;// BRep数据源IBrepSource _Source;//--------------------------------------------------------------------------------------------------// 使几何失效void _Invalidate(){Extents = null;}//--------------------------------------------------------------------------------------------------// 计算范围protected override void CalculateExtents(){// 更新边界矩形Bnd_Box2d aabb = new Bnd_Box2d();// 获取BRep形状var shapes = _Source?.GetBreps();if (shapes != null){foreach (var shape in shapes){double xmin = 0;double xmax = 0;double ymin = 0;double ymax = 0;double zmin = 0;double zmax = 0;// 获取形状的边界框shape.BoundingBox()?.Get(ref xmin, ref ymin, ref zmin, ref xmax, ref ymax, ref zmax);// 将边界框的最小点和最大点添加到包围盒中aabb.Add(new Pnt2d(xmin, ymin));aabb.Add(new Pnt2d(xmax, ymax));}}Extents = aabb;}//--------------------------------------------------------------------------------------------------// 渲染public override bool Render(IDrawingRenderer renderer){// 获取BRep形状var shapes = _Source?.GetBreps();if (shapes == null)return true; // 没有要绘制的内容if (renderer.RenderElement(this))return true;// 设置绘制样式renderer.SetStyle(_Stroke, _Fill, null);renderer.BeginGroup(Name);bool res = true;foreach (var shape in shapes){// 绘制BRep形状res &= BrepRenderHelper.RenderShape(renderer, shape);}renderer.EndGroup();return res;}}
}
这段代码定义了一个BRep绘图类 BRepDrawing
,用于在绘图中渲染BRep形状。其中包含了描述样式和数据源的属性,以及渲染方法和辅助计算范围的方法。
9.
using System.Linq;
using Macad.Common;
using Macad.Common.Serialization;
using Macad.Occt;
using Macad.Occt.Helper;namespace Macad.Core.Drawing
{// HLR绘图类,用于生成隐藏线public class HlrDrawing : DrawingElement{// 图层类型枚举,定义了不同类型的绘图图层enum LayerType{Outline = 0,Inline = 1,HiddenOutline = 2,HiddenInline = 3}//--------------------------------------------------------------------------------------------------// 不同图层的描边样式数组static readonly StrokeStyle[] _StrokeStyles = {new (Color.Black, 0.2f, LineStyle.Solid),new (Color.Black, 0.1f, LineStyle.Solid),new (Color.Black, 0.1f, LineStyle.Dash),new (Color.Black, 0.05f, LineStyle.ShortDash),};//--------------------------------------------------------------------------------------------------// BRep数据源数组[SerializeMember]public IBrepSource[] Sources{get { return _Sources; }set{if (_Sources != value){SaveUndo();_Sources = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 投影轴[SerializeMember]public Ax3 Projection{get { return _Projection; }set{if (_Projection != value){SaveUndo();_Projection = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 包含的边类型[SerializeMember]public HlrEdgeTypes IncludedEdgeTypes{get { return _IncludedEdgeTypes; }set{if (_IncludedEdgeTypes != value){SaveUndo();_IncludedEdgeTypes = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 是否使用三角化[SerializeMember]public bool UseTriangulation{get { return _UseTriangulation; }set{if (_UseTriangulation != value){SaveUndo();_UseTriangulation = value;_Invalidate();RaisePropertyChanged();}}}//--------------------------------------------------------------------------------------------------// 是否使用三角化bool _UseTriangulation;// 包含的边类型HlrEdgeTypes _IncludedEdgeTypes;// 投影轴Ax3 _Projection;// BRep数据源数组IBrepSource[] _Sources;// BRep形状数组TopoDS_Shape[] _Shapes;//--------------------------------------------------------------------------------------------------// 创建HLR绘图对象的静态方法public static HlrDrawing Create(Ax3 projection, HlrEdgeTypes includedEdges, params IBrepSource[] sources){return new HlrDrawing(){_Projection = projection,_IncludedEdgeTypes = includedEdges,_Sources = sources,};}//--------------------------------------------------------------------------------------------------// 使几何失效void _Invalidate(){_Shapes = null;Extents = null;}//--------------------------------------------------------------------------------------------------// 计算范围protected override void CalculateExtents(){_EnsureShapes();}//--------------------------------------------------------------------------------------------------// 确保BRep形状准备就绪bool _EnsureShapes(){if (_Shapes != null)return true; // 已准备好// 创建BRep形状数组_Shapes = new TopoDS_Shape[4];Bnd_Box2d aabb = new Bnd_Box2d();if (_Sources == null)return true; // 没有要绘制的内容// 获取所有BRep形状var breps = _Sources.SelectMany(s => s.GetBreps());// 创建HLR算法实例HlrBRepAlgoBase hlrAlgo;if (_UseTriangulation)hlrAlgo = new HlrBRepAlgoPoly(breps);elsehlrAlgo = new HlrBRepAlgo(breps);// 设置投影轴hlrAlgo.SetProjection(_Projection);// 执行HLR算法hlrAlgo.Update();// 获取图层形状_CreateLayerShape(LayerType.Outline, HlrEdgeTypes.VisibleOutline, HlrEdgeTypes.VisibleSharp, hlrAlgo, aabb);_CreateLayerShape(LayerType.Inline, HlrEdgeTypes.VisibleSmooth, HlrEdgeTypes.VisibleSewn, hlrAlgo, aabb);_CreateLayerShape(LayerType.HiddenOutline, HlrEdgeTypes.HiddenOutline, HlrEdgeTypes.HiddenSharp, hlrAlgo, aabb);_CreateLayerShape(LayerType.HiddenInline, HlrEdgeTypes.HiddenSmooth, HlrEdgeTypes.HiddenSewn, hlrAlgo, aabb);// 更新范围Extents = aabb;return true;}//--------------------------------------------------------------------------------------------------// 创建图层形状void _CreateLayerShape(LayerType layerType, HlrEdgeTypes edgeType1, HlrEdgeTypes edgeType2, HlrBRepAlgoBase hlrAlgo, Bnd_Box2d aabb){TopoDS_Shape shape = null;var shape1 = _IncludedEdgeTypes.Has(edgeType1) ? hlrAlgo.GetResult(edgeType1) : null;var shape2 = _IncludedEdgeTypes.Has(edgeType2) ? hlrAlgo.GetResult(edgeType2) : null;if (shape1 != null && shape2 != null){var builder = new BRep_Builder();var compound = new TopoDS_Compound();builder.MakeCompound(compound);builder.Add(compound, hlrAlgo.GetResult(edgeType1));builder.Add(compound, hlrAlgo.GetResult(edgeType2));shape = compound;}else if (shape1 != null){shape = shape1;}else if (shape2 != null){shape = shape2;}if (shape == null) return;_Shapes[(int) layerType] = shape;// 更新边界矩形double xmin = 0;double xmax = 0;double ymin = 0;double ymax = 0;double zmin = 0;double zmax = 0;shape.BoundingBox()?.Get(ref xmin, ref ymin, ref zmin, ref xmax, ref ymax, ref zmax);aabb.Add(new Pnt2d(xmin, ymin));aabb.Add(new Pnt2d(xmax, ymax));}//--------------------------------------------------------------------------------------------------// 渲染public override bool Render(IDrawingRenderer renderer){// 确保BRep形状已准备就绪if (!_EnsureShapes())return false;if (renderer.RenderElement(this))return true;// 渲染不同图层bool res = _RenderLayer(renderer, LayerType.HiddenInline);res &= _RenderLayer(renderer, LayerType.Inline);res &= _RenderLayer(renderer, LayerType.HiddenOutline);res &= _RenderLayer(renderer, LayerType.Outline);return res;}//--------------------------------------------------------------------------------------------------// 渲染指定图层bool _RenderLayer(IDrawingRenderer renderer, LayerType type){var shape = _Shapes[(int) type];if (shape == null)return true; // 没有要渲染的内容// 设置渲染样式renderer.SetStyle(_StrokeStyles[(int)type], null, null);renderer.BeginGroup(type.ToString());// 渲染BRep形状bool res = BrepRenderHelper.RenderShape(renderer, shape);renderer.EndGroup();return res;}}
}
这段代码定义了一个HLR绘图类 HlrDrawing
,用于生成隐藏线图。它根据给定的BRep数据源和投影轴,通过执行HLR算法生成隐藏线图,并根据不同的边类型渲染到不同的图层上。
10.
using System;
using System.Collections.Generic;
using System.Linq;
using Macad.Common;
using Macad.Core.Geom;
using Macad.Core.Shapes;
using Macad.Core.Topology;
using Macad.Occt;namespace Macad.Core.Drawing
{// 管道绘图类,用于生成管道的轮廓和尺寸标注public class PipeDrawing : DrawingElement{#region Statics// 查找管道变换器public static Pipe FindPipeModifier(Body body){if (body == null){return null;}var shape = body.RootShape;while(shape != null){if (shape is Pipe pipe){return pipe;}shape = shape.Predecessor as Shape;}return null;}//--------------------------------------------------------------------------------------------------#endregion#region Members// 常量定义const double ExtensionLength = 10.0;const double BendAllowanceScale = 0.9;const double BendAllowanceThreshold = 0.175; // ~10°// 成员变量Body _Body;TopoDS_Shape _PipeShape;IList<Pipe.ArcInfo> _ArcInfos;IList<TopoDS_Wire> _SpineWires;Geom_Plane _Plane;TopoDS_Shape _Section;readonly List<DrawingElement> _Elements = new();//--------------------------------------------------------------------------------------------------// 创建管道绘图对象的静态方法public static PipeDrawing Create(Body body){return new PipeDrawing{_Body = body};}//--------------------------------------------------------------------------------------------------#endregion#region Make// 确保生成元素public bool _EnsureElements(){if (_Elements.Count > 0)return true;_Elements.Clear();if (!(_InitMake() && _MakeSection())){Messages.Error("The pipe drawing could not be generated.");return false;}// 轮廓_Elements.Add(new BRepDrawing(){Name = $"Contour",Source = new TopoDSBrepSource(_Section),Stroke = new StrokeStyle(Color.Black, 0.05f, LineStyle.Solid),Fill = new FillStyle(Color.Black)});// 尺寸标注foreach (var wire in _SpineWires){_AddDimensions(wire);}return true;}//--------------------------------------------------------------------------------------------------// 初始化生成bool _InitMake(){var pipe = FindPipeModifier(_Body);if (pipe == null){Messages.Error("Pipe Drawing processor requires a Pipe modifier in the shape stack of the owner body.");return false;}_PipeShape = pipe.GetBRep();if (pipe.HasErrors || _PipeShape == null){Messages.Error("The shape does not generate valid data.");return false;}_ArcInfos = pipe.GetArcInfos();if (_ArcInfos == null || _ArcInfos.Count == 0){Messages.Error("The shape does not generate valid data.");return false;}_SpineWires = pipe.GetSpineWires();if (_SpineWires == null || _SpineWires.Count == 0){Messages.Error("The shape does not generate valid data.");return false;}var edges = pipe.GetOperandWires().SelectMany(wire => wire.Edges());if (!EdgeAlgo.GetPlaneOfEdges(edges, out _Plane)){Messages.Error("The path of the pipe does not lie on the same plane.");return false;}return true;}//--------------------------------------------------------------------------------------------------// 生成管道剖面bool _MakeSection(){// 创建轮廓var cutPlaneFace = new TopoDS_Face();new BRep_Builder().MakeFace(cutPlaneFace, _Plane, 1e-7);var common = new BRepAlgoAPI_Common(_PipeShape, cutPlaneFace);if (!common.IsDone()){Messages.Error("Cannot create contour from pipe shape.");return false;}_Section = common.Shape();return true;}//--------------------------------------------------------------------------------------------------// 使几何失效void _Invalidate(){_Elements.Clear();Extents = null;}//--------------------------------------------------------------------------------------------------// 创建角度尺寸标注AngleDimension _CreateAngleDimension(Pipe.ArcInfo arcInfo, Pnt2d p1, Pnt2d p2){double u = 0, v = 0;ElSLib.Parameters(Pln.XOY, arcInfo.Center, ref u, ref v);Pnt2d pc = new(u, v);Dir2d leg1 = new Vec2d(pc, p1).ToDir();Dir2d leg2 = new Vec2d(pc, p2).ToDir();if (arcInfo.Angle.Abs() > BendAllowanceThreshold){// 应用角度公差 ElSLib.Parameters(Pln.XOY, arcInfo.Tangent1.ToPnt(), ref u, ref v);var allowance1 = new Vec2d(u, v).Normalized().Scaled(pc.Distance(p1) * arcInfo.Angle.Abs() * -0.5 * BendAllowanceScale);p1.Translate(allowance1);ElSLib.Parameters(Pln.XOY, arcInfo.Tangent2.ToPnt(), ref u, ref v);var allowance2 = new Vec2d(u, v).Normalized().Scaled(pc.Distance(p2) * arcInfo.Angle.Abs() * -0.5 * BendAllowanceScale);p2.Translate(allowance2);// 重新计算中心IntAna2d_AnaIntersection intersec = new(new gp_Lin2d(p1, leg1), new gp_Lin2d(p2, leg2));if (!intersec.IsDone())return null;pc = intersec.Point(1).Value();}// 计算位置var dir = new Vec2d(pc, p1.Lerped(p2, 0.5)).ToDir();var radius = Math.Max(pc.Distance(p1), pc.Distance(p2));var position = pc.Translated(dir.ToVec(radius + ExtensionLength));// 创建尺寸标注return new AngleDimension(){Position = position,FirstPoint = p1,SecondPoint = p2,CenterPoint = pc};}//--------------------------------------------------------------------------------------------------// 计算两个切线之间的角度double _GetAngleBetweenTangents(Pipe.ArcInfo arcInfo){double u = 0, v = 0;ElSLib.Parameters(Pln.XOY, arcInfo.Tangent1.ToPnt(), ref u, ref v);Vec2d t1 = new(u, v);ElSLib.Parameters(Pln.XOY, arcInfo.Tangent2.ToPnt(), ref u, ref v);Vec2d t2 = new(u, v);return t1.Angle(t2.Reversed());}//--------------------------------------------------------------------------------------------------// 创建长度尺寸标注LengthDimension _CreateLengthDimension(Pnt2d p1, Pnt2d p2, Pipe.ArcInfo nextArc, Pipe.ArcInfo priorArc){// 查找弯曲方向double arcAngle = 0.0;if (nextArc != null){arcAngle = _GetAngleBetweenTangents(nextArc);}if (priorArc != null && priorArc.Angle > arcAngle.Abs()){arcAngle = _GetAngleBetweenTangents(priorArc);}// 计算位置var dimDir = new Vec2d(p1, p2).ToDir();var extDir = new Dir2d(dimDir.Y, -dimDir.X);if (arcAngle < 0.0){extDir.Reverse();}// 应用公差double u = 0, v = 0;if (priorArc != null && priorArc.Angle > BendAllowanceThreshold){ElSLib.Parameters(Pln.XOY, priorArc.Tangent2.ToPnt(), ref u, ref v);p1.Translate(new Vec2d(u, v).Normalized().Scaled(priorArc.Center.Distance(priorArc.P2) * priorArc.Angle * -0.5 * BendAllowanceScale));}if (nextArc != null && nextArc.Angle > BendAllowanceThreshold){ElSLib.Parameters(Pln.XOY, nextArc.Tangent1.ToPnt(), ref u, ref v);p2.Translate(new Vec2d(u, v).Normalized().Scaled(nextArc.Center.Distance(nextArc.P1) * nextArc.Angle * -0.5 * BendAllowanceScale));}Pnt2d position = p1.Lerped(p2, 0.5).Translated(extDir.ToVec(ExtensionLength));// 创建尺寸标注return new LengthDimension(){Position = position,FirstPoint = p1,SecondPoint = p2};}//--------------------------------------------------------------------------------------------------// 添加尺寸标注void _AddDimensions(TopoDS_Wire wire){foreach (var edge in wire.Edges()){var vertices = edge.Vertices();double u = 0, v = 0;ElSLib.Parameters(Pln.XOY, vertices[0].Pnt(), ref u, ref v);Pnt2d p1 = new(u, v);ElSLib.Parameters(Pln.XOY, vertices[1].Pnt(), ref u, ref v);Pnt2d p2 = new(u, v);DrawingElement dim;var arcInfo = _ArcInfos.FirstOrDefault(si => si.P1.IsEqual(vertices[0].Pnt(), 1e-7) && si.P2.IsEqual(vertices[1].Pnt(), 1e-7));if (arcInfo != null){/***** 角度尺寸标注 *****/dim = _CreateAngleDimension(arcInfo, p1, p2);}else{/***** 长度尺寸标注 *****/// 获取下一个和前一个弧var nextArc = _ArcInfos.FirstOrDefault(si => si.P1.IsEqual(vertices[1].Pnt(), 1e-7));var priorArc = _ArcInfos.FirstOrDefault(si => si.P2.IsEqual(vertices[0].Pnt(), 1e-7));dim = _CreateLengthDimension(p1, p2, nextArc, priorArc);}if (dim != null){_Elements.Add(dim);}}}//--------------------------------------------------------------------------------------------------#endregion#region Drawing// 渲染public override bool Render(IDrawingRenderer renderer){if (!_EnsureElements())return false;bool result = true;foreach (var element in _Elements){result &= element.Render(renderer);}return result;}//--------------------------------------------------------------------------------------------------// 计算范围protected override void CalculateExtents(){if (!_EnsureElements())return;Bnd_Box2d aabb = new Bnd_Box2d();foreach (var element in _Elements){aabb.Add(element.Extents);}Extents = aabb;}//--------------------------------------------------------------------------------------------------#endregion}
}
这段代码定义了一个管道绘图类 PipeDrawing
,用于生成管道的轮廓和尺寸标注。
11.
using System;
using System.Collections.Generic;
using System.Linq;
using Macad.Common;
using Macad.Core.Geom;
using Macad.Occt;namespace Macad.Core.Drawing
{// 辅助类,用于渲染 BRep 形状的工具public static class BrepRenderHelper{// 渲染 BRep 形状public static bool RenderShape(IDrawingRenderer renderer, TopoDS_Shape brepShape){// 尝试直接渲染 BRep 形状if (renderer.RenderBrepShape(brepShape))return true;// 如果渲染失败,则尝试渲染其面return RenderFaces(renderer, brepShape);}//--------------------------------------------------------------------------------------------------// 渲染面public static bool RenderFaces(IDrawingRenderer renderer, TopoDS_Shape brepShape){var res = true;renderer.BeginPath();var faces = brepShape.Faces();if (faces.Count == 0){// 若 BRep 形状中没有面,则绘制线var wires = brepShape.Wires();if (wires.Count > 0){foreach (var wire in wires){res &= RenderEdges(renderer, wire.Edges(), null);}}else{// 若没有线,直接绘制松散的边res &= RenderEdges(renderer, brepShape.Edges(), null);}}else{// 绘制面foreach (var face in faces){var outerWire = BRepTools.OuterWire(face);if (outerWire == null)continue;// 绘制外边res &= RenderEdges(renderer, outerWire.Edges(), face);var wires = face.Wires();foreach (var wire in wires){// 绘制内边if (wire.IsEqual(outerWire))continue;res &= RenderEdges(renderer, wire.Edges(), face);}}}renderer.EndPath();return res;}//--------------------------------------------------------------------------------------------------// 渲染边public static bool RenderEdges(IDrawingRenderer renderer, List<TopoDS_Edge> edges, TopoDS_Face face){var res = true;// 查找平面Geom_Plane geomPlane;if (face?.Surface() is Geom_Plane facePlane){geomPlane = new Geom_Plane(Pln.XOY);}else{if (!EdgeAlgo.GetPlaneOfEdges(edges, out var edgesPlane)){return false;}geomPlane = edgesPlane;}// 对边进行排序var order = new ShapeAnalysis_WireOrder(true, 0.0001);foreach (var edge in edges){var first = BRep_Tool.Pnt(TopExp.FirstVertex(edge));var last = BRep_Tool.Pnt(TopExp.LastVertex(edge));if (edge.Orientation() == TopAbs_Orientation.FORWARD)order.Add(first.Coord, last.Coord);elseorder.Add(last.Coord, first.Coord);}order.Perform(true);if (order.IsDone()){order.SetChains(0.0001);for (int chain = 1; chain <= order.NbChains(); chain++){int startIndex = 0, endIndex = 0;order.Chain(chain, ref startIndex, ref endIndex);if(startIndex > endIndex)continue;// 处理排序后的边renderer.BeginPathSegment();for (int index = startIndex; index <= endIndex; index++){int orderIndex = order.Ordered(index);int originalIndex = Math.Abs(orderIndex) - 1; // order index is 1-basedres &= RenderEdge(renderer, edges[originalIndex], orderIndex < 0, geomPlane);}renderer.EndPathSegment();}}else{// 无法排序,直接绘制所有边foreach (var edge in edges)res &= RenderEdge(renderer, edge, false, geomPlane);}return res;}//--------------------------------------------------------------------------------------------------// 渲染边public static bool RenderEdge(IDrawingRenderer renderer, TopoDS_Edge edge, bool reverse, Geom_Plane plane){double first = 0, last = 0;bool store = false;var curve = BRep_Tool.CurveOnSurface(edge, plane, new TopLoc_Location(), ref first, ref last, ref store);if (curve == null)return false;reverse ^= edge.Orientation() == TopAbs_Orientation.REVERSED;return RenderCurve(renderer, curve, first, last, reverse);}//--------------------------------------------------------------------------------------------------// 渲染曲线public static bool RenderCurve(IDrawingRenderer renderer, Geom2d_Curve curve2d, double first, double last, bool reverse){switch (curve2d){case Geom2d_Line line:return RenderLine(renderer, line, first, last, reverse);case Geom2d_Ellipse ellipse:return RenderEllipse(renderer, ellipse, first, last, reverse);case Geom2d_Circle circle:return RenderCircle(renderer, circle, first, last, reverse);case Geom2d_BSplineCurve bspline:return RenderBSplineCurve(renderer, bspline, first, last, reverse);case Geom2d_BezierCurve bezier:return RenderBezierCurve(renderer, bezier, first, last, reverse);case Geom2d_TrimmedCurve trimmed:return RenderCurve(renderer, trimmed.BasisCurve(), Math.Max(first, trimmed.FirstParameter()), Math.Min(last, trimmed.LastParameter()), reverse);default:// 尝试创建 B-Spline 曲线var bsplineCurve = ShapeConstruct.ConvertCurveToBSpline(curve2d, first, last, 0.001 /*Precision.Confusion()*10*/, curve2d.Continuity(), 10000, 3);if (bsplineCurve != null){return RenderBSplineCurve(renderer, bsplineCurve, first, last, reverse);}Messages.Warning("BrepRenderHelper: Unsupported curve class.");return false;}}//--------------------------------------------------------------------------------------------------// 渲染直线public static bool RenderLine(IDrawingRenderer renderer, Geom2d_Line line, double first, double last, bool reverse){var start = line.Value(reverse ? last : first);var end = line.Value(reverse ? first : last);renderer.Line(start, end);return true;}//--------------------------------------------------------------------------------------------------// 渲染圆public static bool RenderCircle(IDrawingRenderer renderer, Geom2d_Circle circle, double first, double last, bool reverse){bool fullCircle = first.Distance(last).IsEqual(Maths.DoublePI, 0.00001);bool renderAsCurve = fullCircle ? renderer.Capabilities.CircleAsCurve : renderer.Capabilities.CircularArcAsCurve;if (renderAsCurve){var bsplineCurve = ShapeConstruct.ConvertCurveToBSpline(circle, first, last, 0.001, GeomAbs_Shape.C2, 100, 3);if (bsplineCurve != null){return RenderBSplineCurve(renderer, bsplineCurve, first, last, reverse);}return false;}var center = circle.Location();var radius = circle.Radius();double rotation = circle.XAxis().Direction.Angle(Dir2d.DX);if (circle.Position().Sense() > 0){first = Maths.DoublePI - first;last = Maths.DoublePI - last;}if (reverse){first.Swap(ref last);}renderer.Circle(center, radius, first - rotation, last - rotation);return true;}//--------------------------------------------------------------------------------------------------// 渲染椭圆public static bool RenderEllipse(IDrawingRenderer renderer, Geom2d_Ellipse ellipse, double first, double last, bool reverse){bool fullEllipse = first.Distance(last).IsEqual(Maths.DoublePI, 0.00001);bool renderAsCurve = fullEllipse ? renderer.Capabilities.EllipseAsCurve : renderer.Capabilities.EllipticalArcAsCurve;if (renderAsCurve){var bsplineCurve = ShapeConstruct.ConvertCurveToBSpline(ellipse, first, last, 0.001, GeomAbs_Shape.C1, 100, 3);if (bsplineCurve != null){return RenderBSplineCurve(renderer, bsplineCurve, first, last, reverse);}return false;}var center = ellipse.Location();var majorRadius = ellipse.MajorRadius();var minorRadius = ellipse.MinorRadius();double rotation = Dir2d.DX.Angle(ellipse.XAxis().Direction);if (ellipse.Position().Sense() > 0){first = Maths.DoublePI - first;last = Maths.DoublePI - last;}if (reverse){first.Swap(ref last);}renderer.Ellipse(center, majorRadius, minorRadius, rotation, first, last);return true;}//--------------------------------------------------------------------------------------------------// 渲染 B-Spline 曲线public static bool RenderBSplineCurve(IDrawingRenderer renderer, Geom2d_BSplineCurve bspline, double first, double last, bool reverse){if (renderer.Capabilities.BSplineCurveMaxDegree > 0){bspline = Geom2dConvert.SplitBSplineCurve(bspline, first, last, 0.00001);if (bspline.Degree() > renderer.Capabilities.BSplineCurveMaxDegree){// 尝试降低曲线次数var continuity = bspline.Continuity();if (continuity != GeomAbs_Shape.C0)continuity = GeomAbs_Shape.C1;var converter = new Geom2dConvert_ApproxCurve(bspline, 0.0001, continuity, 100, 3);if (!(converter.IsDone() && converter.HasResult())){Messages.Warning("BrepRenderHelper: BSpline curve has an undecreasable degree of " + bspline.Degree() + ".");return false;}bspline = converter.Curve();}var knotSource = bspline.KnotSequence();var knots = new double[knotSource.Length()];int sourceStart = knotSource.Lower();for (int i = 0; i < knots.Length; i++){knots[i] = knotSource.Value(sourceStart + i);}var points = new Pnt2d[bspline.NbPoles()];var weights = new double[points.Length];for (int i = 0; i < bspline.NbPoles(); i++){points[i] = bspline.Pole(i + 1);weights[i] = bspline.Weight(i + 1);}renderer.BSplineCurve(bspline.Degree(), knots, points, weights, bspline.IsRational());return true;}else{// 无法渲染 B-Spline,尝试 Beziervar converter = new Geom2dConvert_BSplineCurveToBezierCurve(bspline, first, last, 0.001 /*Precision.PConfusion() * 10*/);bool result = true;if (reverse){for (int i = converter.NbArcs(); i >= 1; i -= 1){var arc = converter.Arc(i);result &= RenderBezierCurve(renderer, arc, arc.FirstParameter(), arc.LastParameter(), true);}}else{for (int i = 1; i <= converter.NbArcs(); i += 1){var arc = converter.Arc(i);result &= RenderBezierCurve(renderer, arc, arc.FirstParameter(), arc.LastParameter(), false);}}return result;}}//--------------------------------------------------------------------------------------------------// 渲染 Bezier 曲线public static bool RenderBezierCurve(IDrawingRenderer renderer, Geom2d_BezierCurve bezier, double first, double last, bool reverse){if (renderer.Capabilities.BezierCurveMaxDegree > 0){var maxDegree = Math.Min(3, renderer.Capabilities.BezierCurveMaxDegree);if (bezier.Degree() > maxDegree){// 尝试降低曲线次数var continuity = bezier.Continuity();if (continuity != GeomAbs_Shape.C0)continuity = GeomAbs_Shape.C1;var converter = new Geom2dConvert_ApproxCurve(bezier, 0.0001, continuity, 1000, maxDegree);if (!(converter.IsDone() && converter.HasResult())){Messages.Warning("BrepRenderHelper: Bezier curve has an undecreasable order of " + bezier.Degree() + ".");return false;}return RenderBSplineCurve(renderer, converter.Curve(), first, last, reverse);}bezier.Segment(first, last);Pnt2d c1, c2;var start = reverse ? bezier.EndPoint() : bezier.StartPoint();var end = reverse ? bezier.StartPoint() : bezier.EndPoint();switch (bezier.Degree()){case 1:renderer.Line(start, end);return true;case 2:c1 = bezier.Pole(2);renderer.BezierCurve(new[] {start, c1, end});return true;case 3:c1 = bezier.Pole(reverse ? 3 : 2);c2 = bezier.Pole(reverse ? 2 : 3);renderer.BezierCurve(new[] {start, c1, c2, end});return true;default:Messages.Warning("BrepRenderHelper: Bezier curve has an unsupported order of " + bezier.Degree() + ".");break;}return false;}else{// 尝试创建 B-Spline 曲线var bsplineCurve = ShapeConstruct.ConvertCurveToBSpline(bezier, first, last, 0.0001, bezier.Continuity(), 10000, 3);if (bsplineCurve != null){return RenderBSplineCurve(renderer, bsplineCurve, first, last, reverse);}Messages.Warning("BrepRenderHelper: Bezier curve is not supported by exporter and conversion to BSpline failed.");return false;}}//--------------------------------------------------------------------------------------------------}
}
这段 C# 代码定义了一个静态类 BrepRenderHelper
,其中包含了一些静态方法,用于在图形绘制过程中渲染 Brep(Boundary Representation)模型的形状。
以下是每个方法的作用:
-
RenderShape(IDrawingRenderer renderer, TopoDS_Shape brepShape)
:- 该方法尝试使用给定的绘图渲染器渲染 Brep 模型的整体形状。
- 如果无法通过
RenderBrepShape
方法渲染整体形状,则调用RenderFaces
方法以渲染其面。
-
RenderFaces(IDrawingRenderer renderer, TopoDS_Shape brepShape)
:- 该方法渲染 Brep 模型的各个面。
- 如果 Brep 中不包含面,则将其中的边缘渲染出来。
-
RenderEdges(IDrawingRenderer renderer, List<TopoDS_Edge> edges, TopoDS_Face face)
:- 该方法渲染给定的边缘集合。
- 如果指定了面,则根据面的曲面类型确定渲染方式;否则,尝试根据边缘的几何特性确定平面。
-
RenderEdge(IDrawingRenderer renderer, TopoDS_Edge edge, bool reverse, Geom_Plane plane)
:- 该方法渲染单个边缘。
- 如果指定了平面,使用该平面来获取边缘上的曲线。
-
RenderCurve(IDrawingRenderer renderer, Geom2d_Curve curve2d, double first, double last, bool reverse)
:- 该方法渲染二维曲线。
- 根据曲线类型调用相应的渲染方法。
-
RenderLine(IDrawingRenderer renderer, Geom2d_Line line, double first, double last, bool reverse)
:- 渲染直线。
-
RenderCircle(IDrawingRenderer renderer, Geom2d_Circle circle, double first, double last, bool reverse)
:- 渲染圆或圆弧。
-
RenderEllipse(IDrawingRenderer renderer, Geom2d_Ellipse ellipse, double first, double last, bool reverse)
:- 渲染椭圆或椭圆弧。
-
RenderBSplineCurve(IDrawingRenderer renderer, Geom2d_BSplineCurve bspline, double first, double last, bool reverse)
:- 渲染 B-Spline 曲线。
-
RenderBezierCurve(IDrawingRenderer renderer, Geom2d_BezierCurve bezier, double first, double last, bool reverse)
:- 渲染 Bezier 曲线。
这些方法用于将 Brep 模型的几何信息转换为可供绘图渲染器绘制的图形元素。
11.
using System.Collections.Generic;
using Macad.Core.Topology;
using Macad.Occt;namespace Macad.Core.Drawing
{// 接口:定义获取 Brep 模型的方法public interface IBrepSource{IEnumerable<TopoDS_Shape> GetBreps(); // 获取 Brep 模型的方法}//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------// 结构体:从 TopoDS_Shape 数组中获取 Brep 模型public readonly struct TopoDSBrepSource : IBrepSource{public TopoDS_Shape[] Shapes { get; } // 包含的 Brep 模型数组// 构造函数:初始化 Brep 模型数组public TopoDSBrepSource(params TopoDS_Shape[] shapes){Shapes = shapes;}//--------------------------------------------------------------------------------------------------// 实现接口方法:从 Shapes 数组中获取 Brep 模型public IEnumerable<TopoDS_Shape> GetBreps(){if (Shapes == null) // 若数组为空,则返回空yield break;foreach (var shape in Shapes) // 遍历 Brep 模型数组,逐个返回{yield return shape;}}}//--------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------// 结构体:从 Body 对象中获取 Brep 模型public readonly struct BodyBrepSource : IBrepSource{public Body Body { get; } // 包含的几何体 Body// 构造函数:初始化 Bodypublic BodyBrepSource(Body body){Body = body;}//--------------------------------------------------------------------------------------------------// 实现接口方法:从 Body 对象中获取变换后的 Brep 模型public IEnumerable<TopoDS_Shape> GetBreps(){var shape = Body?.GetTransformedBRep(); // 获取经过变换的 Brep 模型if (shape == null) // 若获取失败,则返回空yield break;yield return shape; // 返回获取到的 Brep 模型}}//--------------------------------------------------------------------------------------------------}
这段 C# 代码定义了两个结构体和一个接口,它们用于提供 Brep(Boundary Representation)模型的数据源。
-
IBrepSource
接口:- 该接口定义了一个方法
GetBreps()
,用于获取 Brep 模型的集合。 - 具体实现类需要提供相应的获取方法。
- 该接口定义了一个方法
-
TopoDSBrepSource
结构体:- 该结构体实现了
IBrepSource
接口。 - 它包含一个 TopoDS_Shape 数组,表示一个或多个 Brep 模型。
- 构造函数用于初始化
Shapes
数组。 GetBreps()
方法实现了接口方法,用于获取包含在Shapes
数组中的 Brep 模型。
- 该结构体实现了
-
BodyBrepSource
结构体:- 该结构体也实现了
IBrepSource
接口。 - 它包含一个
Body
对象,表示一个 Macad 中的几何体。 - 构造函数用于初始化
Body
。 GetBreps()
方法实现了接口方法,用于获取通过Body
对象的变换后的 Brep 模型。
- 该结构体也实现了
这些结构体和接口提供了一种灵活的方式,用于从不同的数据源中获取 Brep 模型,并在图形绘制过程中使用它们。
12.
using Macad.Common.Serialization; // 导入序列化相关的命名空间
using Macad.Core.Topology; // 导入几何拓扑相关的命名空间
using Macad.Occt; // 导入 Occt 相关的命名空间namespace Macad.Core.Drawing
{// 类:绘图对象,继承自实体容器 EntityContainer,其中包含了 DrawingElement 元素public sealed class Drawing : EntityContainer<DrawingElement>{// 属性:名称,覆盖了基类的名称属性,用于获取和设置绘图的名称[SerializeMember(SortKey = -900)]public override string Name{get { return _Name; } // 获取名称set // 设置名称{if (_Name != value) // 若新名称与旧名称不同{SaveUndo(); // 保存撤销信息_Name = value; // 设置新名称RaisePropertyChanged(); // 触发属性变化事件}}}//--------------------------------------------------------------------------------------------------string _Name; // 内部字段:名称//--------------------------------------------------------------------------------------------------// 构造函数:初始化 Drawing 对象public Drawing(){// 初始化名称为 "Drawing",并为其添加文档中的下一个名称后缀_Name = CoreContext.Current?.Document?.AddNextNameSuffix(nameof(Drawing)) ?? "Drawing";}//--------------------------------------------------------------------------------------------------// 方法:获取绘图对象的二维包围盒public Bnd_Box2d GetBoundingBox(){Bnd_Box2d aabb = new(); // 创建二维包围盒对象foreach (var element in this) // 遍历绘图元素集合{// 将元素的包围盒应用变换后添加到绘图对象的二维包围盒中aabb.Add(element.Extents.Transformed(new Trsf2d(element.Position, element.Rotation)));}// 添加边界aabb.SetGap(10.0); // 在每个边上增加 10.0 单位的间隙,相当于在绘图对象周围留出 1cm 的空间return aabb; // 返回计算得到的二维包围盒}//--------------------------------------------------------------------------------------------------// 方法:渲染绘图对象public void Render(IDrawingRenderer renderer){foreach (var element in this) // 遍历绘图元素集合{element.Render(renderer); // 渲染每个绘图元素}}}
}
这段代码定义了一个绘图对象 Drawing
,用于管理绘图元素并进行渲染。它包含了绘图元素的集合,可以获取绘图对象的名称、二维包围盒,并对其进行渲染
13.
using Macad.Common.Serialization; // 导入序列化相关的命名空间
using Macad.Core.Topology; // 导入几何拓扑相关的命名空间
using Macad.Occt; // 导入 Occt 相关的命名空间namespace Macad.Core.Drawing
{// 抽象类:绘图元素,继承自实体 Entitypublic abstract class DrawingElement : Entity{// 属性:名称,覆盖了基类的名称属性,用于获取和设置绘图元素的名称[SerializeMember(SortKey = -900)]public override string Name{get { return _Name; } // 获取名称set // 设置名称{if (_Name != value) // 若新名称与旧名称不同{SaveUndo(); // 保存撤销信息_Name = value; // 设置新名称RaisePropertyChanged(); // 触发属性变化事件}}}//--------------------------------------------------------------------------------------------------string _Name; // 内部字段:名称//--------------------------------------------------------------------------------------------------// 属性:位置,用于获取和设置绘图元素的位置[SerializeMember]public Pnt2d Position{get { return _Position; } // 获取位置set // 设置位置{if (_Position != value) // 若新位置与旧位置不同{SaveUndo(); // 保存撤销信息_Position = value; // 设置新位置RaisePropertyChanged(); // 触发属性变化事件}}}//--------------------------------------------------------------------------------------------------// 属性:旋转角度,用于获取和设置绘图元素的旋转角度[SerializeMember]public double Rotation{get { return _Rotation; } // 获取旋转角度set // 设置旋转角度{if (_Rotation != value) // 若新旋转角度与旧旋转角度不同{SaveUndo(); // 保存撤销信息_Rotation = value; // 设置新旋转角度RaisePropertyChanged(); // 触发属性变化事件}}}//--------------------------------------------------------------------------------------------------// 属性:包围盒,用于获取和设置绘图元素的包围盒[SerializeMember]public Bnd_Box2d Extents{get{if (_Extents == null) // 若包围盒为空{CalculateExtents(); // 计算包围盒}return _Extents ?? new Bnd_Box2d(); // 返回包围盒,若为空则返回一个空的包围盒}set{if (_Extents != value) // 若新包围盒与旧包围盒不同{_Extents = value; // 设置新包围盒RaisePropertyChanged(); // 触发属性变化事件}}}//--------------------------------------------------------------------------------------------------Pnt2d _Position; // 内部字段:位置double _Rotation; // 内部字段:旋转角度Bnd_Box2d _Extents; // 内部字段:包围盒//--------------------------------------------------------------------------------------------------// 抽象方法:渲染绘图元素,派生类需实现具体的渲染逻辑public abstract bool Render(IDrawingRenderer renderer);//--------------------------------------------------------------------------------------------------// 抽象方法:计算包围盒,派生类需实现具体的包围盒计算逻辑protected abstract void CalculateExtents();}
}
这段代码定义了一个抽象类 DrawingElement
,用于表示绘图元素,它包含了名称、位置、旋转角度和包围盒等属性,并提供了抽象方法 Render
用于渲染绘图元素,以及抽象方法 CalculateExtents
用于计算包围盒。
14.
using Macad.Common; // 导入 Macad.Common 命名空间namespace Macad.Core.Drawing
{// 绘图参数集,继承自 OverridableParameterSet 类public class DrawingParameterSet : OverridableParameterSet{// 属性:尺寸箭头长度,用于获取和设置绘图中尺寸箭头的长度public double DimensionArrowLength { get => GetValue<double>(); // 获取属性值set => SetValue(value); // 设置属性值}// 属性:尺寸箭头宽度,用于获取和设置绘图中尺寸箭头的宽度public double DimensionArrowWidth { get => GetValue<double>(); // 获取属性值set => SetValue(value); // 设置属性值}// 属性:默认字体族,用于获取和设置绘图中的默认字体族public string DefaultFontFamily { get => GetValue<string>(); // 获取属性值set => SetValue(value); // 设置属性值}// 属性:默认字体大小,用于获取和设置绘图中的默认字体大小public float DefaultFontSize { get => GetValue<float>(); // 获取属性值set => SetValue(value); // 设置属性值}//--------------------------------------------------------------------------------------------------// 构造函数:初始化绘图参数集public DrawingParameterSet(){// 设置默认值SetDefaultValue(nameof(DimensionArrowLength), 3.0); // 尺寸箭头长度默认为3.0SetDefaultValue(nameof(DimensionArrowWidth), 1.0); // 尺寸箭头宽度默认为1.0SetDefaultValue(nameof(DefaultFontFamily), "Arial"); // 默认字体族默认为 ArialSetDefaultValue(nameof(DefaultFontSize), 3.0f); // 默认字体大小默认为 3.0}}
}
这段代码定义了一个名为 DrawingParameterSet
的类,用于管理绘图相关的参数集。它继承自 OverridableParameterSet
类,并包含了四个属性:DimensionArrowLength
(尺寸箭头长度)、DimensionArrowWidth
(尺寸箭头宽度)、DefaultFontFamily
(默认字体族)和 DefaultFontSize
(默认字体大小)。构造函数初始化了这些属性的默认值。
15.
using System; // 导入 System 命名空间
using System.Drawing; // 导入 System.Drawing 命名空间
using Macad.Common.Interop; // 导入 Macad.Common.Interop 命名空间
using Macad.Occt; // 导入 Macad.Occt 命名空间namespace Macad.Core.Drawing
{// 绘图渲染辅助类public static class DrawingRenderHelper{// 获取默认字体样式public static FontStyle GetDefaultFontStyle(){// 获取绘图参数集var parameterSet = CoreContext.Current.Parameters.Get<DrawingParameterSet>();// 返回默认字体样式return new FontStyle(parameterSet.DefaultFontFamily, parameterSet.DefaultFontSize);}//--------------------------------------------------------------------------------------------------// 获取箭头尺寸public static (double Length, double Width) GetArrowSize(){// 获取绘图参数集var parameterSet = CoreContext.Current.Parameters.Get<DrawingParameterSet>();// 返回箭头尺寸return (parameterSet.DimensionArrowLength, parameterSet.DimensionArrowWidth);}//--------------------------------------------------------------------------------------------------// 渲染箭头public static void RenderArrow(IDrawingRenderer renderer, Ax2d location, double scale=1.0){// 获取箭头尺寸var arrowSize = GetArrowSize();// 计算箭头点var p1 = location.Location;var backpoint = p1.Translated(location.Direction.Reversed().ToVec(arrowSize.Length * scale));var rightVec = new Vec2d(location.Direction.Y, -location.Direction.X).Scaled(arrowSize.Width * 0.5 * scale);var p2 = backpoint.Translated(rightVec);var p3 = backpoint.Translated(rightVec.Reversed());// 设置绘制样式renderer.SetStyle(null, new FillStyle(Common.Color.Black), null);renderer.BeginPath();renderer.BeginPathSegment();renderer.Line(p1, p2);renderer.Line(p2, p3);renderer.Line(p3, p1);renderer.EndPathSegment();renderer.EndPath();}//--------------------------------------------------------------------------------------------------// 渲染交叉线public static void RenderCross(IDrawingRenderer renderer, Pnt2d point){// 绘制两条交叉线renderer.Line(point.Translated(new Vec2d(-1, -1)), point.Translated(new Vec2d(1, 1)));renderer.Line(point.Translated(new Vec2d(-1, 1)), point.Translated(new Vec2d(1, -1)));}//--------------------------------------------------------------------------------------------------// 测量文本尺寸public static XY MeasureText(string text, FontStyle style){// 创建字体对象Font font = new Font(new FontFamily(style.Family), style.Size, System.Drawing.FontStyle.Regular, GraphicsUnit.Millimeter);// 创建图形对象using var g = Graphics.FromHwnd(IntPtr.Zero);g.PageUnit = GraphicsUnit.Millimeter;// 测量文本尺寸var size = g.MeasureString(text, font, new SizeF(), StringFormat.GenericTypographic);return new XY(size.Width, size.Height);}}
}
这段代码定义了一个静态类 DrawingRenderHelper
,其中包含了一系列静态方法,用于在绘图中进行渲染和测量文本尺寸等操作。方法包括:
GetDefaultFontStyle()
:获取默认字体样式。GetArrowSize()
:获取箭头尺寸。RenderArrow()
:渲染箭头。RenderCross()
:渲染交叉线。MeasureText()
:测量文本尺寸。
16.
using Macad.Occt;namespace Macad.Core.Drawing
{// 绘图渲染器接口public interface IDrawingRenderer{// 渲染器能力IRendererCapabilities Capabilities { get; }//--------------------------------------------------------------------------------------------------// 绘制直线void Line(Pnt2d start, Pnt2d end);// 绘制圆void Circle(Pnt2d center, double radius, double startAngle, double endAngle);// 绘制椭圆void Ellipse(Pnt2d center, double majorRadius, double minorRadius, double rotation, double startAngle, double endAngle);// 绘制贝塞尔曲线void BezierCurve(Pnt2d[] knots);// 绘制B样条曲线void BSplineCurve(int degree, double[] knots, Pnt2d[] controlPoints, double[] weights, bool isRational);// 绘制文本void Text(string text, Pnt2d position, double rotation);//--------------------------------------------------------------------------------------------------// 开始分组void BeginGroup(string name);// 结束分组void EndGroup();// 开始路径void BeginPath();// 结束路径void EndPath();// 开始路径段void BeginPathSegment();// 结束路径段void EndPathSegment();//--------------------------------------------------------------------------------------------------// 设置样式void SetStyle(StrokeStyle stroke, FillStyle fill, FontStyle font);//--------------------------------------------------------------------------------------------------// 渲染绘图元素bool RenderElement(DrawingElement element);// 渲染Brep形状bool RenderBrepShape(TopoDS_Shape shape);//--------------------------------------------------------------------------------------------------}
}
17.
namespace Macad.Core.Drawing
{// 渲染器能力接口public interface IRendererCapabilities{// 获取或设置B样条曲线的最大次数int BSplineCurveMaxDegree { get; }// 获取或设置贝塞尔曲线的最大次数int BezierCurveMaxDegree { get; }// 获取或设置是否将圆渲染为曲线bool CircleAsCurve { get; }// 获取或设置是否将圆弧渲染为曲线bool CircularArcAsCurve { get; }// 获取或设置是否将椭圆渲染为曲线bool EllipseAsCurve { get; }// 获取或设置是否将椭圆弧渲染为曲线bool EllipticalArcAsCurve { get; }}
}
这段代码定义了一个名为 IRendererCapabilities
的接口,用于表示渲染器的能力,它具有以下属性:
BSplineCurveMaxDegree
:获取或设置B样条曲线的最大次数。BezierCurveMaxDegree
:获取或设置贝塞尔曲线的最大次数。CircleAsCurve
:获取或设置是否将圆渲染为曲线。CircularArcAsCurve
:获取或设置是否将圆弧渲染为曲线。EllipseAsCurve
:获取或设置是否将椭圆渲染为曲线。EllipticalArcAsCurve
:获取或设置是否将椭圆弧渲染为曲线。- 18.
using Macad.Common;namespace Macad.Core.Drawing {// 线条样式类public class StrokeStyle{// 颜色public Color? Color { get; }// 宽度public float Width { get; }// 线条样式public LineStyle LineStyle { get; }// 构造函数public StrokeStyle(Color? color, float width, LineStyle lineStyle){Color = color;Width = width;LineStyle = lineStyle;}}// 填充样式类public class FillStyle{// 颜色public Color? Color { get; }// 构造函数public FillStyle(Color? color){Color = color;}}// 字体样式类public class FontStyle{// 字体public string Family { get; }// 字体大小public float Size { get; }// 构造函数public FontStyle(string family, float size){Family = family;Size = size;}// 判断是否相等public bool IsEqual(FontStyle other){return Family == other.Family&& Size == other.Size;}} }
这段代码定义了三个类:
StrokeStyle
:表示绘制线条的样式,包括颜色、宽度和线条样式。FillStyle
:表示填充区域的样式,包括颜色。FontStyle
:表示文本的字体样式,包括字体和大小。
这篇关于macad.core解析auxiliary、components、drawing的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!