Detect cylinder is outer or inner

Hiii …I want to determine which cylinder surface is inside and which one is outside in the given model.How can I do that ?

image

I have written this code but both cylinders are getting as inner cylinder .Here attaching the sample code.

RhinoDoc activeDoc = RhinoDoc.ActiveDoc;

IEnumerable<RhinoObject> brepObjects = activeDoc.Objects.GetObjectList(ObjectType.Brep);
RhinoObject object1 = brepObjects.ElementAt(0);
Brep Brep_body = Brep.TryConvertBrep(object1.Geometry);
A = Brep_body;
BrepFace face1 = Brep_body.Faces.ElementAt(3);

Cylinder cylinder;
face1.TryGetCylinder(out cylinder);
Brep b2 = face1.ToBrep();

Point3d pointOnSurface = face1.PointAt(0.5, 0.5);
Vector3d normal = face1.NormalAt(0.5, 0.5);

normal *= cylinder.Radius;

Point3d samplePoint = pointOnSurface + normal;

Line axisLine = new Line(cylinder.Center, cylinder.Axis);
Line sampleLine = new Line(samplePoint, cylinder.Axis);


int isColinear = sampleLine.Direction.IsParallelTo(axisLine.Direction);
A = isColinear;

activeDoc.Views.Redraw();
object1.CommitChanges();

Hi @Supriya,

it is important to know what is your goal. For example, if you always have two surfaces like this, you can simply check which has the smaller area and you are done :slight_smile:

There is also a function that checks if the point is inside a (closed!) Brep:

https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.brep/ispointinside

That means that you could take those two Cylinders, make copies of them and close them both. You can use this for example to “cap” them:

https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.brep/capplanarholes

Then, you can take a point on the surface of the cylinder and check if it is inside the other one…the one that has a point inside the other one IS the INNER one.

I am sure there are other mathematical tricks you could use…I see you tried drawing a Line…there must be a solution hiding there as well, but the two above are the first that came to my mind…I will write if I think of another one.

For example, here is another one :slight_smile: Find the center of the entire object (the center of the Bounding Box for example), and check the distance from that center to the closest point on both Surfaces…the one closer to the center is the inner one.

2 Likes

image

Hii @dimcic I want to get this holes as inside of the square surface.

I think the most robust solution would be the one I mentioned, where you create a closed Brep out of that square element and then choose wisely a point on the cylinder surface and check if it is inside that closed Brep.

This can be done using the Surface.TryGetCylinder() method to detect cylinders, but there are a few areas you will need to address.

You’ll want to use the version of Surface.TryGetCylinder() that accepts a tolerance.

Boolean Surface.TryGetCylinder(out Cylinder cylinder, Double tolerance)

The version that does not accept a tolerance uses RhinoMath.ZeroTolerance (2.3283e-10) and will fail to detect some cylinders. You can use document tolerance (or a custom value if you prefer).

Surface.TryGetCylinder() detects surfaces that are “a portion of a cylinder” so it will return some undesired surfaces (fillets for example). You can eliminate these undesired surfaces by testing with the Surface.IsClosed() method. You’ll also want to use Brep.Faces.ShrinkFaces() before iterating the brep faces to use Surface.TryGetCylinder() otherwise it could still detect some of these undesired surfaces depending on how your geometry was constructed.

To determine if the cylinders face inward or outward:

  • Get a Plane by using the `Surface.FrameAt()’ method
  • Use `Plane.DistanceTo(cylinder.Center)
    • Positive values face inward
    • Negative values face outward

In the code you posted, you use:

Point3d pointOnSurface = face1.PointAt(0.5, 0.5);

You can’t assume that the surface domains are 0 to 1. you should use something like this if you want to evaluate a Point, Normal, or Frame at the surface “midpoint”.

double u = face1.Domain(0).Mid;
double v = face1.Domain(1).Mid;
Point3d pointOnSurface = face1.PointAt(u, v);

Here’s a grasshopper file with a C# script to demonstrate the points I’ve made above:
is_inner.gh (257.1 KB)

-Kevin

2 Likes

Thanks @kev.r the problem is resolved.