Page 1 of 1

Get Data of path in code

Posted: 17 Oct 2016, 18:02
by kemarofangs
Hey,

Is there any way to read in a Shapes.Path object's Geometry Data and convert it to say a list of points within code? I have this working in normal WPF but have to do the same in Noesis. I need this in order for my polygon 2 polygon impulse physics engine to work. My aim is to create a bunch of user controls and specify an outline using a simple Path object. Thank you for the advice in advance. Below is all the working code for pure WPF.
<UserControl x:Class="Asteroids.UserControl_Asteroid"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             Width="100" Height="100">
    <Path x:Name="m_path_outline" Data="M 20,0 L70,5 L100,20 L80,90 L30,95 L0,50 Z" Stretch="Fill">
        <Path.Fill>
            <!--<ImageBrush ImageSource="/Textures/Asteroid.png" />-->
            <ImageBrush ImageSource="pack://application:,,,/Textures/Asteroid.png" />
        </Path.Fill>
    </Path>
</UserControl>
PointCollection pointCollection = PathDataToPointCollection(m_path_wireframe.Data);
/// <summary>
        /// Parses point data from a Shapes.Path object
        /// 
        /// |Examples|
        /// 1) M 0,0 L80,50 L0,100 Z
        /// 2) M 20,0 L70,5 L100,20 L80,90 L30,95 L0,50 Z
        /// 
        /// |Use|
        /// Path path = new Path();
        /// PointCollection pointCollection = PathDataToPointCollection(path.Data);
        /// </summary>
        /// <param name="geometry_pathData"></param>
        /// <returns></returns>
        private PointCollection PathDataToPointCollection(Geometry geometry_pathData)
        {
            PointCollection pointCollection = new PointCollection();
            PathFigureCollection pathFigureCollection = null;

            PathGeometry pathGeometry = m_path_wireframe.Data as PathGeometry;
            if (null != pathGeometry) // Geometry data defined in code behind
            {
                pathFigureCollection = pathGeometry.Figures;
            }
            else  // Geometry data defined in wpf
            {
                GeometryValueSerializer serializer = new GeometryValueSerializer();
                string str = serializer.ConvertToString(m_path_wireframe.Data, null);
                if (null != str)
                {
                    pathFigureCollection = PathFigureCollection.Parse(str);
                }
            }

            // Deduce points from the PathFigureCollection object
            if (null != pathFigureCollection && 1 == pathFigureCollection.Count)
            {
                PathFigure pathFigure = pathFigureCollection[0] as PathFigure;
                if (null != pathFigure && null != pathFigure.Segments && 1 == pathFigure.Segments.Count)
                {
                    pointCollection.Add(pathFigure.StartPoint);
                    PolyLineSegment polyLineSegment = pathFigure.Segments[0] as PolyLineSegment;
                    if (null != polyLineSegment)
                    {
                        foreach (Point point in polyLineSegment.Points)
                        {
                            pointCollection.Add(point);
                        }
                    }
                }
            }
            return pointCollection;
        }
Edit:

I'm going to try this instead...
/// <summary>
        /// Parses point data from a Shapes.Path object
        /// 
        /// |Examples|
        /// 1) "M0,0 L100,50 L0,100 Z" converts to "M0,0L100,50 0,100z"
        /// 
        /// </summary>
        /// <param name="miniLanguage"></param>
        /// <returns></returns>
        public Vec2[] Parse(Geometry geometry)
        {
            string miniLanguage = geometry.ToString();

            // Remove letters leaving only coordinates seperated by spaces.
            miniLanguage = miniLanguage.ToUpper().Replace("M", string.Empty);
            miniLanguage = miniLanguage.Replace("L", " ");
            miniLanguage = miniLanguage.Replace("Z", string.Empty);

            // Split the coordinates on the spaces an convert them to an array of points.
            return miniLanguage
                .Split(" ".ToCharArray())
                .Select(t => Vec2.Parse(t))
                .ToArray();
        }

Re: Get Data of path in code

Posted: 19 Oct 2016, 02:18
by sfernandez
Hi,

I think your latest approach won't work either, because the Geometry.ToString() will return just the name of the underlying geometry type.

Unfortunately there is no way to get that info in NoesisGUI. If you need this, please create a ticket in our bugtracker and we will discuss the best way to implement it.

Regards.

Re: Get Data of path in code

Posted: 27 Oct 2016, 05:23
by kemarofangs
You are correct sir. I've created a ticket as this is vital to my efforts. 0000970
Should I mark this post as checked then?

Re: Get Data of path in code

Posted: 28 Oct 2016, 19:01
by sfernandez
Thanks, I already asked you for feedback.

It would be better to mark it as solved when we release a version with the fix, to avoid confusion.