Checking whether a 2D point lies within a flat surface profile

Checking whether a 2D point lies within a flat surface profile

ksudeadeye
Participant Participant
983 Views
4 Replies
Message 1 of 5

Checking whether a 2D point lies within a flat surface profile

ksudeadeye
Participant
Participant

Hey Guys:

 

I was wondering if there's an easy way to find out if a 2D point lies within a flat surface profile.

 

I've checked the API for SurfaceEvaluator and found a few functions that I thought would help, but based on the descriptions I don't think they'll get me all the way there.

 

isParameterOnFaceDetermines if the specified parameter position lies with the parametric range of the surface.
getParameterAtPointGet the parameter position that correspond to a point on the surface. For reliable results, the point should lie on the surface within model tolerance. If the point does not lie on the surface, the parameter of the nearest point on the surface will generally be returned.

 

getParameterAtPoint() seems to want a point that is already KNOWN to be on the surface, so I don't think that's much use....and isParameterOnFace() wants a param as an input, not a point.

 

Am I missing an easier way to do this. Would it be easier to check whether or not a line crosses a surface, because I can generate the lines to check for that as well..

 

Thanks very much.

-Erik

 

0 Likes
Accepted solutions (1)
984 Views
4 Replies
Replies (4)
Message 2 of 5

marshaltu
Autodesk
Autodesk

Hello,

 

I cannot find API to judge if a point lies within a surface. You can probably work it around by two APIs as below

 

  • getParameterAtPoint - Get the parameter position that correspond to a point on the surface. For reliable results, the point should lie on the surface within model tolerance. If the point does not lie on the surface, the parameter of the nearest point on the surface will generally be returned.
  • getPointAtParameter - Get the point on the surface that correspond to evaluating a parameter position on the surface.

Firstly you could get parameter by the point(#1) you specify. Secondly you could get the corresponding point(#2) on the surface by previous parameter. Then you could compare Point#1 and Point#2 and see if they are equal.

 

The following codes demo that. I am assuming we have a box created on XZ plane and we select the face in the plane. Then we can judge Point1 is not on the face by the approach.

import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        selection = adsk.core.Selection.cast(ui.activeSelections.item(0))
        face = adsk.fusion.BRepFace.cast(selection.entity)
        evaluator = face.evaluator
        
        point1 = adsk.core.Point3D.create(0, 10, 0)
        (res, param1) = evaluator.getParameterAtPoint(point1)
        (res, point2) = evaluator.getPointAtParameter(param1)
        if (point1.isEqualTo(point2)):
            ui.messageBox('Point is on the surface')
        else:
            ui.messageBox('Point is not on the surface')

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

Thanks,

Marshal



Marshal Tu
Fusion Developer
>
Message 3 of 5

ksudeadeye
Participant
Participant
That works. Thanks very much. 🙂
0 Likes
Message 4 of 5

ksudeadeye
Participant
Participant

Marshal:

 

This check is failing on one of my test drawings. I've attached two screenshots and some code. The points I'm trying to check are in the center of each shot. The face is also highlighted. You can see one point is clearly off plane and one is on, but they both pass the check.

 

Any thoughts?

 

Thanks.

-Erik

 

// check the test point to see if it's on the face
bool BoxJoint::isPointOnSurface(const Ptr<Point3D>& testPoint, const Ptr<BRepFace>& plane)
{
    bool isOk = false;
    Ptr<Point3D> planePoint;

    Ptr<SurfaceEvaluator> surfaceEval = plane->evaluator();
    Ptr<Point2D> param;

    isOk = surfaceEval->getParameterAtPoint(testPoint, param);
    if (!isOk) return false;

    isOk = surfaceEval->getPointAtParameter(param, planePoint);
    if (!isOk) return false;

    XTRACE(L"test point : (%lf, %lf, %lf)\n", testPoint->x(), testPoint->y(), testPoint->z());
    XTRACE(L"plane point : (%lf, %lf, %lf)\n", planePoint->x(), planePoint->y(), planePoint->z());

    if (testPoint->isEqualTo(planePoint))
    {
        return true;
    }
    else
    {
        return false;
    }
}

 

on plane
===========
test point : (3.913734, 16.609741, -1.652988)
plane point : (3.913734, 16.609741, -1.652988)

on_plane.png

 

off plane
===========
test point : (5.994380, 18.066625, -1.652988)
plane point : (5.994380, 18.066625, -1.652988)

off_plane.png

0 Likes
Message 5 of 5

ekinsb
Alumni
Alumni
Accepted solution

Here's a slightly modified version of function that I belive should fix the problem.  The problem before is that a planar face is treated as infinite.  I added a call to isParameterOnFace which takes into account the boundaries of the face and checks to see if the point is within the bounded area of the face.

 

bool BoxJoint::isPointOnSurface(const Ptr<Point3D>& testPoint, const Ptr<BRepFace>& plane)
{
    bool isOk = false;
    Ptr<Point3D> planePoint;

    Ptr<SurfaceEvaluator> surfaceEval = plane->evaluator();
    Ptr<Point2D> param;

    isOk = surfaceEval->getParameterAtPoint(testPoint, param);
    if (!isOk) return false;

    isOk = surfaceEval->getPointAtParameter(param, planePoint);
    if (!isOk) return false;

    XTRACE(L"test point : (%lf, %lf, %lf)\n", testPoint->x(), testPoint->y(), testPoint->z());
    XTRACE(L"plane point : (%lf, %lf, %lf)\n", planePoint->x(), planePoint->y(), planePoint->z());

    if (testPoint->isEqualTo(planePoint))
    {
		if (surfaceEval->isParameterOnFace(param))
		{
			return true;
		}
		else
		{
			return false;
		}
    }
    else
    {
        return false;
    }
}

Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog