From 7412780d10c5c4dd4dd77f4875bafe10b67dd570 Mon Sep 17 00:00:00 2001 From: Wertoi Date: Sat, 8 Feb 2020 14:30:36 +0100 Subject: [PATCH] v3.0 --- Graphy/App.xaml | 207 +++- Graphy/{ => CustomControl}/TextBoxWithUnit.cs | 3 +- Graphy/Enum/ViewModelToken.cs | 9 +- Graphy/Graphy.csproj | 16 +- Graphy/MainWindow.xaml | 138 +-- Graphy/MainWindow.xaml.cs | 33 +- Graphy/Model/CatiaChar.cs | 188 --- Graphy/Model/CatiaShape/CatiaCharacter.cs | 203 ++++ Graphy/Model/CatiaShape/CatiaContour.cs | 148 ++- Graphy/Model/CatiaShape/CatiaSurface.cs | 121 +- Graphy/Model/Contour.cs | 121 -- Graphy/Model/DesignTable.cs | 80 -- Graphy/Model/GeneratedFont.cs | 110 -- Graphy/Model/Generator/FontGenerator.cs | 546 --------- Graphy/Model/Generator/MarkingGenerator.cs | 1011 ++++------------- .../Model/Generator/SupportedCharGenerator.cs | 43 +- Graphy/Model/MarkingData.cs | 6 +- Graphy/Model/{Font.cs => SelectableFont.cs} | 126 +- Graphy/Properties/Resources.en-US.resx | 47 +- Graphy/Properties/Resources.fr-FR.resx | 45 +- Graphy/Themes/Generic.xaml | 8 +- Graphy/View/DesignTableView.xaml | 8 +- Graphy/View/FontView.xaml | 248 ++++ .../{NewFontView.xaml.cs => FontView.xaml.cs} | 9 +- Graphy/View/NewFontView.xaml | 92 -- Graphy/View/SettingView.xaml | 61 +- Graphy/View/SettingView.xaml.cs | 6 - Graphy/View/StatusView.xaml | 21 +- Graphy/View/StatusView.xaml.cs | 12 - Graphy/ViewModel/DesignTableViewModel.cs | 2 +- Graphy/ViewModel/FontViewModel.cs | 304 +++-- Graphy/ViewModel/InputDataViewModel.cs | 9 +- Graphy/ViewModel/SettingViewModel.cs | 213 +--- Graphy/ViewModel/StatusViewModel.cs | 29 +- 34 files changed, 1520 insertions(+), 2703 deletions(-) rename Graphy/{ => CustomControl}/TextBoxWithUnit.cs (98%) delete mode 100644 Graphy/Model/CatiaChar.cs create mode 100644 Graphy/Model/CatiaShape/CatiaCharacter.cs delete mode 100644 Graphy/Model/Contour.cs delete mode 100644 Graphy/Model/DesignTable.cs delete mode 100644 Graphy/Model/GeneratedFont.cs delete mode 100644 Graphy/Model/Generator/FontGenerator.cs rename Graphy/Model/{Font.cs => SelectableFont.cs} (56%) create mode 100644 Graphy/View/FontView.xaml rename Graphy/View/{NewFontView.xaml.cs => FontView.xaml.cs} (72%) delete mode 100644 Graphy/View/NewFontView.xaml diff --git a/Graphy/App.xaml b/Graphy/App.xaml index 6273cdd..45c8476 100644 --- a/Graphy/App.xaml +++ b/Graphy/App.xaml @@ -4,6 +4,7 @@ xmlns:local="clr-namespace:Graphy" xmlns:conv="clr-namespace:Graphy.Converter" xmlns:vm="clr-namespace:Graphy.ViewModel" + xmlns:cc="clr-namespace:Graphy.CustomControl" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" x:Class="Graphy.App" StartupUri="MainWindow.xaml"> @@ -20,9 +21,27 @@ + + False + True + + + + + + + + + + + + + + + - + 0.87 0.54 @@ -40,7 +59,7 @@ - + @@ -73,9 +92,54 @@ - - + + + + + + + + + - + - - + + + + + + - - + + + @@ -260,19 +352,6 @@ - - - - - - - - - - - - - @@ -285,6 +364,7 @@ + @@ -339,7 +426,7 @@ - + @@ -400,6 +487,7 @@ + + - + + + + + + + + + + + + + + - @@ -569,16 +696,16 @@ - + - + - + @@ -593,10 +720,10 @@ - + - + /// Suivez les étapes 1a ou 1b puis 2 pour utiliser ce contrôle personnalisé dans un fichier XAML. @@ -61,6 +61,5 @@ public string Unit public static readonly DependencyProperty UnitProperty = DependencyProperty.Register("Unit", typeof(string), typeof(TextBoxWithUnit), new PropertyMetadata("")); - } } diff --git a/Graphy/Enum/ViewModelToken.cs b/Graphy/Enum/ViewModelToken.cs index 13abf18..1780a56 100644 --- a/Graphy/Enum/ViewModelToken.cs +++ b/Graphy/Enum/ViewModelToken.cs @@ -16,10 +16,7 @@ public enum CatiaToken public enum FontToken { - DirectoryNotFound, - FileReadingFailed, - GenerateNewFont, - SupportedCharacterComputed + FavoriteFontListChanged }; public enum InputDataToken @@ -39,12 +36,12 @@ public enum ProcessToken public enum SettingToken { + UserPreferencesChanged, GeneratedFontDirectoryPathChanged, ClassicFontDirectoryPathChanged, SettingFileReadingFailed, SettingFileWritingFailed, - LicenceFileReadingFailed, - ComputedFontCollectionChanged, + LicenceFileReadingFailed } public enum DesignTableToken diff --git a/Graphy/Graphy.csproj b/Graphy/Graphy.csproj index 18fecd3..a8fbcbf 100644 --- a/Graphy/Graphy.csproj +++ b/Graphy/Graphy.csproj @@ -93,24 +93,20 @@ + - - - - - + + - - @@ -123,8 +119,8 @@ DesignTableView.xaml - - NewFontView.xaml + + FontView.xaml SettingView.xaml @@ -153,7 +149,7 @@ Designer MSBuild:Compile - + Designer MSBuild:Compile diff --git a/Graphy/MainWindow.xaml b/Graphy/MainWindow.xaml index 9249185..63bcf37 100644 --- a/Graphy/MainWindow.xaml +++ b/Graphy/MainWindow.xaml @@ -4,10 +4,11 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Graphy" + xmlns:cc="clr-namespace:Graphy.CustomControl" xmlns:view="clr-namespace:Graphy.View" xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" x:Class="Graphy.MainWindow" mc:Ignorable="d" - Title="Graphy" Height="720" Width="500" WindowStartupLocation="CenterScreen" Icon="Icon/Graphy_Icon.ico"> + Title="Graphy" Height="720" Width="450" WindowStartupLocation="CenterScreen" Icon="Icon/Graphy_Icon.ico"> @@ -17,7 +18,7 @@ - + @@ -26,6 +27,7 @@ + - + + @@ -122,13 +125,13 @@ + FontFamily="{Binding Source={StaticResource Locator}, Path=FontViewModel.SelectedFont.FontFamily}"/> + Visibility="{Binding FontViewModel.FontCollection.View.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}, Source={StaticResource Locator}}"> @@ -143,104 +146,34 @@ - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -249,7 +182,7 @@ - @@ -260,7 +193,7 @@ - @@ -286,7 +219,7 @@ - + @@ -440,14 +373,13 @@ + BackButtonClicked="SettingView_BackButtonClicked" /> - + - diff --git a/Graphy/MainWindow.xaml.cs b/Graphy/MainWindow.xaml.cs index 91ed9a3..b5957c0 100644 --- a/Graphy/MainWindow.xaml.cs +++ b/Graphy/MainWindow.xaml.cs @@ -26,16 +26,15 @@ public MainWindow() InitializeComponent(); } - private void StateView_QuitButtonClicked(object sender, EventArgs e) - { - this.Close(); - } - private void SelectionButton_Click(object sender, RoutedEventArgs e) { this.WindowState = WindowState.Minimized; } + + + // ***** SETTING VIEW MANAGEMENT ***** + private void SettingView_BackButtonClicked(object sender, EventArgs e) { SettingView.Visibility = Visibility.Collapsed; @@ -46,6 +45,13 @@ private void SettingButton_Click(object sender, RoutedEventArgs e) SettingView.Visibility = Visibility.Visible; } + // ***** END OF SETTING VIEW MANAGEMENT ***** + + + + + // ***** DESIGN TABLE VIEW MANAGEMENT ***** + private void DesignTableView_BackButtonClicked(object sender, EventArgs e) { DesignTableView.Visibility = Visibility.Collapsed; @@ -56,14 +62,23 @@ private void DesignTableButton_Click(object sender, RoutedEventArgs e) DesignTableView.Visibility = Visibility.Visible; } - private void SettingView_ShowAddNewFont(object sender, EventArgs e) + // ***** END OF DESIGN TABLE VIEW MANAGEMENT ***** + + + + + // ***** FONT VIEW MANAGEMENT ***** + + private void FontView_BackButtonClicked(object sender, EventArgs e) { - NewFontView.Visibility = Visibility.Visible; + FontView.Visibility = Visibility.Collapsed; } - private void NewFontView_BackButtonClicked(object sender, EventArgs e) + private void FontButton_Click(object sender, RoutedEventArgs e) { - NewFontView.Visibility = Visibility.Collapsed; + FontView.Visibility = Visibility.Visible; } + + // ***** END OF FONT VIEW MANAGEMENT ***** } } diff --git a/Graphy/Model/CatiaChar.cs b/Graphy/Model/CatiaChar.cs deleted file mode 100644 index 423d3bb..0000000 --- a/Graphy/Model/CatiaChar.cs +++ /dev/null @@ -1,188 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using INFITF; -using MECMOD; -using HybridShapeTypeLib; -using GalaSoft.MvvmLight; - -namespace Graphy.Model -{ - public class CatiaChar : ObservableObject - { - // CONSTRUCTOR - public CatiaChar(char value) - { - Value = value; - OriginalContourShapeList = new List(); - SurfaceList = new List(); - } - - - // ATTRIBUTS - private char _value; - private double _defaultHeight; - private double _defaultWidth; - private double _scaleRatio; - private double _scaledHeight; - private double _scaleWidth; - private List _originalContourShapeList; - private List _surfaceList; - private Reference _surfaceListAssembledRef; - - - public char Value - { - get => _value; - set - { - Set(() => Value, ref _value, value); - } - } - - - public double DefaultHeight - { - get => _defaultHeight; - set - { - Set(() => DefaultHeight, ref _defaultHeight, value); - } - } - - public double DefaultWidth - { - get => _defaultWidth; - set - { - Set(() => DefaultWidth, ref _defaultWidth, value); - } - } - - public double ScaleRatio - { - get => _scaleRatio; - set - { - Set(() => ScaleRatio, ref _scaleRatio, value); - - ScaledHeight = DefaultHeight * ScaleRatio; - ScaleWidth = DefaultWidth * ScaleRatio; - } - } - - public double ScaledHeight - { - get => _scaledHeight; - set - { - Set(() => ScaledHeight, ref _scaledHeight, value); - } - } - - public double ScaleWidth - { - get => _scaleWidth; - set - { - Set(() => ScaleWidth, ref _scaleWidth, value); - } - } - - public List SurfaceList - { - get => _surfaceList; - set - { - Set(() => SurfaceList, ref _surfaceList, value); - } - } - public Reference SurfaceListAssembledRef - { - get => _surfaceListAssembledRef; - set - { - Set(() => SurfaceListAssembledRef, ref _surfaceListAssembledRef, value); - } - } - public List OriginalContourShapeList - { - get => _originalContourShapeList; - set - { - Set(() => OriginalContourShapeList, ref _originalContourShapeList, value); - } - } - - - // METHODS - - public void LoadSurfaceListFromSet(HybridBody set, Contour.ContourStatus contourStatus) - { - SurfaceList.Clear(); - - foreach (HybridShape shape in set.HybridShapes) - { - // Reminder, shape name format : "Ext.#" for EXT contour and "Ext.#-Int.#" for INT contour. - string[] shapeSplitName = shape.get_Name().Split('-'); - - // If the name cannot be splitted by '-', it means we have an EXT contour. - if (shapeSplitName.Count() == 1) - { - SurfaceList.Add(new Surface() - { - ExtContour = new Contour(shape, contourStatus) - }); - } - else // Otherwise it's an INT contour - { - foreach (Surface surface in SurfaceList) - { - if (surface.ExtContour.Name(contourStatus) == shapeSplitName.First()) - { - surface.IntContourList.Add(new Contour(shape, contourStatus)); - surface.IsIntContourListEmpty = false; - break; - } - } - } - } - } - } - - public class Surface - { - public Surface() - { - IntContourList = new List(); - } - - private Contour _extContour; - private List _intContourList; - private bool _isIntContourListEmpty; - private Reference _intContourListAssembledRef; - private Reference _surfaceRef; - - public Contour ExtContour { get => _extContour; set => _extContour = value; } - public List IntContourList - { - get => _intContourList; - set - { - _intContourList = value; - - if (IntContourList.Count > 0) - IsIntContourListEmpty = false; - else - IsIntContourListEmpty = true; - } - } - - public bool IsIntContourListEmpty { get => _isIntContourListEmpty; set => _isIntContourListEmpty = value; } - public Reference IntContourListAssembledRef { get => _intContourListAssembledRef; set => _intContourListAssembledRef = value; } - public Reference SurfaceRef { get => _surfaceRef; set => _surfaceRef = value; } - } -} diff --git a/Graphy/Model/CatiaShape/CatiaCharacter.cs b/Graphy/Model/CatiaShape/CatiaCharacter.cs new file mode 100644 index 0000000..f8b7bd7 --- /dev/null +++ b/Graphy/Model/CatiaShape/CatiaCharacter.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; +using HybridShapeTypeLib; +using MECMOD; + +namespace Graphy.Model.CatiaShape +{ + public class CatiaCharacter : CatiaGenericShape + { + public CatiaCharacter(PartDocument partDocument, char value) : base(partDocument) + { + Value = value; + SurfaceList = new List(); + } + + private char _value; + private List _surfaceList; + private PathGeometry _pathGeometry; + private bool _isSpaceCharacter = false; + + + public List SurfaceList { get => _surfaceList; set => _surfaceList = value; } + + public PathGeometry PathGeometry + { + get => _pathGeometry; + set + { + _pathGeometry = value; + FillSurfaceList(); + } + } + + public bool IsSpaceCharacter { get => _isSpaceCharacter; set => _isSpaceCharacter = value; } + public char Value + { + get => _value; + set + { + _value = value; + + if(Value == ' ') + { + Value = '_'; + IsSpaceCharacter = true; + } + } + } + + + private void FillSurfaceList() + { + SurfaceList.Clear(); + + // Compute the XY plane reference + INFITF.Reference planeXYReference = PartDocument.Part.CreateReferenceFromObject(PartDocument.Part.OriginElements.PlaneXY); + + // Separate the pathGeometry in a list of contour PathGeometry + List pathGeometryContourList = new List(); + foreach (PathFigure figure in PathGeometry.Figures) + { + pathGeometryContourList.Add(new PathGeometry(new List() { figure })); + } + + // Sort the list by area + pathGeometryContourList.Sort((x, y) => y.GetArea().CompareTo(x.GetArea())); + + // FILL THE CATIA SURFACE LIST + // Compute to know if the contour is an internal contour + int smallestParentContourIndex = -1; + for (int i = 0; i < pathGeometryContourList.Count; i++) + { + for (int j = 0; j < i; j++) + { + IntersectionDetail intersectionDetail = pathGeometryContourList[i].FillContainsWithDetail(pathGeometryContourList[j]); + + if (intersectionDetail == IntersectionDetail.FullyInside) + { + smallestParentContourIndex = j; + } + } + + // If smallestParentContourIndex is not modified, we have an external contour + if (smallestParentContourIndex == -1) + { + SurfaceList.Add(new CatiaSurface(PartDocument) + { + ExternalContour = new CatiaContour(PartDocument, planeXYReference) + { + PathGeometry = pathGeometryContourList[i] + } + }); + } + else + { + // Get the parent contour. + CatiaContour parentContour = new CatiaContour(PartDocument, planeXYReference) + { + PathGeometry = pathGeometryContourList[smallestParentContourIndex] + }; + + // Try to find the parent contour in the list of surfaces' external contour. + CatiaSurface tempSurface = SurfaceList.Find((surface) => surface.ExternalContour.PathGeometry.ToString() == parentContour.PathGeometry.ToString()); + + // If the parent contour has been found, i-contour is internal. + if (tempSurface != null) + { + tempSurface.InternalContourList.Add(new CatiaContour(PartDocument, planeXYReference) + { + PathGeometry = pathGeometryContourList[i] + }); + } + + // If the parent contour is not found, i-contour is the external contour of a new surface. + else + { + SurfaceList.Add(new CatiaSurface(PartDocument) + { + ExternalContour = new CatiaContour(PartDocument, planeXYReference) + { + PathGeometry = pathGeometryContourList[i] + } + }); + } + } + } + } + + public void DrawCharacter(HybridBody set) + { + for(int i = 0; i < SurfaceList.Count; i++) + { + SurfaceList[i].ExternalContour.DrawContour(set); + SurfaceList[i].ExternalContour.SmoothedShape.set_Name("Ext." + (i+1).ToString()); + + for (int j = 0; j < SurfaceList[i].InternalContourList.Count; j++) + { + SurfaceList[i].InternalContourList[j].DrawContour(set); + SurfaceList[i].InternalContourList[j].SmoothedShape.set_Name("Ext." + (i+1).ToString() + "-Int." + (j+1).ToString()); + } + } + } + + public void AssembleSurfaces() + { + if (SurfaceList.Count > 1) + { + HybridShapeAssemble surfaceAssy = HybridShapeFactory.AddNewJoin(SurfaceList.First().ShapeReference, SurfaceList[1].ShapeReference); + surfaceAssy.SetConnex(false); + + foreach (CatiaSurface surface in SurfaceList) + { + surfaceAssy.AddElement(surface.ShapeReference); + } + + surfaceAssy.Compute(); + + Shape = surfaceAssy; + } + else + { + Shape = SurfaceList.First().Shape; + } + } + + + + // EQUALS OVERRIDE + public override bool Equals(object obj) + { + // Is null? + if (Object.ReferenceEquals(null, obj)) + { + return false; + } + + // Is the same object? + if (Object.ReferenceEquals(this, obj)) + { + return true; + } + + // Is the same type? + if (obj.GetType() != this.GetType()) + { + return false; + } + + CatiaCharacter catiaCharacter = (CatiaCharacter)obj; + return (Value == catiaCharacter.Value && IsSpaceCharacter == catiaCharacter.IsSpaceCharacter); + } + + // GETHASHCODE OVERRIDE + public override int GetHashCode() + { + return base.GetHashCode(); + } + } +} diff --git a/Graphy/Model/CatiaShape/CatiaContour.cs b/Graphy/Model/CatiaShape/CatiaContour.cs index 6e6182f..427df98 100644 --- a/Graphy/Model/CatiaShape/CatiaContour.cs +++ b/Graphy/Model/CatiaShape/CatiaContour.cs @@ -21,8 +21,9 @@ public CatiaContour(PartDocument partDocument, Reference supportReference) : bas private Reference _supportReference; private HybridShape _smoothedShape; private Reference _smoothedShapeReference; + private bool _isSmoothedShapeComputed = false; private double _area; - private System.Windows.Media.PathGeometry _pathGeometry; + private PathGeometry _pathGeometry; // Modify property Shape new public HybridShape Shape @@ -33,7 +34,9 @@ public CatiaContour(PartDocument partDocument, Reference supportReference) : bas _shape = value; ShapeReference = PartDocument.Part.CreateReferenceFromObject(Shape); - if (GetShapeType(HybridShapeFactory, ShapeReference) == ShapeType.Curve || GetShapeType(HybridShapeFactory, ShapeReference) == ShapeType.Circle) + IsSmoothedShapeComputed = false; + + /* if (GetShapeType(HybridShapeFactory, ShapeReference) == ShapeType.Curve || GetShapeType(HybridShapeFactory, ShapeReference) == ShapeType.Circle) { // Check if the contour is closed if (IsContourClosed(PartDocument, HybridShapeFactory, ShapeReference, SupportReference)) @@ -51,7 +54,7 @@ public CatiaContour(PartDocument partDocument, Reference supportReference) : bas else { throw new InvalidShapeException("Shape must be a curve."); - } + }*/ } } @@ -71,13 +74,14 @@ public HybridShape SmoothedShape public Reference SupportReference { get => _supportReference; set => _supportReference = value; } public double Area { get => _area; set => _area = value; } public PathGeometry PathGeometry { get => _pathGeometry; set => _pathGeometry = value; } + public bool IsSmoothedShapeComputed { get => _isSmoothedShapeComputed; set => _isSmoothedShapeComputed = value; } public void ComputeSmoothedShape() { // Smooth the sub curve HybridShapeCurveSmooth smoothSubCurve = HybridShapeFactory.AddNewCurveSmooth(ShapeReference); smoothSubCurve.CorrectionMode = 3; - smoothSubCurve.SetMaximumDeviation(0.001); + smoothSubCurve.SetMaximumDeviation(0.01); smoothSubCurve.TopologySimplificationActivity = true; smoothSubCurve.MaximumDeviationActivity = true; smoothSubCurve.Support = SupportReference; @@ -89,11 +93,13 @@ public void ComputeSmoothedShape() smoothSubCurveWithoutHistoric.Compute(); SmoothedShape = (HybridShape)smoothSubCurveWithoutHistoric; + + IsSmoothedShapeComputed = true; } public void ComputeInnerSurfaceArea() { - if(SmoothedShape == null) + if(!IsSmoothedShapeComputed) { ComputeSmoothedShape(); } @@ -136,6 +142,138 @@ public static bool IsContourClosed(PartDocument partDocument, HybridShapeFactory return true; } + + public void DrawContour(HybridBody set) + { + List lineList = new List(); + + foreach (PathSegment segment in PathGeometry.Figures.First().Segments) + { + if (segment.GetType() == typeof(PolyLineSegment)) + { + List tempPointList = new List(); + foreach (System.Windows.Point point in ((PolyLineSegment)segment).Points) + { + tempPointList.Add(new CatiaPoint(PartDocument, point.X, -point.Y, 0)); + tempPointList.Last().ComputePointShape(); + } + + + for (int i = 0; i < tempPointList.Count() - 1; i++) + { + HybridShape line = HybridShapeFactory.AddNewLinePtPt(tempPointList[i].ShapeReference, tempPointList[i + 1].ShapeReference); + + line.Compute(); + lineList.Add(PartDocument.Part.CreateReferenceFromObject(line)); + } + + HybridShapeLinePtPt lastLine = HybridShapeFactory.AddNewLinePtPt(tempPointList.Last().ShapeReference, tempPointList.First().ShapeReference); + lastLine.Compute(); + lineList.Add(PartDocument.Part.CreateReferenceFromObject(lastLine)); + } + /*else + { + if (segment.GetType() == typeof(PolyBezierSegment)) + { + HybridShapeSpline curve = HybridShapeFactory.AddNewSpline(); + foreach (System.Windows.Point point in ((PolyBezierSegment)segment).Points) + { + pointList.Add(new CatiaPoint(PartDocument, point.X, point.Y, 0)); + pointList.Last().ComputePointShape(); + + pointReferenceList.Add(pointShapeRef); + + curve.AddPoint(pointList.Last().ShapeReference); + curve.Compute(); + } + + tempSet.AppendHybridShape(curve); + } + else + { + if (segment.GetType() == typeof(System.Windows.Media.LineSegment)) + { + Reference startPointShapeRef; + if (pointReferenceList.Count != 0) + { + startPointShapeRef = pointReferenceList.Last(); + } + else + { + System.Windows.Point startPoint = character.PathGeometry.Figures.First().StartPoint; + HybridShape startPointShape = hybridShapeFactory.AddNewPointCoord(startPoint.X, startPoint.Y, 0); + startPointShape.Compute(); + startPointShapeRef = partDocument.Part.CreateReferenceFromObject(startPointShape); + + pointReferenceList.Add(startPointShapeRef); + } + + System.Windows.Point point = ((System.Windows.Media.LineSegment)segment).Point; + HybridShape pointShape = hybridShapeFactory.AddNewPointCoord(point.X, point.Y, 0); + pointShape.Compute(); + Reference pointShapeRef = partDocument.Part.CreateReferenceFromObject(pointShape); + + pointReferenceList.Add(pointShapeRef); + + HybridShape line = hybridShapeFactory.AddNewLinePtPt(startPointShapeRef, pointShapeRef); + lineList.Add(partDocument.Part.CreateReferenceFromObject(line)); + } + } + }*/ + } + + HybridShapeAssemble assemblyShape = HybridShapeFactory.AddNewJoin(lineList.First(), lineList[1]); + for (int i = 2; i < lineList.Count; i++) + { + assemblyShape.AddElement(lineList[i]); + } + + assemblyShape.Compute(); + + Shape = assemblyShape; + ComputeSmoothedShape(); + + set.AppendHybridShape(SmoothedShape); + } + + + public void Scale(double scaleRatio, Reference scaleCenterPointRef) + { + HybridShapeScaling scaledShape; + if (IsSmoothedShapeComputed) + scaledShape = HybridShapeFactory.AddNewHybridScaling(SmoothedShapeReference, scaleCenterPointRef, scaleRatio); + else + scaledShape = HybridShapeFactory.AddNewHybridScaling(ShapeReference, scaleCenterPointRef, scaleRatio); + + scaledShape.Compute(); + Shape = (HybridShape)scaledShape; + } + + public void Move(Reference referenceAxisRef, Reference targetAxisRef) + { + HybridShapeAxisToAxis movedShape; + if (IsSmoothedShapeComputed) + movedShape = HybridShapeFactory.AddNewAxisToAxis(SmoothedShapeReference, referenceAxisRef, targetAxisRef); + else + movedShape = HybridShapeFactory.AddNewAxisToAxis(ShapeReference, referenceAxisRef, targetAxisRef); + + movedShape.Compute(); + Shape = (HybridShape)movedShape; + } + + public void Project(Reference projectionSurfaceRef) + { + HybridShapeProject projectedShape; + if (IsSmoothedShapeComputed) + projectedShape = HybridShapeFactory.AddNewProject(SmoothedShapeReference, projectionSurfaceRef); + else + projectedShape = HybridShapeFactory.AddNewProject(ShapeReference, projectionSurfaceRef); + + projectedShape.Compute(); + Shape = (HybridShape)projectedShape; + } + + public class ContourNotClosed : Exception { public ContourNotClosed() diff --git a/Graphy/Model/CatiaShape/CatiaSurface.cs b/Graphy/Model/CatiaShape/CatiaSurface.cs index 8d6f84a..adcabc2 100644 --- a/Graphy/Model/CatiaShape/CatiaSurface.cs +++ b/Graphy/Model/CatiaShape/CatiaSurface.cs @@ -1,4 +1,5 @@ -using INFITF; +using HybridShapeTypeLib; +using INFITF; using MECMOD; using System; using System.Collections.Generic; @@ -17,23 +18,14 @@ public CatiaSurface(PartDocument partDocument) : base(partDocument) private CatiaContour _externalContour; private List _internalContourList; - private bool _isInternalContourListEmpty; - private double _area; - private Reference _internalContourListAssembledReference; public CatiaContour ExternalContour { get => _externalContour; set => _externalContour = value; } public List InternalContourList { get => _internalContourList; - set - { - _internalContourList = value; - - IsInternalContourListEmpty = InternalContourList.Count > 0 ? false : true; - } + set => _internalContourList = value; } - public bool IsInternalContourListEmpty { get => _isInternalContourListEmpty; set => _isInternalContourListEmpty = value; } new public HybridShape Shape { @@ -43,21 +35,116 @@ public List InternalContourList _shape = value; ShapeReference = PartDocument.Part.CreateReferenceFromObject(Shape); - if (GetShapeType(HybridShapeFactory, ShapeReference) == ShapeType.Surface) + /*if (GetShapeType(HybridShapeFactory, ShapeReference) == ShapeType.Surface) { - // Retrieves the surface area - SPATypeLib.Measurable measurable = SPAWorkbench.GetMeasurable(ShapeReference); - Area = measurable.Area; } else { throw new InvalidShapeException("Shape must be a surface."); + }*/ + } + } + + + + + public void ComputeSurface(Reference projectionSurfaceRef) + { + // Initialize splitOrientation + int splitOrientation = 1; + + // Create exterior split surface + HybridShapeSplit exteriorSplitSurface; + + HybridShapeSplit tempSplit = HybridShapeFactory.AddNewHybridSplit(projectionSurfaceRef, ExternalContour.ShapeReference, splitOrientation); + tempSplit.Compute(); + Reference tempSplitRef = PartDocument.Part.CreateReferenceFromObject(tempSplit); + + + if (!IsSplitOrientationOK(PartDocument, tempSplitRef, ExternalContour.ShapeReference, HybridShapeFactory, projectionSurfaceRef)) + { + exteriorSplitSurface = HybridShapeFactory.AddNewHybridSplit(projectionSurfaceRef, ExternalContour.ShapeReference, -splitOrientation); + } + else + { + exteriorSplitSurface = HybridShapeFactory.AddNewHybridSplit(projectionSurfaceRef, ExternalContour.ShapeReference, splitOrientation); + splitOrientation = -1; + } + + exteriorSplitSurface.Compute(); + + + if (InternalContourList.Count > 0) + { + Reference internalContourListAssembledRef; + // Assemble interior contours + if (InternalContourList.Count > 1) + { + HybridShapeAssemble interiorContourAssy = HybridShapeFactory.AddNewJoin(InternalContourList[0].ShapeReference, InternalContourList[1].ShapeReference); + interiorContourAssy.SetConnex(false); + foreach (CatiaContour intContour in InternalContourList) + { + interiorContourAssy.AddElement(intContour.ShapeReference); + } + + interiorContourAssy.Compute(); + internalContourListAssembledRef = PartDocument.Part.CreateReferenceFromObject(interiorContourAssy); + } + else + { + internalContourListAssembledRef = InternalContourList[0].ShapeReference; } + + + // Cut surface result by interior contours + Reference exteriorSplitSurfaceRef = PartDocument.Part.CreateReferenceFromObject(exteriorSplitSurface); + Shape = HybridShapeFactory.AddNewHybridSplit(exteriorSplitSurfaceRef, internalContourListAssembledRef, -splitOrientation); + Shape.Compute(); + + // Hide + HybridShapeFactory.GSMVisibility(internalContourListAssembledRef, 0); + HybridShapeFactory.GSMVisibility(exteriorSplitSurfaceRef, 0); } + else + { + Shape = exteriorSplitSurface; + } + + } - public double Area { get => _area; set => _area = value; } - public Reference InternalContourListAssembledReference { get => _internalContourListAssembledReference; set => _internalContourListAssembledReference = value; } + + /// + /// Check if the orientation of the split should be inverted by comparing split surface area and the character filled surface area. + /// + /// Part of the working document. + /// Reference of the splited surface. + /// Reference of the contour which split the surface. + /// HybridShapeFactory of the working part. + /// Reference of the surface before split. + /// + private bool IsSplitOrientationOK(PartDocument partDocument, Reference cutSurfaceRef, Reference characterContourRef, HybridShapeFactory factory, Reference supportRef) + { + SPATypeLib.Measurable measurable = SPAWorkbench.GetMeasurable(cutSurfaceRef); + double cutArea = measurable.Area; + + // Create a filled contour + HybridShapeFill filledContour = factory.AddNewFill(); + filledContour.AddBound(characterContourRef); + filledContour.AddSupportAtBound(characterContourRef, supportRef); + filledContour.Compute(); + + Reference filledContourRef = partDocument.Part.CreateReferenceFromObject(filledContour); + + SPATypeLib.Measurable measurable2 = SPAWorkbench.GetMeasurable(filledContourRef); + double charArea = measurable2.Area; + + // If the difference between areas are equal with a marge of 10% => OK + if (Math.Abs(cutArea - charArea) < 0.1 * charArea) + return true; + else + return false; + } } } diff --git a/Graphy/Model/Contour.cs b/Graphy/Model/Contour.cs deleted file mode 100644 index 716c720..0000000 --- a/Graphy/Model/Contour.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using INFITF; -using MECMOD; - -namespace Graphy.Model -{ - public class Contour - { - public enum ContourType - { - Ext, - Int, - ExtInt - } - - public enum ContourStatus - { - FontFileOriginal, - Imported - } - - public Contour() - { - - } - - public Contour(HybridShape shape, ContourStatus status) - { - switch(status) - { - case ContourStatus.FontFileOriginal: - FontFileContourShape = shape; - break; - - case ContourStatus.Imported: - ImportedContourShape = shape; - break; - } - } - - private HybridShape _fontFileContourShape; - private HybridShape _importedContourShape; - private Reference _modifiedContourRef; - private double _area; - private ContourType _type; - private Reference _contourRef; - private double _scaledPerimeter; - private string _parentContourName; - - public HybridShape FontFileContourShape { get => _fontFileContourShape; set => _fontFileContourShape = value; } - public double Area { get => _area; set => _area = value; } - public ContourType Type { get => _type; set => _type = value; } - public Reference ContourRef { get => _contourRef; set => _contourRef = value; } - public Reference ModifiedContourRef { get => _modifiedContourRef; set => _modifiedContourRef = value; } - public double ScaledPerimeter { get => _scaledPerimeter; set => _scaledPerimeter = value; } - public HybridShape ImportedContourShape { get => _importedContourShape; set => _importedContourShape = value; } - public string ParentContourName { get => _parentContourName; set => _parentContourName = value; } - - public string Name(ContourStatus status) - { - switch(status) - { - case ContourStatus.FontFileOriginal: - return FontFileContourShape.get_Name(); - - case ContourStatus.Imported: - return ImportedContourShape.get_Name(); - - default: - return FontFileContourShape.get_Name(); - } - } - - public Contour DeepCopy(PartDocument partDocument, HybridShapeTypeLib.HybridShapeFactory factory) - { - Contour contourCopy = (Contour)this.MemberwiseClone(); - - // Attributs à copier. - contourCopy.FontFileContourShape = (HybridShape)factory.AddNewCurveDatum(ContourRef); - contourCopy.FontFileContourShape.Compute(); - - contourCopy.ContourRef = partDocument.Part.CreateReferenceFromObject(contourCopy.FontFileContourShape); - - return contourCopy; - } - - - public override bool Equals(object obj) - { - // Is null? - if (Object.ReferenceEquals(null, obj)) - { - return false; - } - - // Is the same object? - if (Object.ReferenceEquals(this, obj)) - { - return true; - } - - // Is the same type? - if (obj.GetType() != this.GetType()) - { - return false; - } - - Contour contour = (Contour)obj; - return (FontFileContourShape == contour.FontFileContourShape); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - } -} diff --git a/Graphy/Model/DesignTable.cs b/Graphy/Model/DesignTable.cs deleted file mode 100644 index bdf61dc..0000000 --- a/Graphy/Model/DesignTable.cs +++ /dev/null @@ -1,80 +0,0 @@ -using GalaSoft.MvvmLight; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Excel = Microsoft.Office.Interop.Excel; -using Graphy.Model.CatiaDocument; - -namespace Graphy.Model -{ - public class DesignTable : ObservableObject - { - public DesignTable() - { - ParameterCollection = new ObservableCollection(); - PartCollection = new ObservableCollection(); - } - - private string _fullPath; - private string _partFolderPath; - private ObservableCollection _parameterCollection; - private ObservableCollection _partCollection; - - public string FullPath - { - get => _fullPath; - set - { - Set(() => FullPath, ref _fullPath, value); - } - } - - public string PartFolderPath - { - get => _partFolderPath; - set - { - Set(() => PartFolderPath, ref _partFolderPath, value); - - LoadCatiaFileCollection(PartFolderPath); - } - } - - public ObservableCollection ParameterCollection - { - get => _parameterCollection; - set - { - Set(() => ParameterCollection, ref _parameterCollection, value); - } - } - - public ObservableCollection PartCollection - { - get => _partCollection; - set - { - Set(() => PartCollection, ref _partCollection, value); - } - } - - public void LoadCatiaFileCollection(string folderPath) - { - if(System.IO.Directory.Exists(folderPath)) - { - foreach (string fileFullPath in System.IO.Directory.GetFiles(folderPath)) - { - CatiaFile tempCatiaFile = new CatiaFile(fileFullPath); - - if (tempCatiaFile.GetDocumentFormat() == CatiaDocument.CatiaGenericDocument.CatiaDocumentFormat.CATPart) - { - PartCollection.Add(tempCatiaFile); - } - } - } - } - } -} diff --git a/Graphy/Model/GeneratedFont.cs b/Graphy/Model/GeneratedFont.cs deleted file mode 100644 index 2c6eb5a..0000000 --- a/Graphy/Model/GeneratedFont.cs +++ /dev/null @@ -1,110 +0,0 @@ -using GalaSoft.MvvmLight; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Media; - -namespace Graphy.Model -{ - public class GeneratedFont : Font - { - // CONSTRUCTION - public GeneratedFont() - { - - } - - // ATTRIBUTS - private const string FONT_FILE_PREFIXE = "CATIA_FONT-"; - private const string CURRENT_FILE_VERSION = "2.0"; - - - private string _generatedFileFullPath; - private Version _generatedFileVersion; - private bool _isGeneratedFileOK; - - public string GeneratedFileFullPath - { - get => _generatedFileFullPath; - set - { - if (IsGeneratedFileReadable(value)) - { - Set(() => GeneratedFileFullPath, ref _generatedFileFullPath, value); - - // Get the generated file version - TryGetVersionFromName(GeneratedFileFullPath, out Version tempVersion); - GeneratedFileVersion = tempVersion; - - // Get the font family associated - FontFamily = GetFontFamilyFromName(GeneratedFileFullPath); - - // Say it's OK - IsGeneratedFileOK = true; - } - else - IsGeneratedFileOK = false; - } - } - - public bool IsGeneratedFileOK - { - get => _isGeneratedFileOK; - set - { - Set(() => IsGeneratedFileOK, ref _isGeneratedFileOK, value); - } - } - - public Version GeneratedFileVersion - { - get => _generatedFileVersion; - set - { - Set(() => GeneratedFileVersion, ref _generatedFileVersion, value); - } - } - - - - public static string GetFileNameFormat() - { - return FONT_FILE_PREFIXE + CURRENT_FILE_VERSION + "-"; - } - - // STATIC METHODS - - public static bool TryGetVersionFromName(string fileFullPath, out Version fileVersion) - { - string fontName = Path.GetFileNameWithoutExtension(fileFullPath); - - // CHECK THE NAME FORMAT - if (fontName.Substring(0, FONT_FILE_PREFIXE.Length) == FONT_FILE_PREFIXE) - return Version.TryParse(fontName.Substring(FONT_FILE_PREFIXE.Length, 3), out fileVersion); - else - fileVersion = null; - return false; - } - - public static bool IsGeneratedFileReadable(string fileFullPath) - { - bool versionOk = TryGetVersionFromName(fileFullPath, out Version fileVersion); - - if (versionOk && fileVersion >= new Version(CURRENT_FILE_VERSION)) - return true; - else - return false; - } - - public static FontFamily GetFontFamilyFromName(string fileFullPath) - { - return new FontFamily(Path.GetFileNameWithoutExtension(fileFullPath).Substring((FONT_FILE_PREFIXE + CURRENT_FILE_VERSION + "-").Length)); - } - } -} diff --git a/Graphy/Model/Generator/FontGenerator.cs b/Graphy/Model/Generator/FontGenerator.cs deleted file mode 100644 index 83d9a5e..0000000 --- a/Graphy/Model/Generator/FontGenerator.cs +++ /dev/null @@ -1,546 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Globalization; -using INFITF; -using DRAFTINGITF; -using MECMOD; -using HybridShapeTypeLib; -using Graphy.Model; -using Graphy.Model.CatiaShape; -using Graphy.Model.CatiaDocument; - -namespace Graphy.Model.Generator -{ - public class FontGenerator : IGenerator - { - public event EventHandler ProgressRateChanged; - public event EventHandler StepProgressRateChanged; - - public FontGenerator() - { - - } - - private double _progressRate; - private int _stepProgressRate; - - public double ProgressRate - { - get => _progressRate; - set - { - if (value != ProgressRate) - { - _progressRate = value; - ProgressRateChanged?.Invoke(this, new ProgressRateChangedEventArgs(ProgressRate)); - } - } - } - - public int StepProgressRate - { - get => _stepProgressRate; - set - { - if (value != StepProgressRate) - { - _stepProgressRate = value; - StepProgressRateChanged?.Invoke(this, new ProgressRateChangedEventArgs(StepProgressRate)); - } - } - } - - public void Generate(CatiaEnv catiaEnv, Font font, string savePath) - { - CatiaDrawingDocument catiaDrawingDocument = new CatiaDrawingDocument((CatiaDocument.CatiaGenericDocument)catiaEnv.AddNewDocument(CatiaDocument.CatiaGenericDocument.CatiaDocumentFormat.Drawing)); - DrawingView drawingView = catiaDrawingDocument.DrawingDocument.Sheets.ActiveSheet.Views.ActiveView; - - CatiaPartDocument catiaPartDocument = new CatiaPartDocument((CatiaDocument.CatiaGenericDocument)catiaEnv.AddNewDocument(CatiaDocument.CatiaGenericDocument.CatiaDocumentFormat.CATPart)); - - // Create .dxf set - HybridBody importSet = catiaPartDocument.PartDocument.Part.HybridBodies.Add(); - importSet.set_Name("Set_Import_.dxf"); - - // Create assembly set - HybridBody assemblySet = catiaPartDocument.PartDocument.Part.HybridBodies.Add(); - assemblySet.set_Name("Set_Font_Assembled"); - - // Create disassembled set - HybridBody disassemblySet = catiaPartDocument.PartDocument.Part.HybridBodies.Add(); - disassemblySet.set_Name("Set_Font_Disassembled"); - - catiaPartDocument.PartDocument.Part.Update(); - - HybridShapeFactory factory = (HybridShapeFactory)catiaPartDocument.PartDocument.Part.HybridShapeFactory; - - Selection selectionPart = catiaPartDocument.PartDocument.Selection; - - string tempFullPath = System.IO.Path.GetTempPath() + "CatiaWriterTempChar.dxf"; - - ProgressRate = 0; - - foreach (char c in font.SupportedCharacterList) - { - DrawingText text = drawingView.Texts.Add(c.ToString(), 0, 0); - text.AnchorPosition = CatTextAnchorPosition.catHalfCenter; - text.SetFontName(0, 0, font.Name + " (TrueType)"); // We only work with TrueType font - - if (System.IO.File.Exists(tempFullPath)) - System.IO.File.Delete(tempFullPath); - - - catiaDrawingDocument.DrawingDocument.ExportData(tempFullPath, "dxf"); - drawingView.Texts.Remove(1); - - - if (System.IO.File.Exists(tempFullPath)) - { - CatiaDocument.CatiaGenericDocument tempGenericDocument = catiaEnv.OpenDocument(new CatiaFile(tempFullPath)); - CatiaDrawingDocument tempDrawingDocument = new CatiaDrawingDocument(catiaEnv) - { - DrawingDocument = (DrawingDocument)catiaEnv.Application.ActiveDocument - // Dunno why but the ligne below does not work. - //DrawingDocument = (DrawingDocument)tempGenericDocument.Document - }; - - Selection selection = tempDrawingDocument.DrawingDocument.Selection; - - // Paste the dxf in the font part file - bool isPasteOK = false; - - do - { - try - { - tempDrawingDocument.DrawingDocument.Activate(); - - selection.Clear(); - selection.Add(tempDrawingDocument.DrawingDocument.Sheets.ActiveSheet.Views.ActiveView); - selection.Copy(); - - // Activate the font part file - catiaPartDocument.PartDocument.Activate(); - - selectionPart.Clear(); - selectionPart.Add(importSet); - selectionPart.Paste(); - - isPasteOK = true; - } - catch (Exception) - { - isPasteOK = false; - } - } - while (!isPasteOK); - - - // Close the temp drawing - tempDrawingDocument.DrawingDocument.Close(); - - // Activate the font part file - catiaPartDocument.PartDocument.Activate(); - - // Rename the sketch - Sketch sketch = importSet.HybridSketches.Item(importSet.HybridSketches.Count); - sketch.set_Name(c.ToString()); - - // Create the reference of the sketch - Reference sketchRef = catiaPartDocument.PartDocument.Part.CreateReferenceFromObject(sketch); - - // Create the assembly - HybridShapeAssemble assemblyShape = factory.AddNewJoin(sketchRef, sketchRef); - assemblyShape.SetConnex(false); - assemblyShape.RemoveElement(1); - assemblyShape.set_Name(c.ToString()); - assemblyShape.Compute(); - assemblySet.AppendHybridShape(assemblyShape); - - // *** CREATION UNICODE CATEGORY SET & CHAR SET *** - - HybridBody charSet = null; - - // Check if unicode category set already exists - bool unicodeCategoryExists = false; - foreach (HybridBody unicodeCategoryset in disassemblySet.HybridBodies) - { - if (unicodeCategoryset.get_Name() == CharUnicodeInfo.GetUnicodeCategory(c).ToString()) - { - unicodeCategoryExists = true; - charSet = unicodeCategoryset.HybridBodies.Add(); - break; - } - } - - if (!unicodeCategoryExists) - { - HybridBody unicodeCategorySet = disassemblySet.HybridBodies.Add(); - unicodeCategorySet.set_Name(CharUnicodeInfo.GetUnicodeCategory(c).ToString()); - - charSet = unicodeCategorySet.HybridBodies.Add(); - } - - // *** END *** - - // Get the reference of the assemblyShape - Reference assemblyShapeRef = catiaPartDocument.PartDocument.Part.CreateReferenceFromObject(assemblyShape); - - // Create the main contourList - List catiaContourList = new List(); - List catiaSurfaceList = new List(); - List extContourList = new List(); - Reference planeXYReference = catiaPartDocument.PartDocument.Part.CreateReferenceFromObject(catiaPartDocument.PartDocument.Part.OriginElements.PlaneXY); - - if (factory.AddNewDatums(assemblyShapeRef).Length > 1) - { - // Disassemble the assembly into a list of contours - List disassembledShapeList = new List(); - DisassembleCurve(catiaPartDocument.PartDocument, assemblyShape, disassembledShapeList); - - // Smooth and store the list of contours into main contourList - foreach (HybridShape shape in disassembledShapeList) - { - catiaContourList.Add(new CatiaContour(catiaPartDocument.PartDocument, planeXYReference) - { - Shape = shape - }); - } - - // Compute the smooth shape and the inner surface area. - foreach (CatiaContour catiaContour in catiaContourList) - { - catiaContour.ComputeInnerSurfaceArea(); - } - - // Sort by inner surface area largest to smallest. - catiaContourList.Sort((x, y) => x.Area.CompareTo(y.Area)); - catiaContourList.Reverse(); - - // Append the smoothed shape to the set. - charSet.AppendHybridShape(catiaContourList.First().SmoothedShape); - - catiaSurfaceList.Add(new CatiaSurface(catiaPartDocument.PartDocument) - { - ExternalContour = catiaContourList.First() - }); - - // For each contour in the list of contours - for (int i = 1; i < catiaContourList.Count; i++) - { - // Append in the set the current contour - charSet.AppendHybridShape(catiaContourList[i].SmoothedShape); - - // Get the list of points composing the current contour - List pointList = new List(); - GetCurvePointList(pointList, catiaPartDocument.PartDocument, catiaContourList[i].SmoothedShape); - - // Create a list to compare current contour with all longer contours than current one. - List tempContourList = new List(); - for (int k = 0; k < i; k++) - { - tempContourList.Add(catiaContourList[k]); - } - - int smallestParentContourIndex = -1; - - // For each contour larger than current one, we check to see if the current contour is INT or EXT - for (int j = 0; j < tempContourList.Count; j++) - { - int nbOfPointInside = 0; - - // For each point in the point list - foreach (CatiaPoint point in pointList) - { - point.ComputePointShape(); - - // Compute the number of intersection with the longest contour - int nbOfIntersecX = GetNumberOfIntersection(point, tempContourList[j].ShapeReference, catiaPartDocument.PartDocument, factory, true); - int nbOfIntersecY = GetNumberOfIntersection(point, tempContourList[j].ShapeReference, catiaPartDocument.PartDocument, factory, false); - - // If at least one of the number of intersection is an odd number we are IN the contour - if (nbOfIntersecX % 2 != 0 || nbOfIntersecY % 2 != 0) - { - nbOfPointInside++; - } - } - - // If all the points are inside the contour, it's an interior contour - if (nbOfPointInside == pointList.Count) - smallestParentContourIndex = j; - } - - // >--- FILL THE SURFACE COLLECTION --- - - // If smallestParentContourIndex is not modified, we have an external contour - if (smallestParentContourIndex == -1) - { - catiaSurfaceList.Add(new CatiaSurface(catiaPartDocument.PartDocument) - { - ExternalContour = catiaContourList[i] - }); - } - else - { - // Get the parent contour. - CatiaContour parentContour = tempContourList[smallestParentContourIndex]; - - // Try to find the parent contour in the list of surfaces' external contour. - CatiaSurface tempSurface = catiaSurfaceList.Find((surface) => surface.ExternalContour == parentContour); - - // If the parent contour has been found, i-contour is internal. - if(tempSurface != null) - { - tempSurface.InternalContourList.Add(catiaContourList[i]); - } - // If the parent contour is not found, i-contour is the external contour of a new surface. - else - { - catiaSurfaceList.Add(new CatiaSurface(catiaPartDocument.PartDocument) - { - ExternalContour = catiaContourList[i] - }); - } - } - - // >--- END --- - } - - // >--- GIVE NAME TO CONTOURS --- - int extCount = 0; - foreach (CatiaSurface surface in catiaSurfaceList) - { - surface.ExternalContour.SmoothedShape.set_Name("Ext." + (extCount + 1).ToString()); - - for (int i = 0; i < surface.InternalContourList.Count; i++) - { - surface.InternalContourList[i].SmoothedShape.set_Name(surface.ExternalContour.SmoothedShape.get_Name() + "-Int." + (i + 1).ToString()); - } - - extCount++; - } - // >--- END --- - - - - // >--- STORE ALL EXTERNAL CONTOURS FOR HEIGHT AND WIDTH COMPUTATION --- - foreach (CatiaSurface surface in catiaSurfaceList) - { - extContourList.Add(surface.ExternalContour); - } - // >--- END --- - - } - else - { - HybridShapeCurveExplicit onlyExtContour = factory.AddNewCurveDatum(assemblyShapeRef); - onlyExtContour.Compute(); - - CatiaContour catiaContour = new CatiaContour(catiaPartDocument.PartDocument, planeXYReference) - { - Shape = onlyExtContour - }; - - catiaContour.ComputeSmoothedShape(); - catiaContour.SmoothedShape.set_Name("Ext.1"); - charSet.AppendHybridShape(catiaContour.SmoothedShape); - - extContourList.Add(catiaContour); - } - - charSet.set_Name(c.ToString() + " " + GetWidthAndHeight(catiaPartDocument.PartDocument, extContourList, planeXYReference)); - - // >--- DELETE IMPORTED SKETCH AND ASSEMBLY SHAPE --- - Selection partDocumentSelection = catiaPartDocument.PartDocument.Selection; - partDocumentSelection.Clear(); - partDocumentSelection.Add(assemblyShape); - partDocumentSelection.Add(sketch); - - partDocumentSelection.Delete(); - // >--- END --- - } - - ProgressRate += 1 / (double)font.SupportedCharacterList.Length; - } - - catiaDrawingDocument.DrawingDocument.Close(); - - catiaPartDocument.PartDocument.SaveAs(savePath + GeneratedFont.GetFileNameFormat() + font.Name); - } - - private string GetWidthAndHeight(PartDocument partDocument, List extContourList, Reference supportReference) - { - List pointList = new List(); - - HybridBody tempSet = partDocument.Part.HybridBodies.Add(); - - foreach (CatiaContour contour in extContourList) - { - HybridShape tempShape = CatiaShape.CatiaGenericShape.CopyShape(contour.ShapeReference, (HybridShapeFactory)partDocument.Part.HybridShapeFactory); - tempSet.AppendHybridShape(tempShape); - GetCurvePointList(pointList, partDocument, tempShape); - } - - HybridShapeFactory factory = (HybridShapeFactory)partDocument.Part.HybridShapeFactory; - Reference tempSetRef = partDocument.Part.CreateReferenceFromObject(tempSet); - factory.DeleteObjectForDatum(tempSetRef); - - return "W" + ((GetXWidth(pointList) * 1000).ToString()).Substring(0, 4) + " H" + ((GetYWidth(pointList) * 1000).ToString()).Substring(0, 4); - } - - /// - /// Get the maximum width on the X axis from a point list. - /// - /// - /// - private double GetXWidth(List pointList) - { - if (pointList.Count != 0) - { - double minXValue = 0; - double maxXvalue = 0; - - foreach (CatiaPoint point in pointList) - { - if (point.X > maxXvalue) - maxXvalue = point.X; - - if (point.X < minXValue) - minXValue = point.X; - } - - return maxXvalue - minXValue; - } - else - return 0; - } - - - /// - /// Get the maximum width on the Y axis from a point list. - /// - /// - /// - private static double GetYWidth(List pointList) - { - double minYValue = 0; - double maxYValue = 0; - - foreach (CatiaPoint point in pointList) - { - if (point.Y > maxYValue) - maxYValue = point.Y; - - if (point.Y < minYValue) - minYValue = point.Y; - } - - return maxYValue - minYValue; - } - - - private static int GetNumberOfIntersection(CatiaPoint point, Reference comparedContourRef, PartDocument partDocument, HybridShapeFactory factory, bool direction) - { - OriginElements originElement = partDocument.Part.OriginElements; - Reference normalPlaneRef; - - // Direction = true => direction is X axis - // Direction = false => direction is Y axis - if (direction) - normalPlaneRef = partDocument.Part.CreateReferenceFromObject(originElement.PlaneYZ); - else - normalPlaneRef = partDocument.Part.CreateReferenceFromObject(originElement.PlaneZX); - - HybridShapeDirection directionIntersectionLine = factory.AddNewDirection(normalPlaneRef); - directionIntersectionLine.Compute(); - - HybridShapeLinePtDir intersectionLine = factory.AddNewLinePtDir(point.ShapeReference, directionIntersectionLine, 0, 10000, false); - intersectionLine.Compute(); - Reference intersectionLineRef = partDocument.Part.CreateReferenceFromObject(intersectionLine); - - - HybridShapeIntersection intersection = factory.AddNewIntersection(intersectionLineRef, comparedContourRef); - intersection.Compute(); - Reference intersectionRef = partDocument.Part.CreateReferenceFromObject(intersection); - - if (MarkingGenerator.GetShapeType(partDocument.Part, intersectionRef) != MarkingGenerator.ShapeType.Point) - { - return 0; - } - else - { - try - { - return factory.AddNewDatums(intersectionRef).Length; - } - catch (Exception) - { - return 0; - } - } - } - - - /// - /// Disassemble a curve into subcurves. - /// - /// PartDocument of the curve to disassemble. - /// Curve to disassemble. - /// List where are stored disassembled sub curves. - public void DisassembleCurve(PartDocument partDocument, HybridShape curveShape, List disassembledSubCurveList) - { - HybridShapeFactory factory = (HybridShapeFactory)partDocument.Part.HybridShapeFactory; - - Selection selectedCurve = partDocument.Selection; - selectedCurve.Clear(); - selectedCurve.Add(curveShape); - selectedCurve.Search("Topology.CGMEdge,sel"); - - for (int i = 1; i <= selectedCurve.Count; i++) - { - SelectedElement subCurveSelectedElement = selectedCurve.Item(i); - - string subCurveName = subCurveSelectedElement.Reference.get_Name().Substring(21, subCurveSelectedElement.Reference.get_Name().Length - 22); - - Reference subCurveRef = partDocument.Part.CreateReferenceFromBRepName(subCurveName, (AnyObject)subCurveSelectedElement.Value); - HybridShapeCurveExplicit subCurve = factory.AddNewCurveDatum(subCurveRef); - subCurve.Compute(); - - disassembledSubCurveList.Add(subCurve); - } - } - - - /// - /// For each point in the curve, get coordinates and store them in pointList. - /// - /// Store the point of the list. - /// PartDocument of the curve. - /// Curve to extract the point list. - public static void GetCurvePointList(List pointList, PartDocument partDocument, HybridShape shape) - { - Selection selectedCurve = partDocument.Selection; - selectedCurve.Clear(); - selectedCurve.Add(shape); - selectedCurve.Search("Topology.CGMEdge,sel"); - - SPATypeLib.SPAWorkbench spaWorkbench = (SPATypeLib.SPAWorkbench)partDocument.GetWorkbench("SPAWorkbench"); - - for (int i = 1; i < selectedCurve.Count + 1; i++) - { - SelectedElement subCurve = selectedCurve.Item(i); - - SPATypeLib.Measurable measurable = spaWorkbench.GetMeasurable(subCurve.Reference); - - object[] curvePointCoordinateArray = new object[9]; - measurable.GetPointsOnCurve(curvePointCoordinateArray); - - CatiaPoint firstPoint = new CatiaPoint(partDocument, (double)curvePointCoordinateArray.GetValue(0), (double)curvePointCoordinateArray.GetValue(1), (double)curvePointCoordinateArray.GetValue(2)); - - pointList.Add(firstPoint); - } - } - } -} diff --git a/Graphy/Model/Generator/MarkingGenerator.cs b/Graphy/Model/Generator/MarkingGenerator.cs index bf81b3a..90e9526 100644 --- a/Graphy/Model/Generator/MarkingGenerator.cs +++ b/Graphy/Model/Generator/MarkingGenerator.cs @@ -53,19 +53,6 @@ public int StepProgressRate } } - public enum ShapeType - { - Unknown = 0, - Point = 1, - Curve = 2, - Line = 3, - Circle = 4, - Surface = 5, - Plane = 6, - Solid = 7, - AxisSystem = 12 - }; - public void RunForCatalogPart(CatiaEnv catiaEnv, MarkingData markingData, string designTableFullPath, List partList) { @@ -123,474 +110,334 @@ public void Run(CatiaEnv catiaEnv, PartDocument partDocument, MarkingData markin { ProgressRate = 0; - List characterList = new List(); - - CatiaPartDocument fontPartDocument = new CatiaPartDocument(catiaEnv.OpenDocument(new CatiaFile(markingData.Font.GeneratedFileFullPath))); - - if (CanDrawAllCharacters(fontPartDocument.PartDocument, markingData, characterList)) - { - // Creates the marking set - HybridBody markingSet = partDocument.Part.HybridBodies.Add(); - markingSet.set_Name("MARKING SET - " + markingData.Name); - - // Creates the origin axis system to the marking set - partDocument.Part.InWorkObject = markingSet; - AxisSystem originAxisSystem = partDocument.Part.AxisSystems.Add(); - originAxisSystem.set_Name("Origin axis system"); - - // Creates the point set - HybridBody pointSet = markingSet.HybridBodies.Add(); - pointSet.set_Name("Points"); - - // Creates the local axis system set - HybridBody localAxisSet = markingSet.HybridBodies.Add(); - localAxisSet.set_Name("Local Axis systems"); - - // Creates the working set - HybridBody writingSet = markingSet.HybridBodies.Add(); - writingSet.set_Name("Characters construction"); - // Creates the input data references - Reference originAxisSystemRef = partDocument.Part.CreateReferenceFromObject(originAxisSystem); + // ***** PREPARE MARKING ***** // - AnyObject trackingCurve = partDocument.Part.FindObjectByName(markingData.TrackingCurveName); - Reference trackingCurveRef = partDocument.Part.CreateReferenceFromObject(trackingCurve); + // Creates the marking set + HybridBody markingSet = partDocument.Part.HybridBodies.Add(); + markingSet.set_Name("MARKING SET - " + markingData.Name); - AnyObject projectionSurface = partDocument.Part.FindObjectByName(markingData.ProjectionSurfaceName); - Reference projectionSurfaceRef = partDocument.Part.CreateReferenceFromObject(projectionSurface); - - AnyObject startPoint = partDocument.Part.FindObjectByName(markingData.StartPointName); - Reference startPointRef = partDocument.Part.CreateReferenceFromObject(startPoint); - - AxisSystem startAxisSystem = (AxisSystem)partDocument.Part.FindObjectByName(markingData.AxisSystemName); - Reference startAxisSystemRef = partDocument.Part.CreateReferenceFromObject(startAxisSystem); - - // Factories - HybridShapeFactory hybridShapeFactory = (HybridShapeFactory)partDocument.Part.HybridShapeFactory; - ShapeFactory shapeFactory = (ShapeFactory)partDocument.Part.ShapeFactory; - - // Creates the origin point - HybridShapePointCoord originPoint = hybridShapeFactory.AddNewPointCoord(0, 0, 0); - Reference originPointRef = partDocument.Part.CreateReferenceFromObject(originPoint); - - // Creates the marking body - Body markingBody = partDocument.Part.Bodies.Add(); - markingBody.set_Name("MARKING BODY - " + markingData.Name); - - // Add or remove marking body from main body - partDocument.Part.InWorkObject = partDocument.Part.MainBody; - if (markingData.ExtrusionHeight.Value > 0) - { - Add addBody = shapeFactory.AddNewAdd(markingBody); - } - else - { - Remove removeBody = shapeFactory.AddNewRemove(markingBody); - } + // Creates the origin axis system to the marking set + partDocument.Part.InWorkObject = markingSet; + AxisSystem originAxisSystem = partDocument.Part.AxisSystems.Add(); + originAxisSystem.set_Name("Origin axis system"); - // Updates - partDocument.Part.Update(); + // Creates the point set + HybridBody pointSet = markingSet.HybridBodies.Add(); + pointSet.set_Name("Points"); + // Creates the local axis system set + HybridBody localAxisSet = markingSet.HybridBodies.Add(); + localAxisSet.set_Name("Local Axis systems"); - // ***** CREATE A REFERENTIEL FOR COMPARISON ***** // + // Creates the working set + HybridBody writingSet = markingSet.HybridBodies.Add(); + writingSet.set_Name("Characters construction"); - // Check if surface natural normal passing by the start point is in the same direction as user Z axis - object[] ZAxisDirection = new object[3]; - startAxisSystem.GetZAxis(ZAxisDirection); + // Creates the input data references + Reference originAxisSystemRef = partDocument.Part.CreateReferenceFromObject(originAxisSystem); - object[] naturalNormalLineDirection = new object[3]; - HybridShapeLineNormal naturalNormalLine = hybridShapeFactory.AddNewLineNormal(projectionSurfaceRef, startPointRef, 0, 10, false); - naturalNormalLine.Compute(); - pointSet.AppendHybridShape(naturalNormalLine); - naturalNormalLine.GetDirection(naturalNormalLineDirection); + AnyObject trackingCurve = partDocument.Part.FindObjectByName(markingData.TrackingCurveName); + Reference trackingCurveRef = partDocument.Part.CreateReferenceFromObject(trackingCurve); - bool isZSameDirection = false; - if (Math.Abs((double)ZAxisDirection[0] - (double)naturalNormalLineDirection[0]) < 0.1 - && Math.Abs((double)ZAxisDirection[1] - (double)naturalNormalLineDirection[1]) < 0.1 - && Math.Abs((double)ZAxisDirection[2] - (double)naturalNormalLineDirection[2]) < 0.1) - { - isZSameDirection = true; - } + AnyObject projectionSurface = partDocument.Part.FindObjectByName(markingData.ProjectionSurfaceName); + Reference projectionSurfaceRef = partDocument.Part.CreateReferenceFromObject(projectionSurface); - // Check if natural angle line passing by the start point is in the same direction as user Y axis - object[] YAxisDirection = new object[3]; - startAxisSystem.GetYAxis(YAxisDirection); + AnyObject startPoint = partDocument.Part.FindObjectByName(markingData.StartPointName); + Reference startPointRef = partDocument.Part.CreateReferenceFromObject(startPoint); - object[] naturalAngleLineDirection = new object[3]; - HybridShapePlaneTangent tangentPlane = hybridShapeFactory.AddNewPlaneTangent(projectionSurfaceRef, startPointRef); - tangentPlane.Compute(); - Reference tangentPlaneRef = partDocument.Part.CreateReferenceFromObject(tangentPlane); + AxisSystem startAxisSystem = (AxisSystem)partDocument.Part.FindObjectByName(markingData.AxisSystemName); + Reference startAxisSystemRef = partDocument.Part.CreateReferenceFromObject(startAxisSystem); - HybridShapeLineAngle naturalAngleLine = hybridShapeFactory.AddNewLineAngle(trackingCurveRef, tangentPlaneRef, startPointRef, false, 0, 10, 90, false); - naturalAngleLine.Compute(); - naturalAngleLine.GetDirection(naturalAngleLineDirection); + // Factories + HybridShapeFactory hybridShapeFactory = (HybridShapeFactory)partDocument.Part.HybridShapeFactory; + ShapeFactory shapeFactory = (ShapeFactory)partDocument.Part.ShapeFactory; - bool isYSameDirection = false; - if (Math.Abs((double)YAxisDirection[0] - (double)naturalAngleLineDirection[0]) < 0.1 - && Math.Abs((double)YAxisDirection[1] - (double)naturalAngleLineDirection[1]) < 0.1 - && Math.Abs((double)YAxisDirection[2] - (double)naturalAngleLineDirection[2]) < 0.1) - { - isYSameDirection = true; - } + // Creates the origin point + HybridShapePointCoord originPoint = hybridShapeFactory.AddNewPointCoord(0, 0, 0); + Reference originPointRef = partDocument.Part.CreateReferenceFromObject(originPoint); - // Check if natural tangent line passing by the start point is in the same direction as user X axis - object[] XAxisDirection = new object[3]; - startAxisSystem.GetXAxis(XAxisDirection); + // Creates the marking body + Body markingBody = partDocument.Part.Bodies.Add(); + markingBody.set_Name("MARKING BODY - " + markingData.Name); - object[] naturalTangentLineCoordinate = new object[3]; - HybridShapeLineTangency naturalTangentLine = hybridShapeFactory.AddNewLineTangency(trackingCurveRef, startPointRef, 0, 10, false); - naturalTangentLine.Compute(); - naturalTangentLine.GetDirection(naturalTangentLineCoordinate); + // Add or remove marking body from main body + partDocument.Part.InWorkObject = partDocument.Part.MainBody; + if (markingData.ExtrusionHeight.Value > 0) + { + Add addBody = shapeFactory.AddNewAdd(markingBody); + } + else + { + Remove removeBody = shapeFactory.AddNewRemove(markingBody); + } - bool isXSameDirection = false; - if (Math.Abs((double)XAxisDirection[0] - (double)naturalTangentLineCoordinate[0]) < 0.1 - && Math.Abs((double)XAxisDirection[1] - (double)naturalTangentLineCoordinate[1]) < 0.1 - && Math.Abs((double)XAxisDirection[2] - (double)naturalTangentLineCoordinate[2]) < 0.1) - { - isXSameDirection = true; - } + // Updates + partDocument.Part.Update(); - // ***** END OF REFERENTIEL ***** // + // ***** END OF PREPARATIONS ***** // - int i = 1; - double currentLength = 0; - ProgressRate = 0; - foreach (char c in markingData.Text.Value) - { - originAxisSystem.IsCurrent = true; - if (c == ' ') - { - WriteSpace(characterList, markingData, ref currentLength, partDocument, pointSet, trackingCurveRef, startPointRef, hybridShapeFactory, isXSameDirection); - } - else - { - WriteCharacter(i, c, characterList, markingData, ref currentLength, - fontPartDocument.PartDocument, partDocument, writingSet, localAxisSet, pointSet, markingBody, - originAxisSystemRef, trackingCurveRef, projectionSurfaceRef, startPointRef, startAxisSystemRef, - hybridShapeFactory, shapeFactory, originPointRef, isXSameDirection, isYSameDirection, isZSameDirection); + // ***** CREATE A REFERENTIEL FOR COMPARISON ***** // - i++; - } + // Check if surface natural normal passing by the start point is in the same direction as user Z axis + object[] ZAxisDirection = new object[3]; + startAxisSystem.GetZAxis(ZAxisDirection); - partDocument.Part.Update(); - ProgressRate += 1 / (double)markingData.Text.Value.Length; - } + object[] naturalNormalLineDirection = new object[3]; + HybridShapeLineNormal naturalNormalLine = hybridShapeFactory.AddNewLineNormal(projectionSurfaceRef, startPointRef, 0, 10, false); + naturalNormalLine.Compute(); + pointSet.AppendHybridShape(naturalNormalLine); + naturalNormalLine.GetDirection(naturalNormalLineDirection); - partDocument.Part.Update(); - } - else + bool isZSameDirection = false; + if (Math.Abs((double)ZAxisDirection[0] - (double)naturalNormalLineDirection[0]) < 0.1 + && Math.Abs((double)ZAxisDirection[1] - (double)naturalNormalLineDirection[1]) < 0.1 + && Math.Abs((double)ZAxisDirection[2] - (double)naturalNormalLineDirection[2]) < 0.1) { - throw new Exception("Tous les caractères n'ont pas été trouvés."); + isZSameDirection = true; } - fontPartDocument.PartDocument.Close(); - } + // Check if natural angle line passing by the start point is in the same direction as user Y axis + object[] YAxisDirection = new object[3]; + startAxisSystem.GetYAxis(YAxisDirection); - private void WriteSpace(List catiaCharList, MarkingData markingData, ref double currentLength, PartDocument markingPartDocument, HybridBody pointSet, - Reference trackingCurveRef, Reference startPointRef, HybridShapeFactory hybridShapeFactory, bool isXSameDirection) - { - foreach (CatiaChar catiaChar in catiaCharList) - { - if (catiaChar.Value == '_') - { - // Local point on the tracking curve positionning the current character - currentLength += catiaChar.ScaleWidth / 2; - HybridShapePointOnCurve localPoint = hybridShapeFactory.AddNewPointOnCurveWithReferenceFromDistance(trackingCurveRef, startPointRef, currentLength, !isXSameDirection); - Reference localPointRef = markingPartDocument.Part.CreateReferenceFromObject(localPoint); - pointSet.AppendHybridShape(localPoint); - - currentLength += catiaChar.ScaleWidth / 2; - } - } - } + object[] naturalAngleLineDirection = new object[3]; + HybridShapePlaneTangent tangentPlane = hybridShapeFactory.AddNewPlaneTangent(projectionSurfaceRef, startPointRef); + tangentPlane.Compute(); + Reference tangentPlaneRef = partDocument.Part.CreateReferenceFromObject(tangentPlane); + HybridShapeLineAngle naturalAngleLine = hybridShapeFactory.AddNewLineAngle(trackingCurveRef, tangentPlaneRef, startPointRef, false, 0, 10, 90, false); + naturalAngleLine.Compute(); + naturalAngleLine.GetDirection(naturalAngleLineDirection); - private void WriteCharacter(int index, char c, List catiaCharList, MarkingData markingData, ref double currentLength, - PartDocument fontPartDocument, PartDocument markingPartDocument, HybridBody writingSet, HybridBody localAxisSet, HybridBody pointSet, Body markingBody, - Reference originAxisSystemRef, Reference trackingCurveRef, Reference projectionSurfaceRef, Reference startPointRef, Reference startAxisSystemRef, - HybridShapeFactory hybridShapeFactory, ShapeFactory shapeFactory, Reference originPointRef, bool isXSameDirection, bool isYSameDirection, bool isZSameDirection) - { - foreach (CatiaChar catiaChar in catiaCharList) + bool isYSameDirection = false; + if (Math.Abs((double)YAxisDirection[0] - (double)naturalAngleLineDirection[0]) < 0.1 + && Math.Abs((double)YAxisDirection[1] - (double)naturalAngleLineDirection[1]) < 0.1 + && Math.Abs((double)YAxisDirection[2] - (double)naturalAngleLineDirection[2]) < 0.1) { - if (c == catiaChar.Value) - { - // Create char set - HybridBody charSet = writingSet.HybridBodies.Add(); - charSet.set_Name(c.ToString() + "." + index); - - // Compute base positionning values - double charWidth = markingData.Font.GetWidth(c); - double charLeftSideBearing = 0; - double charRightSideBearing = 0; - - if (charWidth != 0) - { - charLeftSideBearing = Math.Abs(markingData.Font.GetLeftSideBearing(c)) * catiaChar.ScaleWidth / charWidth; - - charRightSideBearing = Math.Abs(markingData.Font.GetLeftSideBearing(c)) * catiaChar.ScaleWidth / charWidth; - } - - - // ***** CREATE LINES FOR LOCAL AXIS SYSTEMS ***** // + isYSameDirection = true; + } - // Local point on the tracking curve positionning the current character - currentLength += catiaChar.ScaleWidth / 2 + charLeftSideBearing; - HybridShapePointOnCurve localPoint = hybridShapeFactory.AddNewPointOnCurveWithReferenceFromDistance(trackingCurveRef, startPointRef, currentLength, !isXSameDirection); - Reference localPointRef = markingPartDocument.Part.CreateReferenceFromObject(localPoint); - pointSet.AppendHybridShape(localPoint); + // Check if natural tangent line passing by the start point is in the same direction as user X axis + object[] XAxisDirection = new object[3]; + startAxisSystem.GetXAxis(XAxisDirection); + object[] naturalTangentLineCoordinate = new object[3]; + HybridShapeLineTangency naturalTangentLine = hybridShapeFactory.AddNewLineTangency(trackingCurveRef, startPointRef, 0, 10, false); + naturalTangentLine.Compute(); + naturalTangentLine.GetDirection(naturalTangentLineCoordinate); - // Normal of the surface passing by the local point - HybridShapeLineNormal localLineNormal = hybridShapeFactory.AddNewLineNormal(projectionSurfaceRef, localPointRef, 0, 10, false); - localLineNormal.Compute(); - Reference localLineNormalRef = markingPartDocument.Part.CreateReferenceFromObject(localLineNormal); + bool isXSameDirection = false; + if (Math.Abs((double)XAxisDirection[0] - (double)naturalTangentLineCoordinate[0]) < 0.1 + && Math.Abs((double)XAxisDirection[1] - (double)naturalTangentLineCoordinate[1]) < 0.1 + && Math.Abs((double)XAxisDirection[2] - (double)naturalTangentLineCoordinate[2]) < 0.1) + { + isXSameDirection = true; + } + // ***** END OF REFERENTIEL ***** // - // Tangent of the tracking curve passing by the local point - HybridShapeLineTangency localLineTangent = hybridShapeFactory.AddNewLineTangency(trackingCurveRef, localPointRef, 0, 10, false); - localLineTangent.Compute(); - Reference localLineTangentRef = markingPartDocument.Part.CreateReferenceFromObject(localLineTangent); - // 90° angle line considering tracking curve passing by the local point - HybridShapePlaneTangent localPlaneTangent = hybridShapeFactory.AddNewPlaneTangent(projectionSurfaceRef, localPointRef); - localPlaneTangent.Compute(); - Reference localPlaneTangentRef = markingPartDocument.Part.CreateReferenceFromObject(localPlaneTangent); + // ***** WRITE CHARACTERS ***** // - HybridShapeLineAngle localLineAngle = hybridShapeFactory.AddNewLineAngle(trackingCurveRef, localPlaneTangentRef, localPointRef, false, 0, 10, 90, false); - localLineAngle.Compute(); + List characterList = new List(); // Inutile pour le moment à voir pour optimiser le code et ne pas redessiner chaque lettre à chaque fois ! + int characterIndex = 0; + double currentLength2 = 0; - Reference localLineAngleRef = markingPartDocument.Part.CreateReferenceFromObject(localLineAngle); + // Compute the scale ratio to obtain the character height with a fixed character reference + double scaleRatio = markingData.CharacterHeight.Value / markingData.Font.GetCharacterGeometry('M').Bounds.Height; - // ***** END OF LOCAL LINES ***** // + // Create a catia character list from input text and character height + foreach (char character in markingData.Text.Value) + { + // Create the character set + HybridBody characterSet = writingSet.HybridBodies.Add(); + characterSet.set_Name(character.ToString() + "." + characterIndex); + // Get the associatedCatiaCharacter + CatiaCharacter associatedCatiaCharacter = GetCatiaCharacter(partDocument, markingData, characterSet, character); - // ***** LOCAL AXIS SYSTEM ***** // + // Create the local point + Reference localPointRef = ComputeLocalPoint(associatedCatiaCharacter, markingData, trackingCurveRef, startPointRef, pointSet, isXSameDirection, ref currentLength2, scaleRatio); - markingPartDocument.Part.InWorkObject = localAxisSet; - AxisSystem localAxisSystem = markingPartDocument.Part.AxisSystems.Add(); + if (!associatedCatiaCharacter.IsSpaceCharacter) + { + // Create the local axis system + AxisSystem localAxisSystem = ComputeLocalAxisSystem(partDocument, markingData, localAxisSet, localPointRef, projectionSurfaceRef, trackingCurveRef, + isXSameDirection, isYSameDirection, isZSameDirection); - // Local axis system : point - localAxisSystem.OriginType = CATAxisSystemOriginType.catAxisSystemOriginByPoint; - localAxisSystem.OriginPoint = localPointRef; + Reference localAxisSystemRef = partDocument.Part.CreateReferenceFromObject(localAxisSystem); - // Local axis system : X direction - if (isXSameDirection) - localAxisSystem.XAxisType = CATAxisSystemAxisType.catAxisSystemAxisSameDirection; - else - localAxisSystem.XAxisType = CATAxisSystemAxisType.catAxisSystemAxisOppositeDirection; + // For each surface composing the CatiaCharacter + foreach (CatiaSurface surface in associatedCatiaCharacter.SurfaceList) + { + // Scale external contour + surface.ExternalContour.Scale(scaleRatio, originPointRef); - localAxisSystem.XAxisDirection = localLineTangentRef; + // Move external contour + surface.ExternalContour.Move(originAxisSystemRef, localAxisSystemRef); - // Local axis system : Y direction - if (isYSameDirection) - localAxisSystem.YAxisType = CATAxisSystemAxisType.catAxisSystemAxisSameDirection; - else - localAxisSystem.YAxisType = CATAxisSystemAxisType.catAxisSystemAxisOppositeDirection; + // Project external contour + surface.ExternalContour.Project(projectionSurfaceRef); - localAxisSystem.YAxisDirection = localLineAngleRef; + foreach (CatiaContour contour in surface.InternalContourList) + { + // Scale external contour + contour.Scale(scaleRatio, originPointRef); - // Local axis system : Z direction - if (isZSameDirection) - localAxisSystem.ZAxisType = CATAxisSystemAxisType.catAxisSystemAxisSameDirection; - else - localAxisSystem.ZAxisType = CATAxisSystemAxisType.catAxisSystemAxisOppositeDirection; + // Move external contour + contour.Move(originAxisSystemRef, localAxisSystemRef); - localAxisSystem.ZAxisDirection = localLineNormalRef; + // Project external contour + contour.Project(projectionSurfaceRef); + } - // Local axis system : Update - markingPartDocument.Part.UpdateObject(localAxisSystem); + surface.ComputeSurface(projectionSurfaceRef); - // Local axis system : Reference - Reference localAxisSystemRef = markingPartDocument.Part.CreateReferenceFromObject(localAxisSystem); + characterSet.AppendHybridShape(surface.Shape); + } - // ***** END LOCAL AXIS SYSTEM ***** // + associatedCatiaCharacter.AssembleSurfaces(); + // ADD THICKNESS TO THE ASSEMBLED SURFACE + int thickSurfaceDirection = GetThickSurfaceDirection(localAxisSystem, associatedCatiaCharacter.ShapeReference, localPointRef, hybridShapeFactory); + partDocument.Part.InWorkObject = markingBody; + ThickSurface characterThickSurface = shapeFactory.AddNewThickSurface(associatedCatiaCharacter.ShapeReference, thickSurfaceDirection, markingData.ExtrusionHeight.Value, 0); + currentLength2 += scaleRatio * associatedCatiaCharacter.PathGeometry.Bounds.Width * (0.5d + markingData.Font.GetRightSideBearing(character) / markingData.Font.GetWidth(character)); - // ***** CREATE THE CHARACTER ***** // + } + else + currentLength2 += scaleRatio * associatedCatiaCharacter.PathGeometry.Bounds.Width * 0.5d; - // Paste character contours from font file - //CopyPasteShape(catiaChar.GetAllContours(), fontPartDocument, charSet, markingPartDocument); + ProgressRate += 1d / (double)markingData.Text.Value.Count(); - // ******************************** NEWWW !!! TEST - CopyPasteShape(catiaChar.OriginalContourShapeList, fontPartDocument, charSet, markingPartDocument); + } - catiaChar.LoadSurfaceListFromSet(charSet, Contour.ContourStatus.Imported); + // ***** END ***** // - foreach (Surface surface in catiaChar.SurfaceList) - { - // >------- EXTERIOR CONTOUR ----------- + } - // Get Scale / Positionned / Projected EXT contour reference - surface.ExtContour.ModifiedContourRef = ContourScalePositionProjection(surface.ExtContour.ImportedContourShape, catiaChar.ScaleRatio, - markingPartDocument, hybridShapeFactory, originPointRef, originAxisSystemRef, localAxisSystemRef, projectionSurfaceRef, charSet); + private CatiaCharacter GetCatiaCharacter(PartDocument partDocument, MarkingData markingData, HybridBody characterSet, char character) + { + CatiaCharacter CatiaCharacter = new CatiaCharacter(partDocument, character); - surface.ExtContour.ScaledPerimeter = GetCurveLenght(markingPartDocument, surface.ExtContour.ModifiedContourRef); + /*if (!characterList.Contains(tempCatiaCharacter)) + { + characterList.Add(tempCatiaCharacter);*/ + CatiaCharacter.PathGeometry = markingData.Font.GetCharacterGeometry(CatiaCharacter.Value); - // Initialize splitOrientation - int splitOrientation = 1; + if (!CatiaCharacter.IsSpaceCharacter) + CatiaCharacter.DrawCharacter(characterSet); - // Create exterior split surface - HybridShapeSplit exteriorSplitSurface; + return CatiaCharacter; + /*} + else + { + return characterList.Find((catiaCharacter) => catiaCharacter.Value == character); + }*/ + } - HybridShapeSplit tempSplit = hybridShapeFactory.AddNewHybridSplit(projectionSurfaceRef, surface.ExtContour.ModifiedContourRef, splitOrientation); - tempSplit.Compute(); - Reference tempSplitRef = markingPartDocument.Part.CreateReferenceFromObject(tempSplit); + private Reference ComputeLocalPoint(CatiaCharacter character, MarkingData markingData, Reference trackingCurveRef, Reference startPointRef, HybridBody pointSet, + bool isXSameDirection, ref double currentLength, double scaleRatio) + { + // ***** CREATE LINES FOR LOCAL AXIS SYSTEMS ***** // + // Local point on the tracking curve positionning the current character + if (currentLength != 0) + { + if (character.IsSpaceCharacter) + currentLength += scaleRatio * character.PathGeometry.Bounds.Width * 0.5d; + else + currentLength += scaleRatio * character.PathGeometry.Bounds.Width * (0.5d + markingData.Font.GetLeftSideBearing(character.Value) / markingData.Font.GetWidth(character.Value)); + } - if (!IsSplitOrientationOK(markingPartDocument, tempSplitRef, surface.ExtContour.ModifiedContourRef, hybridShapeFactory, projectionSurfaceRef)) - { - exteriorSplitSurface = hybridShapeFactory.AddNewHybridSplit(projectionSurfaceRef, surface.ExtContour.ModifiedContourRef, -splitOrientation); - } - else - { - exteriorSplitSurface = hybridShapeFactory.AddNewHybridSplit(projectionSurfaceRef, surface.ExtContour.ModifiedContourRef, splitOrientation); - splitOrientation = -1; - } + HybridShapePointOnCurve localPoint = character.HybridShapeFactory.AddNewPointOnCurveWithReferenceFromDistance(trackingCurveRef, startPointRef, currentLength, !isXSameDirection); + localPoint.Compute(); + Reference localPointRef = character.PartDocument.Part.CreateReferenceFromObject(localPoint); + pointSet.AppendHybridShape(localPoint); - exteriorSplitSurface.Compute(); - surface.SurfaceRef = markingPartDocument.Part.CreateReferenceFromObject(exteriorSplitSurface); + return localPointRef; + } - // >------- END EXTERIOR CONTOUR ----------- - // IF WE HAVE INTERIOR CONTOURS - if (!surface.IsIntContourListEmpty) - { - foreach (Contour intContour in surface.IntContourList) - { - // Get Scale / Positionned / Projected int contour reference - intContour.ModifiedContourRef = ContourScalePositionProjection(intContour.ImportedContourShape, catiaChar.ScaleRatio, - markingPartDocument, hybridShapeFactory, originPointRef, originAxisSystemRef, localAxisSystemRef, projectionSurfaceRef, charSet); - } - - // Assemble interior contours - if (surface.IntContourList.Count > 1) - { - HybridShapeAssemble interiorContourAssy = hybridShapeFactory.AddNewJoin(surface.IntContourList[0].ModifiedContourRef, surface.IntContourList[1].ModifiedContourRef); - interiorContourAssy.SetConnex(false); - foreach (Contour intContour in surface.IntContourList) - { - interiorContourAssy.AddElement(intContour.ModifiedContourRef); - } - - surface.IntContourListAssembledRef = markingPartDocument.Part.CreateReferenceFromObject(interiorContourAssy); - } - else - { - surface.IntContourListAssembledRef = surface.IntContourList[0].ModifiedContourRef; - } - - // Cut surface result by interior contours - HybridShapeSplit finalSurface = hybridShapeFactory.AddNewHybridSplit(surface.SurfaceRef, surface.IntContourListAssembledRef, splitOrientation); - finalSurface.Compute(); - - // Hide previous cut - hybridShapeFactory.GSMVisibility(surface.SurfaceRef, 0); - - // Add surface result - charSet.AppendHybridShape(finalSurface); - - surface.SurfaceRef = markingPartDocument.Part.CreateReferenceFromObject(finalSurface); - } - else - { - charSet.AppendHybridShape(exteriorSplitSurface); - } - } + private AxisSystem ComputeLocalAxisSystem(PartDocument partDocument, MarkingData markingData, HybridBody localAxisSystemSet, Reference localPointRef, Reference projectionSurfaceRef, Reference trackingCurveRef, + bool isXSameDirection, bool isYSameDirection, bool isZSameDirection) + { - // ASSEMBLE CATIA CHARACTER SURFACES - if (catiaChar.SurfaceList.Count > 1) - { - HybridShapeAssemble surfaceAssy = hybridShapeFactory.AddNewJoin(catiaChar.SurfaceList.First().SurfaceRef, catiaChar.SurfaceList[1].SurfaceRef); - surfaceAssy.SetConnex(false); + HybridShapeFactory hybridShapeFactory = (HybridShapeFactory)partDocument.Part.HybridShapeFactory; - foreach (Surface surface in catiaChar.SurfaceList) - { - surfaceAssy.AddElement(surface.SurfaceRef); - } + // Normal of the surface passing by the local point + HybridShapeLineNormal localLineNormal = hybridShapeFactory.AddNewLineNormal(projectionSurfaceRef, localPointRef, 0, 10, false); + localLineNormal.Compute(); + Reference localLineNormalRef = partDocument.Part.CreateReferenceFromObject(localLineNormal); - catiaChar.SurfaceListAssembledRef = markingPartDocument.Part.CreateReferenceFromObject(surfaceAssy); - } - else - { - catiaChar.SurfaceListAssembledRef = catiaChar.SurfaceList.First().SurfaceRef; - } + // Tangent of the tracking curve passing by the local point + HybridShapeLineTangency localLineTangent = hybridShapeFactory.AddNewLineTangency(trackingCurveRef, localPointRef, 0, 10, false); + localLineTangent.Compute(); + Reference localLineTangentRef = partDocument.Part.CreateReferenceFromObject(localLineTangent); - // ADD THICKNESS TO THE ASSEMBLED SURFACE - int thickSurfaceDirection = GetThickSurfaceDirection(localAxisSystem, catiaChar.SurfaceListAssembledRef, localPointRef, hybridShapeFactory); - markingPartDocument.Part.InWorkObject = markingBody; - ThickSurface characterThickSurface = shapeFactory.AddNewThickSurface(catiaChar.SurfaceListAssembledRef, thickSurfaceDirection, markingData.ExtrusionHeight.Value, 0); + // 90° angle line considering tracking curve passing by the local point + HybridShapePlaneTangent localPlaneTangent = hybridShapeFactory.AddNewPlaneTangent(projectionSurfaceRef, localPointRef); + localPlaneTangent.Compute(); + Reference localPlaneTangentRef = partDocument.Part.CreateReferenceFromObject(localPlaneTangent); - currentLength += catiaChar.ScaleWidth / 2 + charRightSideBearing; - } - } - } + HybridShapeLineAngle localLineAngle = hybridShapeFactory.AddNewLineAngle(trackingCurveRef, localPlaneTangentRef, localPointRef, false, 0, 10, 90, false); + localLineAngle.Compute(); + Reference localLineAngleRef = partDocument.Part.CreateReferenceFromObject(localLineAngle); + // ***** END OF LOCAL LINES ***** // - private Reference ContourScalePositionProjection(HybridShape contour, double scaleRatio, PartDocument partDocument, HybridShapeFactory hybridShapeFactory, Reference originPointRef, - Reference originAxisSystemRef, Reference localAxisSystemRef, Reference projectionSurfaceRef, HybridBody set) - { - Reference shapeRef = partDocument.Part.CreateReferenceFromObject(contour); + // ***** LOCAL AXIS SYSTEM ***** // - // Scaling - HybridShapeScaling scaledShape = hybridShapeFactory.AddNewHybridScaling(shapeRef, originPointRef, scaleRatio); - scaledShape.Compute(); - Reference scaledShapeRef = partDocument.Part.CreateReferenceFromObject(scaledShape); + partDocument.Part.InWorkObject = localAxisSystemSet; + AxisSystem localAxisSystem = partDocument.Part.AxisSystems.Add(); - // Positionning - HybridShapeAxisToAxis positionedShape = hybridShapeFactory.AddNewAxisToAxis(scaledShapeRef, originAxisSystemRef, localAxisSystemRef); - positionedShape.Compute(); - Reference positionedShapeRef = partDocument.Part.CreateReferenceFromObject(positionedShape); + // Local axis system : point + localAxisSystem.OriginType = CATAxisSystemOriginType.catAxisSystemOriginByPoint; + localAxisSystem.OriginPoint = localPointRef; - // Projecting - HybridShapeProject projectedShape = hybridShapeFactory.AddNewProject(positionedShapeRef, projectionSurfaceRef); - projectedShape.Compute(); - set.AppendHybridShape(projectedShape); + // Local axis system : X direction + if (isXSameDirection) + localAxisSystem.XAxisType = CATAxisSystemAxisType.catAxisSystemAxisSameDirection; + else + localAxisSystem.XAxisType = CATAxisSystemAxisType.catAxisSystemAxisOppositeDirection; - Reference projectedShapeRef = partDocument.Part.CreateReferenceFromObject(projectedShape); + localAxisSystem.XAxisDirection = localLineTangentRef; - return projectedShapeRef; - } + // Local axis system : Y direction + if (isYSameDirection) + localAxisSystem.YAxisType = CATAxisSystemAxisType.catAxisSystemAxisSameDirection; + else + localAxisSystem.YAxisType = CATAxisSystemAxisType.catAxisSystemAxisOppositeDirection; + localAxisSystem.YAxisDirection = localLineAngleRef; - /// - /// Check if the orientation of the split should be inverted by comparing split surface area and the character filled surface area. - /// - /// Part of the working document. - /// Reference of the splited surface. - /// Reference of the contour which split the surface. - /// HybridShapeFactory of the working part. - /// Reference of the surface before split. - /// - private bool IsSplitOrientationOK(PartDocument partDocument, Reference cutSurfaceRef, Reference characterContourRef, HybridShapeFactory factory, Reference supportRef) - { - double cutArea = GetSurfaceArea(partDocument, cutSurfaceRef); + // Local axis system : Z direction + if (isZSameDirection) + localAxisSystem.ZAxisType = CATAxisSystemAxisType.catAxisSystemAxisSameDirection; + else + localAxisSystem.ZAxisType = CATAxisSystemAxisType.catAxisSystemAxisOppositeDirection; - // Create a filled contour - HybridShapeFill filledContour = factory.AddNewFill(); - filledContour.AddBound(characterContourRef); - filledContour.AddSupportAtBound(characterContourRef, supportRef); - filledContour.Compute(); + localAxisSystem.ZAxisDirection = localLineNormalRef; - Reference filledContourRef = partDocument.Part.CreateReferenceFromObject(filledContour); + // Local axis system : Update + partDocument.Part.UpdateObject(localAxisSystem); - double charArea = GetSurfaceArea(partDocument, filledContourRef); + // ***** END LOCAL AXIS SYSTEM ***** // - // If the difference between areas are equal with a marge of 10% => OK - if (Math.Abs(cutArea - charArea) < 0.1 * charArea) - return true; - else - return false; + return localAxisSystem; } + /// /// Compare Z local axis direction with the normal line of the surface at the local point. @@ -610,13 +457,6 @@ private int GetThickSurfaceDirection(AxisSystem localAxisSystem, Reference surfa object[] surfaceNormalLineDirection = new object[3]; surfaceNormalLine.GetDirection(surfaceNormalLineDirection); - // Normalisazion of surfaceNormalLineDirection for comparison - /*object[] surfaceNormalLineDirectionNormalized = new object[3]; - surfaceNormalLineDirectionNormalized[0] = (double)surfaceNormalLineDirection[0] / GetVectorNorme(surfaceNormalLineDirection); - surfaceNormalLineDirectionNormalized[1] = (double)surfaceNormalLineDirection[1] / GetVectorNorme(surfaceNormalLineDirection); - surfaceNormalLineDirectionNormalized[2] = (double)surfaceNormalLineDirection[2] / GetVectorNorme(surfaceNormalLineDirection);*/ - - // Get the direction of the Z axis of the local axis system object[] ZLocalAxisDirection = new object[3]; localAxisSystem.GetZAxis(ZLocalAxisDirection); @@ -633,391 +473,6 @@ private int GetThickSurfaceDirection(AxisSystem localAxisSystem, Reference surfa return thickSurfaceDirection; } - /*private double GetVectorNorme(object[] vector) - { - return Math.Sqrt(Math.Pow((double)vector[0], 2) + Math.Pow((double)vector[1], 2) + Math.Pow((double)vector[2], 2)); - }*/ - - - /// - /// Check if each char of markingText is present in the font file. - /// If the char is present and not already loaded in the list, it is stored in the characterList. - /// - /// Part of the font document - /// Text to mark - /// List of the characters present in the text to mark - /// True if all characters have been found. False if not. - public bool CanDrawAllCharacters(PartDocument fontPartDocument, MarkingData markingData, List fontCharacterList) - { - string charactersAlreadyAdded = ""; - int nbOfCharactersFound = 0; - string charactersNotFound = ""; - HybridBodies hybridBodieCollection = fontPartDocument.Part.HybridBodies.Item("Set_Font_Disassembled").HybridBodies; - - // For each character in the markingText text - foreach (char c in markingData.Text.Value.Replace(' ', '_')) - { - // See if character is already in the list. - if (charactersAlreadyAdded.IndexOf(c) == -1) - { - int k = nbOfCharactersFound; - - if (hybridBodieCollection.Count > 0) - { - // For each shape in the Set "FontSet" of the font document - foreach (HybridBody set in hybridBodieCollection) - { - if (set.get_Name() == CharUnicodeInfo.GetUnicodeCategory(c).ToString()) - { - foreach (HybridBody charSet in set.HybridBodies) - { - if (charSet.get_Name().First() == c) - { - CatiaChar fontCharacter = new CatiaChar(c) - { - DefaultWidth = double.Parse(charSet.get_Name().Substring(3, 4)) / 100, - DefaultHeight = double.Parse(charSet.get_Name().Substring(9, 4)) / 100, - }; - - foreach (HybridShape shape in charSet.HybridShapes) - { - fontCharacter.OriginalContourShapeList.Add(shape); - } - //fontCharacter.LoadSurfaceListFromSet(charSet, Contour.ContourStatus.FontFileOriginal); - - /*foreach (HybridShape shape in set.HybridShapes) - { - if (shape.get_Name().Contains("Ext")) - { - fontCharacter.ExteriorContourList.Add(shape); - } - else if (shape.get_Name().Contains("Int")) - { - fontCharacter.InteriorContourList.Add(shape); - } - }*/ - - fontCharacterList.Add(fontCharacter); - - nbOfCharactersFound++; - - break; - } - } - - break; - } - } - } - - // Append to the characters not found list. - if (nbOfCharactersFound == k) - charactersNotFound += c; - - // Append to the characters added list. - charactersAlreadyAdded += c; - } - } - - SetScaleRatio(fontCharacterList, markingData); - - if (nbOfCharactersFound == charactersAlreadyAdded.Count()) - return true; - else - return false; - } - - private void SetScaleRatio(List fontCharList, MarkingData markingData) - { - List charHeightList = new List(); - - foreach (CatiaChar catiaChar in fontCharList) - { - charHeightList.Add(catiaChar.DefaultHeight); - } - - double maxHeight = charHeightList.Max(); - - foreach (CatiaChar catiaChar in fontCharList) - { - catiaChar.ScaleRatio = markingData.CharacterHeight.Value / maxHeight; - } - } - - /// - /// Copy the shapeListToCopy and paste it to a set. - /// - /// List of shapes to copy. - /// PartDocument of the shapes to copy. - /// Set where shapes should be paste. - /// If the PartDocument of shapes to copy and the set to paste are different, specify the PartDocument of the Set. - private void CopyPasteShape(List shapeListToCopy, PartDocument shapePartDocument, HybridBody setToPaste, PartDocument setPartDocument = null) - { - Selection copySelection = shapePartDocument.Selection; - copySelection.Clear(); - foreach (HybridShape shape in shapeListToCopy) - { - copySelection.Add(shape); - } - copySelection.Copy(); - - Selection pasteSetSelection; - if (setPartDocument != null) - { - setPartDocument.Activate(); - pasteSetSelection = setPartDocument.Selection; - } - else - pasteSetSelection = shapePartDocument.Selection; - - pasteSetSelection.Clear(); - pasteSetSelection.Add(setToPaste); - pasteSetSelection.PasteSpecial("CATPrtResultWithOutLink"); - - pasteSetSelection.Clear(); - } - - - /// - /// Get the curve length with SPAWorkbench measurable function. - /// - /// PartDocument of the curve to be measured. - /// Reference of the curve to be measured. - /// - public static double GetCurveLenght(PartDocument partDocument, Reference curveRef) - { - SPATypeLib.SPAWorkbench spaWorkbench = (SPATypeLib.SPAWorkbench)partDocument.GetWorkbench("SPAWorkbench"); - SPATypeLib.Measurable measurable = spaWorkbench.GetMeasurable(curveRef); - - return measurable.Length; - } - - - - /// - /// Get the surface area with SPAWorkbench measuble function. - /// - /// PartDocument of the surface to be measured. - /// Reference of the surface to be measured. - /// - public static double GetSurfaceArea(PartDocument partDocument, Reference surfaceRef) - { - SPATypeLib.SPAWorkbench spaWorkbench = (SPATypeLib.SPAWorkbench)partDocument.GetWorkbench("SPAWorkbench"); - SPATypeLib.Measurable measurable = spaWorkbench.GetMeasurable(surfaceRef); - - return measurable.Area; - } - - - - /// - /// Get the type of the shape. - /// - /// Part containing the shape - /// Reference of the shape - /// The type of the shape - public static ShapeType GetShapeType(Part part, Reference shapeRef) - { - HybridShapeFactory factory = (HybridShapeFactory)part.HybridShapeFactory; - return (ShapeType)factory.GetGeometricalFeatureType(shapeRef); - } - - - // TEST NEW METHOD TO GENERATE CHARACTERS - - public void test(PartDocument partDocument, MarkingData markingData) - { - System.Windows.Media.FormattedText formattedText = new System.Windows.Media.FormattedText("Input test", new CultureInfo("en-US"), - System.Windows.FlowDirection.LeftToRight, new System.Windows.Media.Typeface("Monospac821 BT"), 12, System.Windows.Media.Brushes.Black, 96); - - HybridShapeFactory hybridShapeFactory = (HybridShapeFactory)partDocument.Part.HybridShapeFactory; - HybridBody tempset = partDocument.Part.HybridBodies.Add(); - - System.Windows.Media.Geometry geometry = formattedText.BuildGeometry(new System.Windows.Point(0, 0)); - - System.Windows.Media.PathGeometry pathGeometry = geometry.GetFlattenedPathGeometry(0.001, System.Windows.Media.ToleranceType.Relative); - - - List catiaSurfaceList = new List(); - Reference planeXYReference = partDocument.Part.CreateReferenceFromObject(partDocument.Part.OriginElements.PlaneXY); - - List separatePathGeometryCollection = new List(); - foreach (System.Windows.Media.PathFigure figure in pathGeometry.Figures) - { - separatePathGeometryCollection.Add(new System.Windows.Media.PathGeometry(new List() { figure })); - } - - separatePathGeometryCollection.Sort((x, y) => y.GetArea().CompareTo(x.GetArea())); - - int smallestParentContourIndex = -1; - for (int i = 0; i < separatePathGeometryCollection.Count; i++) - { - for (int j = 0; j < i; j++) - { - System.Windows.Media.IntersectionDetail intersectionDetail = separatePathGeometryCollection[i].FillContainsWithDetail(separatePathGeometryCollection[j]); - - if (intersectionDetail == System.Windows.Media.IntersectionDetail.FullyInside) - { - smallestParentContourIndex = j; - } - } - - - // >--- FILL THE SURFACE COLLECTION --- - - // If smallestParentContourIndex is not modified, we have an external contour - if (smallestParentContourIndex == -1) - { - catiaSurfaceList.Add(new CatiaSurface(partDocument) - { - ExternalContour = new CatiaContour(partDocument, planeXYReference) - { - PathGeometry = separatePathGeometryCollection[i] - } - }); - } - else - { - // Get the parent contour. - CatiaContour parentContour = new CatiaContour(partDocument, planeXYReference) - { - PathGeometry = separatePathGeometryCollection[smallestParentContourIndex] - }; - - // Try to find the parent contour in the list of surfaces' external contour. - CatiaSurface tempSurface = catiaSurfaceList.Find((surface) => surface.ExternalContour.PathGeometry.ToString() == parentContour.PathGeometry.ToString()); - - // If the parent contour has been found, i-contour is internal. - if (tempSurface != null) - { - tempSurface.InternalContourList.Add(new CatiaContour(partDocument, planeXYReference) - { - PathGeometry = separatePathGeometryCollection[i] - }); - } - // If the parent contour is not found, i-contour is the external contour of a new surface. - else - { - catiaSurfaceList.Add(new CatiaSurface(partDocument) - { - ExternalContour = new CatiaContour(partDocument, planeXYReference) - { - PathGeometry = separatePathGeometryCollection[i] - } - }); - } - } - - // >--- END --- - } - - - System.Windows.Rect bounds = pathGeometry.Bounds; - double height = bounds.Height; - double width = bounds.Width; - - foreach (CatiaSurface surface in catiaSurfaceList) - { - DrawPathGeometry(partDocument, tempset, surface.ExternalContour.PathGeometry); - - for (int j = 0; j < surface.InternalContourList.Count; j++) - { - DrawPathGeometry(partDocument, tempset, surface.InternalContourList[j].PathGeometry); - } - } - } - - private void DrawPathGeometry(PartDocument partDocument, HybridBody tempSet, System.Windows.Media.PathGeometry pathGeometry) - { - HybridShapeFactory hybridShapeFactory = (HybridShapeFactory)partDocument.Part.HybridShapeFactory; - List pointReferenceList = new List(); - List lineList = new List(); - - foreach (System.Windows.Media.PathSegment segment in pathGeometry.Figures.First().Segments) - { - if (segment.GetType() == typeof(System.Windows.Media.PolyLineSegment)) - { - foreach (System.Windows.Point point in ((System.Windows.Media.PolyLineSegment)segment).Points) - { - HybridShape pointShape = hybridShapeFactory.AddNewPointCoord(point.X, point.Y, 0); - pointShape.Compute(); - Reference pointShapeRef = partDocument.Part.CreateReferenceFromObject(pointShape); - - pointReferenceList.Add(pointShapeRef); - } - - for (int i = 0; i < pointReferenceList.Count(); i++) - { - HybridShape line; - if (i == 0) - line = hybridShapeFactory.AddNewLinePtPt(pointReferenceList[i], pointReferenceList[pointReferenceList.Count - 1]); - else - line = hybridShapeFactory.AddNewLinePtPt(pointReferenceList[i - 1], pointReferenceList[i]); - - line.Compute(); - lineList.Add(partDocument.Part.CreateReferenceFromObject(line)); - } - } - else - { - if (segment.GetType() == typeof(System.Windows.Media.PolyBezierSegment)) - { - HybridShapeSpline curve = hybridShapeFactory.AddNewSpline(); - foreach (System.Windows.Point point in ((System.Windows.Media.PolyBezierSegment)segment).Points) - { - HybridShape pointShape = hybridShapeFactory.AddNewPointCoord(point.X, point.Y, 0); - pointShape.Compute(); - Reference pointShapeRef = partDocument.Part.CreateReferenceFromObject(pointShape); - - pointReferenceList.Add(pointShapeRef); - - curve.AddPoint(pointShapeRef); - curve.Compute(); - } - - tempSet.AppendHybridShape(curve); - } - else - { - if (segment.GetType() == typeof(System.Windows.Media.LineSegment)) - { - Reference startPointShapeRef; - if (pointReferenceList.Count != 0) - { - startPointShapeRef = pointReferenceList.Last(); - } - else - { - System.Windows.Point startPoint = pathGeometry.Figures.First().StartPoint; - HybridShape startPointShape = hybridShapeFactory.AddNewPointCoord(startPoint.X, startPoint.Y, 0); - startPointShape.Compute(); - startPointShapeRef = partDocument.Part.CreateReferenceFromObject(startPointShape); - - pointReferenceList.Add(startPointShapeRef); - } - - System.Windows.Point point = ((System.Windows.Media.LineSegment)segment).Point; - HybridShape pointShape = hybridShapeFactory.AddNewPointCoord(point.X, point.Y, 0); - pointShape.Compute(); - Reference pointShapeRef = partDocument.Part.CreateReferenceFromObject(pointShape); - - pointReferenceList.Add(pointShapeRef); - - HybridShape line = hybridShapeFactory.AddNewLinePtPt(startPointShapeRef, pointShapeRef); - lineList.Add(partDocument.Part.CreateReferenceFromObject(line)); - } - } - } - } - - HybridShapeAssemble assy = hybridShapeFactory.AddNewJoin(lineList.First(), lineList[1]); - for (int i = 2; i < lineList.Count; i++) - { - assy.AddElement(lineList[i]); - } - - tempSet.AppendHybridShape(assy); - } } } diff --git a/Graphy/Model/Generator/SupportedCharGenerator.cs b/Graphy/Model/Generator/SupportedCharGenerator.cs index 0805052..50535f9 100644 --- a/Graphy/Model/Generator/SupportedCharGenerator.cs +++ b/Graphy/Model/Generator/SupportedCharGenerator.cs @@ -48,10 +48,45 @@ public int StepProgressRate } // PUBLIC METHODS - public string GenerateSupportedCharacters(Font font) + public string ComputeSupportedCharacterList(FontFamily fontFamily) { string supportedCharacterList = ""; - foreach (UnicodeCategory unicodeCategory in Font.GetUnicodeCategoryCollection()) + + if (fontFamily.GetTypefaces().First().TryGetGlyphTypeface(out GlyphTypeface glyphTypeFace)) + { + for (ushort i = 0; i < ushort.MaxValue; i++) + { + if (glyphTypeFace.CharacterToGlyphMap.TryGetValue(i, out ushort glyphIndex)) + supportedCharacterList += Convert.ToChar(i); + + ProgressRate += 1d / (double)glyphTypeFace.CharacterToGlyphMap.Count(); + } + } + + return supportedCharacterList; + } + + public string GenerateSupportedCharacters(SelectableFont font) + { + string supportedCharacterList = ""; + + // test + + for(ushort i = 0; i < ushort.MaxValue; i++) + { + if (IsCharacterSupported(Convert.ToChar(i), font.FontFamily)) + supportedCharacterList += Convert.ToChar(i); + } + + /*font.FontFamily.GetTypefaces().First().TryGetGlyphTypeface(out System.Windows.Media.GlyphTypeface glyph); + foreach(KeyValuePair character in glyph.CharacterToGlyphMap) + { + supportedCharacterList += Convert.ToChar(Convert.ToUInt16(character.Key)); + }*/ + + // fin test + + /*foreach (UnicodeCategory unicodeCategory in Font.GetUnicodeCategoryCollection()) { foreach (char c in GetCharsByUnicodeCategory(unicodeCategory)) { @@ -60,7 +95,7 @@ public string GenerateSupportedCharacters(Font font) } ProgressRate += (1d / (double)Font.GetUnicodeCategoryCollection().Count()); - } + }*/ return supportedCharacterList.ToString(); } @@ -70,7 +105,7 @@ private bool IsCharacterSupported(char characterToCheck, FontFamily fontFamily) { int unicodeValue = Convert.ToUInt16(characterToCheck); - fontFamily.GetTypefaces().First().TryGetGlyphTypeface(out GlyphTypeface glyph); + fontFamily.GetTypefaces().First().TryGetGlyphTypeface(out System.Windows.Media.GlyphTypeface glyph); if (glyph != null && glyph.CharacterToGlyphMap.TryGetValue(unicodeValue, out ushort glyphIndex)) { return true; diff --git a/Graphy/Model/MarkingData.cs b/Graphy/Model/MarkingData.cs index 08d1782..a90697a 100644 --- a/Graphy/Model/MarkingData.cs +++ b/Graphy/Model/MarkingData.cs @@ -13,7 +13,7 @@ public class MarkingData : ObservableObject { public MarkingData(string textValue, double charactereHeightValue, double extrusionHeightValue) { - Font = new GeneratedFont(); + Font = new SelectableFont(new System.Windows.Media.FontFamily("Arial")); Text = new LinkableData() { Value = textValue @@ -37,7 +37,7 @@ public MarkingData(string textValue, double charactereHeightValue, double extrus private string _name; private LinkableData _text; - private GeneratedFont _font; + private SelectableFont _font; private LinkableData _characterHeight; private LinkableData _extrusionHeight; private string _trackingCurveName = "No curve selected"; @@ -63,7 +63,7 @@ public LinkableData Text } } - public GeneratedFont Font + public SelectableFont Font { get => _font; set diff --git a/Graphy/Model/Font.cs b/Graphy/Model/SelectableFont.cs similarity index 56% rename from Graphy/Model/Font.cs rename to Graphy/Model/SelectableFont.cs index 2cd82fa..156314a 100644 --- a/Graphy/Model/Font.cs +++ b/Graphy/Model/SelectableFont.cs @@ -1,50 +1,50 @@ using GalaSoft.MvvmLight; using System; using System.Collections.Generic; -using System.Globalization; +using System.Windows.Media; using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Windows.Media; namespace Graphy.Model { - public class Font : ObservableObject + public class SelectableFont : ObservableObject { - public Font() - { - - } - - public Font(FontFamily fontFamily, string supportedCharacterList = "") + public SelectableFont(FontFamily fontFamily, bool isDefault = false) { FontFamily = fontFamily; - SupportedCharacterList = supportedCharacterList; + IsDefault = isDefault; + + if (IsDefault) + IsSelected = true; } - private string _name; + // ATTRIBUTS private FontFamily _fontFamily; - private bool _isCalculated = false; + private bool _isSelected; + private bool _isCalculated; private string _supportedCharacterList; + private bool _isDefault; - public string Name + public FontFamily FontFamily { - get => _name; + get => _fontFamily; set { - Set(() => Name, ref _name, value); + Set(() => FontFamily, ref _fontFamily, value); } } - public FontFamily FontFamily + public bool IsSelected { - get => _fontFamily; + get => _isSelected; set { - Set(() => FontFamily, ref _fontFamily, value); - FontFamily.FamilyNames.TryGetValue(System.Windows.Markup.XmlLanguage.GetLanguage("en-us"), out string familyName); - Name = familyName; + if(!IsDefault || (IsDefault && value)) + { + Set(() => IsSelected, ref _isSelected, value); + } } } @@ -64,28 +64,47 @@ public string SupportedCharacterList { Set(() => SupportedCharacterList, ref _supportedCharacterList, value); - if (SupportedCharacterList != "") - IsCalculated = true; - else - IsCalculated = false; + IsCalculated = SupportedCharacterList != "" ? true : false; } } + public bool IsDefault + { + get => _isDefault; + set + { + Set(() => IsDefault, ref _isDefault, value); + } + } - // METHODS + // PUBLIC METHODS + public void ComputeSupportedCharacterList() + { + if (!IsCalculated && FontFamily.GetTypefaces().First().TryGetGlyphTypeface(out GlyphTypeface glyphTypeFace)) + { + for (ushort i = 0; i < ushort.MaxValue; i++) + { + if (glyphTypeFace.CharacterToGlyphMap.TryGetValue(i, out ushort glyphIndex)) + SupportedCharacterList += Convert.ToChar(i); + } + } + } - public static List GetUnicodeCategoryCollection() + public PathGeometry GetCharacterGeometry(char c) { - List unicodeCategoryCollection = new List(); + int unicodeValue = Convert.ToUInt16(c); - // FILL UNICODE CATEGORY COLLECTION - foreach (UnicodeCategory category in System.Enum.GetValues(typeof(UnicodeCategory))) + if (FontFamily.GetTypefaces().First().TryGetGlyphTypeface(out GlyphTypeface glyphTypeFace)) { - if (category != UnicodeCategory.PrivateUse) - unicodeCategoryCollection.Add(category); + if (glyphTypeFace.CharacterToGlyphMap.TryGetValue(unicodeValue, out ushort glyphIndex)) + { + return glyphTypeFace.GetGlyphOutline(glyphIndex, 16, 1).GetFlattenedPathGeometry(0.001, System.Windows.Media.ToleranceType.Relative); + } + else + return null; } - - return unicodeCategoryCollection; + else + return null; } @@ -127,17 +146,6 @@ public double GetRightSideBearing(char c) public double GetWidth(char c) { - /*int unicodeValue = Convert.ToUInt16(c); - - var typefaces = FontFamily.GetTypefaces(); - if (typefaces.First().TryGetGlyphTypeface(out GlyphTypeface glyphTypeFace)) - { - glyphTypeFace.CharacterToGlyphMap.TryGetValue(unicodeValue, out ushort glyphIndex); - return glyphTypeFace.AdvanceWidths[glyphIndex]; - } - else - return 0;*/ - int unicodeValue = Convert.ToUInt16(c); if (FontFamily.GetTypefaces().First().TryGetGlyphTypeface(out GlyphTypeface glyphTypeFace)) @@ -154,35 +162,5 @@ public double GetWidth(char c) } - // ************************************* - - public override bool Equals(object obj) - { - // Is null? - if (Object.ReferenceEquals(null, obj)) - { - return false; - } - - // Is the same object? - if (Object.ReferenceEquals(this, obj)) - { - return true; - } - - // Is the same type? - if (obj.GetType() != this.GetType()) - { - return false; - } - - Font font = (Font)obj; - return (Name == font.Name); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } } } diff --git a/Graphy/Properties/Resources.en-US.resx b/Graphy/Properties/Resources.en-US.resx index 77d6b22..f869a1c 100644 --- a/Graphy/Properties/Resources.en-US.resx +++ b/Graphy/Properties/Resources.en-US.resx @@ -147,6 +147,24 @@ Parts management + + List of supported characters: + + + Ascending order + + + Sort + + + Descending order + + + Favorites + + + Font management + English @@ -261,21 +279,6 @@ Select the working part - - Font is non computed - - - Available characters list - - - Font - - - Generate - - - Add a font - - @@ -291,18 +294,6 @@ About us - - Create a new font - - - 3D font directory - - - Catia font directory - - - Font file management - Language @@ -331,6 +322,6 @@ A wild exception has appeared. - Process in progress ! + In progress ! \ No newline at end of file diff --git a/Graphy/Properties/Resources.fr-FR.resx b/Graphy/Properties/Resources.fr-FR.resx index d6db227..862aead 100644 --- a/Graphy/Properties/Resources.fr-FR.resx +++ b/Graphy/Properties/Resources.fr-FR.resx @@ -147,6 +147,24 @@ Pièces à traiter + + Liste des caractères supportés : + + + Ordre alphabétique + + + Trier + + + Ordre alphabétique inverse + + + Favoris + + + Gestion des polices + English @@ -163,7 +181,7 @@ Création d'un nouveau marquage 3D ! - Hauteur de charactères + Hauteur de caractères Hauteur d'extrusion @@ -202,7 +220,7 @@ - L'axe X doit être la tangente à la "Courbe de suivi" passant par son origine. Son sens indique le sens du marquage. - - L'axe Y est la résultante des axes X et Z. Son sens indique l'orientation des charactères. + - L'axe Y est la résultante des axes X et Z. Son sens indique l'orientation des caractères. - L'axe Z doit être la normale à la "Surface de projection" passant par son origine. Son sens indique le sens d'ajout de matière. @@ -265,16 +283,7 @@ Police non calculée - Liste des charactères disponibles - - - Police - - - Générer - - - Ajouter une police + Liste des caractères disponibles - @@ -291,18 +300,6 @@ A propos - - Créer une nouvelle police - - - Répertoire police 3D - - - Répertoire police Catia - - - Gestion des fichiers de police - Langue diff --git a/Graphy/Themes/Generic.xaml b/Graphy/Themes/Generic.xaml index 09ba565..bfe38f1 100644 --- a/Graphy/Themes/Generic.xaml +++ b/Graphy/Themes/Generic.xaml @@ -1,13 +1,14 @@ + xmlns:local="clr-namespace:Graphy" + xmlns:cc="clr-namespace:Graphy.CustomControl" > - + diff --git a/Graphy/View/DesignTableView.xaml b/Graphy/View/DesignTableView.xaml index c2637b5..4e53924 100644 --- a/Graphy/View/DesignTableView.xaml +++ b/Graphy/View/DesignTableView.xaml @@ -5,7 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Graphy" mc:Ignorable="d" - d:DesignHeight="720" d:DesignWidth="500"> + d:DesignHeight="720" d:DesignWidth="450"> @@ -29,7 +29,7 @@ - + @@ -37,7 +37,7 @@ - + @@ -80,7 +80,7 @@ + Text="{Binding Source={StaticResource Locator}, Path=DesignTableViewModel.PartFolderPath}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Graphy/View/NewFontView.xaml.cs b/Graphy/View/FontView.xaml.cs similarity index 72% rename from Graphy/View/NewFontView.xaml.cs rename to Graphy/View/FontView.xaml.cs index 00f4955..68ddc5f 100644 --- a/Graphy/View/NewFontView.xaml.cs +++ b/Graphy/View/FontView.xaml.cs @@ -18,9 +18,9 @@ namespace Graphy.View /// /// Logique d'interaction pour FontView.xaml /// - public partial class NewFontView : UserControl + public partial class FontView : UserControl { - public NewFontView() + public FontView() { InitializeComponent(); } @@ -30,5 +30,10 @@ private void BackButton_Click(object sender, RoutedEventArgs e) { BackButtonClicked?.Invoke(sender, new EventArgs()); } + + private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) + { + ClearSearchButton.Visibility = SearchTextBox.Text == "" ? Visibility.Collapsed : Visibility.Visible; + } } } diff --git a/Graphy/View/NewFontView.xaml b/Graphy/View/NewFontView.xaml deleted file mode 100644 index eaabf07..0000000 --- a/Graphy/View/NewFontView.xaml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + - + diff --git a/Graphy/View/SettingView.xaml.cs b/Graphy/View/SettingView.xaml.cs index d23f2da..e9ce7c3 100644 --- a/Graphy/View/SettingView.xaml.cs +++ b/Graphy/View/SettingView.xaml.cs @@ -36,11 +36,5 @@ private void BackButton_Click(object sender, RoutedEventArgs e) { BackButtonClicked?.Invoke(sender, new EventArgs()); } - - public event EventHandler ShowAddNewFont; - private void AddNewFontButton_Click(object sender, RoutedEventArgs e) - { - ShowAddNewFont?.Invoke(sender, new EventArgs()); - } } } diff --git a/Graphy/View/StatusView.xaml b/Graphy/View/StatusView.xaml index 3c5b124..40126ea 100644 --- a/Graphy/View/StatusView.xaml +++ b/Graphy/View/StatusView.xaml @@ -26,7 +26,8 @@ - + @@ -40,26 +41,16 @@ - + - - - - - - -