Vertices inside closed Brep search speed

Hi,

Got a question if there is a faster way to determine this.
What I want to do is keep the mesh that has the most vertices inside the brep.

I only check every 50 because each mesh has 4k - 5k vertices.
It can also only be 500 - 600. So if I make it less the accuracy of getting the right mesh will be lost.

Dim brep As Geometry.Brep = Brep //Closed Brep

Dim mMesh As Geometry.Mesh = DefaultMesh // Meshlist(0)
Dim mCount As Integer = 0

For Each a As Geometry.Mesh In MeshList //MeshList = list of used meshes
     Dim boolList As New List(Of Boolean)
     Dim c As Integer = a.Vertices.Count / 50
     For i = 0 To c - 1
          Dim r As Boolean = brep.IsPointInside(a.Vertices(i * 50), 1, False)
          If r Then
               boolList.Add(r)
          End If
      Next
      If mCount < boolList.Count Then
          mMesh = a
          mCount = boolList.Count
      End If
Next

So I want to count them faster than only loop throught them 1 by 1… that takes some time.
Anyone got tips? :smiley:

I don’t have a lot of suggestions today. One idea is to get the bounding box of the Brep and then test to see of the points call inside our outside of it. This calculation is very fast and might prune your point list down a little. Then, test the remaining points to see if they are in our out of the Brep…

It may be faster to create a mesh of the Brep and use that for testing of the point is inside. Having said that, you may even do an equivalent of MeshSplit and get the mesh fragment inside. Then you only have to count vertices.

@dale thats an idea to get half of the other points away. After that I can go back to my old method. Count which mesh has the most vertices. That worked for a long time but found out that isnt 100% working.

@menno the problem is that at the moment if I split the mesh and count the verices the wrong mesh will be deleted. Is searching IsPointInside in a mesh faster that inside a brep?

What I mean is this: for each mesh:

  • split it with the mesh of the Brep
  • get the mesh part that is inside the Brep and count its vertices

Then, keep the original mesh of which the splitted mesh part has the largest number of vertices on the inside mesh part.

@menno oh like that. But how do I determine which mesh is inside the mesh of the brep?

I got a closed brep and a mesh. I split the mesh and then I want to keep the mesh inside of the brep. Thats why I was counting the vertices. Is there a method for this? Mesh.IsMeshInside? Because only IsPointInside exists.

If I understand you correctly, you want to keep the mesh that has its naked edge on, or inside the BREP.

Then you could maybe do the following: for one or more naked edge vertices, find the face that it belongs to, and test if the vertices of the face (that are not naked) are inside or outside. Probably, only one of these faces needs to be tested - at the maximum only the faces that are adjacent to the naked edge: much less than all the vertices.


Mesh m = null; // the mesh to test if it is inside
bool[] nakedVertices = m.GetNakedEdgePointStatus();
for (int i = 0; i < nakedVertices.Length; ++i)
{
    if (!nakedVertices[i]) continue;

    int topvi = m.TopologyVertices.TopologyVertexIndex(i);
    int[] faceIndices = m.TopologyVertices.ConnectedFaces(topvi);
    foreach (int fi in faceIndices)
    {
        MeshFace nakedEdgeFace = m.Faces[fi];
        // test if all vertices of this face, except the naked vertices
        // are inside the BREP
    }
}

Ah like that. So you only check the NakedVertices if they are inside or out and skip everything inside.

Something like this.
Just Ignore everything that is inside? (yellow) and only check the nakedvertices ( red)

Yeah, that is what I meant. My code is a bit more complex, because it checks the non-naked vertices of the faces that contain a naked edge. That way you are sure not to have problems with a point that is not entirely inside due to rounding issues.

Oke I got that far. How do I get the vertices of the meshface?

Ah found it… :smiley:

For Each fi As Integer In faceIndices
                        Dim nakedEdgeFace As MeshFace = m.Faces(fi)
                        doc.Objects.AddPoint(m.Vertices(nakedEdgeFace.A))
                        doc.Objects.AddPoint(m.Vertices(nakedEdgeFace.B))
                        doc.Objects.AddPoint(m.Vertices(nakedEdgeFace.C))
                        doc.Objects.AddPoint(m.Vertices(nakedEdgeFace.D))
Next

now I need to remove nakedEdgeVertices and remove double points. Thats it :smiley: Thank you. This should go a lot faster.

Something like this:

Controllist = list of verticesindex
For Each fi As Integer In faceIndices
     Dim nakedEdgeFace As MeshFace = m.Faces(fi)
     If nakedVertices(nakedEdgeFace.A) = False And ControlList.Contains(nakedEdgeFace.A) = False Then
          ControlList.Add(nakedEdgeFace.A)
     End If
     If nakedVertices(nakedEdgeFace.B) = False And ControlList.Contains(nakedEdgeFace.B) = False Then
          ControlList.Add(nakedEdgeFace.B)
     End If
     If nakedVertices(nakedEdgeFace.C) = False And ControlList.Contains(nakedEdgeFace.C) = False Then
          ControlList.Add(nakedEdgeFace.C)
     End If
     If nakedEdgeFace.IsQuad Then
          If nakedVertices(nakedEdgeFace.D) = False And ControlList.Contains(nakedEdgeFace.D) = False Then
               ControlList.Add(nakedEdgeFace.D)
          End If
     End If
Next

And then ControlList is input for the IsPointInside test I presume?

Yes. Then I loop throught the ControlList for IsPointInside :slight_smile: