tpaviot / pythonocc-core

Python package for 3D geometry CAD/BIM/CAM
GNU Lesser General Public License v3.0
1.39k stars 380 forks source link

How to check if the curve is inside the model? #1346

Closed DanielYipHoi closed 1 week ago

DanielYipHoi commented 4 months ago

I now have a curve of type ais_shape and a TopoDS_Shape

But when I try to use BRepAlgoAPI_Section to verify if the curve is inside the model, the program does not seem to recognize the model as a solid body

The verification result returned is that all data do not intersect

It seems that BRepAlgoAPI_Section can only determine the intersection of the curve and the edge, point, and surface of the model surface, but cannot determine the situation like a curve suspended in a sphere and not in contact with the surface

In this case, how should I judge the test data?

DanielYipHoi commented 4 months ago

One more note, I can see from the viewer that some curves are inside the model, and I can use simple math to know that there are 20 curve data, but only 8 sets of data are outside the model, but when using BRepAlgoAPI_Section to detect intersections, these data are not filtered correctly. Is there a way in the OCC lib to treat the model as a solid geometric body and then perform intersection detection? Because if it is a solid body, even if the curve is inside the model and does not touch the model surface, it will be considered to have an intersection.

Bill-XU commented 1 week ago

There is a page explaining how OCCT evaluates intersection. https://dev.opencascade.org/doc/overview/html/occt_user_guides__modeling_algos.html#occt_modalg_2_2 I have an idea, after performing "the intersection between a 3D curve and a surface;", then checking which side of the surface that the curve is on if they do not intersect will do the work.

tpaviot commented 1 week ago

Use the BRepClass3d_Classifier to check if each point of the curve is inside the solid.

from OCC.Core.BRepClass3d import BRepClass3d_SolidClassifier
from OCC.Core.gp import gp_Pnt
from OCC.Core.TopAbs import TopAbs_IN, TopAbs_OUT, TopAbs_ON
from OCC.Core.BRep import BRep_Tool

def is_curve_inside_solid(curve, solid):
   """ Return True if the curve is inside the solid, False if not """
    # Get some points along the curve for testing
    curve_adaptor = BRepAdaptor_Curve(curve)
    u_start = curve_adaptor.FirstParameter()
    u_end = curve_adaptor.LastParameter()

    # Create classifier
    classifier = BRepClass3d_SolidClassifier(solid)

    # Sample several points along the curve
    num_samples = 10
    points_inside = 0

    for i in range(num_samples):
        # Get parameter at current sample
        u = u_start + (u_end - u_start) * i / (num_samples - 1)
        point = curve_adaptor.Value(u)

        # Classify point
        classifier.Perform(point, 1e-7)  # 1e-7 is the tolerance

        state = classifier.State()

        if state == TopAbs_OUT:
            return False
   return True