IsPointInside is generating unexpected results - C#

Dear forum,
I have a problem with Brep.IsPointInside that I cannot solve on my own. I am checking if the points in a list of three lies within a closed Brep and it tells me that two points are inside and one point is outside the Brep, but in reality is the oposite. The Brep that I am checking with is generated in a C# component one step earlier and interestingly enough, when I first bake that Brep and referece it back to GH, Brep.IsPointInside generates the correct results.

This is giving the two points that are actually lying outside the closed brep.

Whereas when I first bake and reference the closed brep, it gives the correct result

To me it seams like there is something fuzzy going on with the brep, but I can’t figure it out. Could someone please help me troubleshoot this problem?

Thanks,
David

Can you post your Grasshopper file with a minimum reproducable example, this will help finding out what is going on.

Hi @menno, yes, off course. Attached you’ll find the file.

IsPointInside-problem.gh (38.8 KB)

Because your brep is flipped inside out.

2023-08-03 13_32_13-Grasshopper - IsPointInside-problem_
Negative volume…

IsPointInside is doing its work “correctly”.

In your previous c# script, the method Brep.CreateOffsetBrep is returning you a flipped out brep. That is the problem.
In this cases, if you expect the brep to be closed and you are not sure if the solid is “positive” or “negative”, do a .Flip() ; if the brep is already ok, nothing will happens, if the brep is negative, it will be corrected.

In your previous c# script, add a “solid.Flip();” at line 90.


3 Likes

Instead of the blind date way always use this:

2 Likes

Thank you @maje90 and @PeterFotiadis for your replys, that one I would’ve never found myself. But why is that, why is it generating a negative volume? If I use any of your suggested methods, would that be a work around or is that a common workflow?

Cheers,
david

Because of how you designed that brep.
Drawing a line right to left is not the same of drawing a line left to right. It have an orientation.

Follow Peter’s suggestion, use BrepSolidOrientation.

If(brep.orientation==inward){
brep.Flip();
}

… or something similar…

But @maje90, this still feels like a work around. It would be better to just define the solid correctly to begin with. What am I doing wrong in my first code?

It’s not your fault, david.

@dale

Apparently Brep.CreateOffsetBrep always return a negative volume…
(Also in WIP, it seems)

Well … given the fact that any real-life C# worth the name may contain dozens of lines (and Methods) … one more is nothing (plus: better safe than sorry).

That said the lines required for checking the validity of your input … blah, blah

2 Likes

Apparently Brep.CreateOffsetBrep always return a negative volume…

Ah really, well then I’m happy with the “work around”. And @PeterFotiadis I get your point, better safe than sorry indeed.

Problem solved, thanks!

However now I have troubles implementing the solution in my code. I tried the following code

If(brep.SolidOrientation==-1){
     brep.Flip();
}

which does not work and generates the following error message

Error (CS0019): Operator ‘==’ cannot be applied to operands of type ‘Rhino.Geometry.BrepSolidOrientation’ and ‘int’ (line 93)

However, I made it work like this

If(brep.SolidOrientation < 0)

which to me seams strange, now it suddenly works with integers. Is there a logic here that I am missing, could you please explain this @maje90 @PeterFotiadis ?

thanks!

SO is an Enum:

Anyway … use something like this in a check Method

public void Check(ref List<Brep> bList){
    for(int i = 0; i < bList.Count;i++){
      Brep brep = bList[i];
      if(brep == null || !brep.IsValid || !brep.IsSolid) continue; // or do a LINQ When checking input
      if(brep.SolidOrientation.Equals(-1)) {brep.Flip(); bList[i] = brep; Print("brep at: {0} flipped", i); }      
      
      // .....
    }
}

Or

 for(int i = 0; i < bList.Count;i++){
      Brep brep = bList[i];
      if(brep == null || !brep.IsValid || !brep.IsSolid) continue; // or do a LINQ When checking input     
      if(brep.SolidOrientation == BrepSolidOrientation.Inward) {brep.Flip(); bList[i] = brep; Print("brep at: {0} flipped", i); }

      // .....
    }

1 Like

ok, got it. I’ll need to read up on Enum, thanks a lot!

sorry @PeterFotiadis but when I have you on the line I have one more question.
I understand what the line

if(brep == null || !brep.IsValid || !brep.IsSolid) continue;

is doing. But can you please explain why it is important? If I would feed a curve and not a brep, it will anyways not work, why is it important to include a check like this?

Thanks for your patiance

Always check your input … most notably if there’s several C#'s/Methods around (Real-life: meaning …output from one/some is input to an other).

Obviously check(s) are related with the Type expected: so if we are talking, say, GeometryBase (see SDK for the supported Types) … ask more questions and act accodringly. (i.e. if this is Curve > …, if that is Brep > … , if is a Mesh > …) .

Tip: NEVER assume that your input is correct/valid. As we say in motorcycle racing: if you fail to prepare prepare to fail.

Screen Shot 080

So given some GB input List named, say, geomList:

geomList = geomList.Where(x=>IsValid(x)).ToList();
if(!geomList.Any()) {Print(“Wrong geomList: adios amigos”); return;}

where IsValid is a Method of Type bool that does … well … the questions.

3 Likes

thank you @PeterFotiadis