SurfaceBody.IsPointInside could returns wrong results

SurfaceBody.IsPointInside could returns wrong results

atsushi_kuno
Enthusiast Enthusiast
192 Views
0 Replies
Message 1 of 1

SurfaceBody.IsPointInside could returns wrong results

atsushi_kuno
Enthusiast
Enthusiast

Hi, everyone

 

I am writing an add-in to get the mass distribution of an assembly (asm) or a part as a grid of mass points. My strategy is 1. generating 3d grid coordinates within the RangeBox of the asm or the part, 2. verifying whether a point in the grid is contained in a SurfaceBody within the asm or the part, and 3. computing the mass based on the iProperty of the SurfaceBody and the volume of a single voxel. The code works fine in most cases, but I got an unexpected result for an object.

 

The figure below describes how the object is modelled. That part is the body part of the Utah Teapot reconstructed from .stp file uploaded here. 

body.png

 

And the figure below is the mass distribution which is volume rendered with mayavi where points with non-zero mass are rendered with orange-ish color.mass_distr-1.png

As you can see in the second figure, there are mass points aligned like a triangle at the bottom left of the figure. Actually, they look like being placed on the plane aligned with the bottom of the teapot. I thought that Mayavi rendered the distribution stored in a .csv file wrongly, but I got the same result with matplotlib. I have to say that those unexpected points are actually generated with my code and described in the .csv file.

 

I looked into my code but I could not find flaws in the grid coordinate generation and the mass computation for each point. For me, SurfaceBody.IsPointInside is the only suspect which mistakenly recognizes that those points are contained inside the teapot. The code below is excerpted from my code. Does anybody specify or know which part is a potential cause of the issue?

 

 

public List<List<double>> GetGridCoordinates()
{
    gridXYZs = new List<List<double>>();

    foreach (double x in this.aabbSideCoords)  // aabbSideCoords is sth like [-1/n, -1/(n-1), ..., 1/(n-1), 1/n]
    {
        foreach (double y in this.aabbSideCoords)
        {
            foreach (double z in this.aabbSideCoords)
            {
                this.gridXYZs.Add(new List<double> { x, y, z });
            }
        }
    }

    return gridlXYZs;
}


public (double, double) GetVoxelMass(double x, double y, double z, bool useBox=false)
{
    double mass = 0;
    double massDensity = 0;

    foreach (SurfaceBody body in this.surfaceBodyMassDensity.Keys)  // surfaceBodyMassDensity is a Dictionary<SurfaceBody, double>
    {
        ContainmentEnum pointContained = body.IsPointInside[new double[] { x, y, z }, useBox];
        if (ContainmentEnum.kUnknownContainment < pointContained && pointContained <= ContainmentEnum.kOnContainment)
        {
            (mass, massDensity) = this.surfaceBodyMassDensity[body];
        }
    }

    return (mass, massDensity);
}


public void GetMassDistribution()
{
    mass;
    double massDensity;
    int count = 0;
    StringBuilder strBuilder = new StringBuilder();

    gridXYZs = GetGridCoordinates()

    foreach (List<double> xyz in gridXYZs)
    {
        double x = xyz[0];  // [cm]
        double y = xyz[1];  // [cm]
        double z = xyz[2];  // [cm]

        (mass, massDensity) = GetVoxelMass(x + posXAabbCenter.X,  // posXAabbCenter is the center point of the RangeBox of an assembly/part computed like "(MinPoint + MaxPoint) * 0.5"
                                           y + posXAabbCenter.Y,
                                           z + posXAabbCenter.Z);

        // coordinate unit adjustment
        double _x = x / 1e+2;  // [cm] -> [m]
        double _y = y / 1e+2;  // [cm] -> [m]
        double _z = z / 1e+2;  // [cm] -> [m]

        // record a single set of data for a the voxel
        double[] singleVoxel = { _x, _y, _z, mass, massDensity / 1e+6 };  // ([m]) x 3, [kg], [kg/cm^3] -> [kg/m^3]

        strBuilder.AppendLine(string.Join(",", singleVoxel));
        count++;
    }

    using (var writer = System.IO.File.AppendText("output\csv\file\Path"))
    {
        writer.Write(strBuilder.ToString());
    }
}

 

 

If anybody needs more lines of my code, I will post them as requested.

 

Thanks in advance!

0 Likes
193 Views
0 Replies
Replies (0)