Search code examples
c#helix-3d-toolkit

Unable to determine location of a particular geometry and Method to retrieve geometry using its location and sizes


I am using HelixToolkit and programming using C#.

I wrote the following code in order to create a cube:

 var meshBuilder3 = new MeshBuilder(false, false);
 meshBuilder3.AddBox(new Point3D(1, 9, 15), 2, 2, 2);
 var mesh1000 = meshBuilder3.ToMesh(true);
 Color halfTransparent = Color.FromArgb(127, Colors.Black.R, Colors.Black.G, Colors.Black.B);
 var TranspMaterial = MaterialHelper.CreateMaterial(halfTransparent);
 modelGroup.Children.Add(new GeometryModel3D { Geometry = mesh1000, Material = TranspMaterial });

Now, I wrote few more lines in order to retrieve the Geometrical object.

Model3DCollection children  = modelGroup.Children;
Model3D model = children[0];
GeometryModel3D geom3D = (GeometryModel3D)model;
Geometry3D geo3D = geom3D.Geometry;
Rect3D rec3D = geo3D.Bounds;
Point3D x = rec3D.Location;

When I pointed my cursor on Rect3D object and tried to look at the location and X,Y,Z size values, it was displaying location as {0,8,5} and X,Y,Z as 13,5,5 respectively.

But my cube size is 2 and location is {1,9,15}. I don't understand why its printing some wrong value.

Also I went through all the methods available, but I could not find any method which retrieves GeometryModel3D object if we pass location and center values. If I have a location of my cube and also its size, can I retrieve Geometry3D object. Because if I try to retrieve the children, loop the whole children and then if I try to verify the locations of each children with the desired one, it would be really a huge programme and requires more computational time.

I want something like this:

GeometryModel3D geom3D = children.find(Point3D Location,double sizeX,double sizeY,double sizeZ);

I would be really glad,if someone can answer these two questions. Thanks in Advance


Solution

  • I've able to create roughly duplicate your code using v1.0.0 release of the toolkit by the following code.

    var modelGroup = new GroupModel3D();
    
    var meshBuilder3 = new MeshBuilder(false, false);
    meshBuilder3.AddBox(new Vector3(1, 9, 15), 2, 2, 2);
    var mesh1000 = meshBuilder3.ToMesh();
    
    var geomdeModel3D = new MeshGeometryModel3D {Geometry = mesh1000};
    modelGroup.Children.Add(geomdeModel3D);
    
    var children = modelGroup.Children;
    var model = children[0];
    GeometryModel3D geom3D = (GeometryModel3D)model;
    
    
    Geometry3D geo3D = geom3D.Geometry;
    var bound = geo3D.Bound;
    Console.WriteLine(bound); // <--- Minimum:X:0 Y:8 Z:14 Maximum:X:2 Y:10 Z:16
    

    The bound retrieved here is actually correct.


    Regarding your second part of the question. What you requested is not as simple as you thought. Since this toolkit seems like a mesh manipulation tool, AddBox doesn't actually created a (traditionally speaking) box, i.e. an object with it's 6 vertices, but generated several mesh polygons / triangles under the hood. This means that although the geometry still has a physical center and looks like a 'box', doing what you asked is quite tricky (unless with a lot of assumptions).

    For example, you could actually add cylinder or tube in the same model group alongside the box. Then your children.find won't be able to know whether each children is a box (without sophisticated checks).

    • If you know you will always only have boxes inside your model group, then you can use the Bound property's Minimum and Maximum to do the check, by iterating Children
    • If you purely want some structure to store your collection of boxes, you can just implement your own box collection, perhaps with the help of algorithm like KD-Tree to perform a quicker run-time search.