Home > OS >  Hard time adjusting string to fill Class
Hard time adjusting string to fill Class

Time:03-29

I'm writing a Class library to extract data from a 3D model in a CAD software called SpaceClaim. When I extract data from the model I get a string, the 3 usable possibilities below:

{Cone: Origin = (0.006, -0.006, 0.01), Direction = (0, 0, 1), Radius = 0.008, HalfAngle = 0.785398163397448}
{Cylinder: Origin = (-0.003, 0.001, 0), Direction = (0, 0, 1), Radius = 0.00921954445729289}
{Plane: Origin = (0, 0, 0.01), DirX = (1, 0, 0), DirY = (0, 1, 0), DirZ = (0, 0, 1)}

So first we have the type ( Plane, Cone Or Cilinder), then the Origin is a weird looking Array ( replace () with []), and for now i just need the Radius (if Type = Cone or Cilinder) and the HalfAngle (if Type = Cone)

I made a class called FaceInfo:

public class FaceInfo
    {            
        public string Type { get; set; }
        public Coordinates Origin { get; set; }
        public double Radius { get; set; } = 0;
        public double HalfAngle { get; set; } = 0;
    }
public class Coordinates
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double Z { get; set; }

        public Coordinates(string value)
        {
            string [] split = value.Split(new char[] { '(', ')', ',' });
            X = double.Parse(split[0]);
            Y = double.Parse(split[1]);
            Z = double.Parse(split[2]);
        }
    }

I've tried replacing characters, splitting, substrings.

All fails at some point.

Please some help. Thank you

PS. the coordinates class still takes () for the array, need to fix that too. But first, the returned string. No point in working with () or [] if the data is unreadable.

CodePudding user response:

To extract the data you can use the following solution.

string pattern = @"\((?<origin>.*)\). =\s*\((?<direction>.*)\). =\s*(?<radius>[\d\.]*). =\s*(?<halfAngle>.*)\}"; // continue the pattern for your needs
Regex rx = new Regex(pattern);

Match m = rx.Match(searchString);

FaceInfo faceInfo = new FaceInfo();

if (m.Success)
{
    faceInfo.Origin = new Coordinates(m.Groups["origin"].Value);
    faceInfo.Direction = new Coordinates(m.Groups["direction"].Value);
    faceInfo.Radius = Convert.ToDouble(m.Groups["radius"].Value);
    faceInfo.HalfAngle = Convert.ToDouble(m.Groups["halfAngle"].Value);
}

And modify the Coordinate class to

public class Coordinates
{
    public double X { get; set; }
    public double Y { get; set; }
    public double Z { get; set; }

    public Coordinates(string value)
    {
        string[] split = value.Split(new char[] { ',' });
        X = double.Parse(split[0]);
        Y = double.Parse(split[1]);
        Z = double.Parse(split[2]);
    }
}

CodePudding user response:

It sounds like a parsing task. So I would go with (pseudo-code, so check me on this)

var lines = input.Split("\n");
Console.WriteLine(lines[0]); // for QA

foreach(var line in lines) {
 int index1= line.indexOf(":");
 string _type = line.SubString(1,index1);
 Console.WriteLine(_type); // for QA;
 string restOfLine = line.SubString(index1 1, line.Length - index1);
 Console.WriteLine(restOfLine); // for QA;
 var parts = restOfLine.Split(',');
  foreach(var p in parts) {
     Console.WriteLine(p); // for QA;
     // ... continue the parsing....
  }

  FaceInfo f = new FaceInfo();
  f.Type = _type;
  // f. .... whatever = whatever...
}

something like that? make sure you parse in a very correct way, since this text is not exactly in standard JSON format....that's what all the // for QA comments are for.

CodePudding user response:

So let the string value is the input string you get from your CAD program. You already put sample inputs so I will use them too.

    {Cone: Origin = (0.006, -0.006, 0.01)
     , 
     Direction = (0, 0, 1), Radius = 0.008
     , 
     HalfAngle = 0.785398163397448}

When you use split with

      new char[] { '('  ,  ')'  , ',' }

it will parse the string whenever it sees a '(' , ')' or ','

So your output array from the split method will be look something like

0 => Cone: Origin

1 => 0.006

2 => -0.006

3 => 0.01

...

To see elements of your array, you can use

Simple way:

foreach(string element in splitOutputArray)
{
    // If you use form
    MessageBox.Show(element);
    
    // If you use console 
    Console.WriteLine(element);
}
    

 

The more proper way: Use breakpoints. https://docs.microsoft.com/en-us/visualstudio/debugger/using-breakpoints?view=vs-2022

So when you look at elements of your array you will notice the problem. Your indexing is not true.

Possible Solution:

Both your fields (Origin,Direction...) and values in the fields(0.006, -0.006, 0.01) split with ','. So you must look at elements of your output and correct your indexes.

        X = double.Parse(split[0]);
        Y = double.Parse(split[1]);
        Z = double.Parse(split[2]);

must be something like this

        X = double.Parse(split[1]);
        Y = double.Parse(split[2]);
        Z = double.Parse(split[3]);

Summary: You did most of the work right but you must correct indexes (split[index]). Sorry if ı overexplained ı don't know your level.

  • Related