Author Topic: [AcBr(5)]Determine the positional relationship between points and closed curves  (Read 855 times)

0 Members and 1 Guest are viewing this topic.

• Bull Frog
• Posts: 424
[AcBr(5)]Determine the positional relationship between points and closed curves
« on: November 17, 2023, 04:35:32 AM »
ARX can determine the positional relationship between the point and AcBrFace through the AcBr API.

AcBrFace::getPointRelationToFace Function
AcBr::ErrorStatus
getPointRelationToFace(
const AcGePoint3d& point,
AcBr::Relation& relation) const;
 point AcGe point object relation AcBr relation enum

AcBr::Relation Enum
These are the ErrorStatus enumerated values used by getPointRelationToXXX() and getCurveRelationToXXX() functions. These enumerated types and the functions that use them are deprecated in favor of the newer getPointContainment() and getLineContainment() functions, along with the new AcGe::PointContainment enumerated type.
Relation.

The following is the ARX implementation code:

Code - C++: [Select]
1. static void BrepPointCheckPoint(void)
2. {
4.   AcBr::ErrorStatus ebr;
7.   if (acedEntSel(_T("\nSelect contour: "), en, pt) != RTNORM)
8.     return;
9.   AcDbObjectId eId; acdbGetObjectId(eId,en);
11.   if ((es = pline.openStatus()) != Acad::eOk) {
13.     return;
14.   }
15.   if (acedGetPoint(pt,_T("\nPick point: "), pt) != RTNORM)
16.     return;
17.
18.   AcDbVoidPtrArray ar, regions;
19.   ar.append(pline.object());
20.   if ((es = AcDbRegion::createFromCurves(ar,regions)) != Acad::eOk)  {
22.     return;
23.   }
24.   AcDbRegion reg; reg.copyFrom((AcDbRegion *)regions[0]);
25.   for (int i=0; i<regions.length();i++) delete regions[i];
26.   AcBrBrep brEnt;  ebr = brEnt.set(reg);
27.   if (ebr != AcBr::eOk) {
29.     return;
30.   }
31.   AcGe::PointContainment pDesc;
32.   AcBrEntity *pCont = NULL;
33.   AcBrBrepFaceTraverser brepFaceTrav; brepFaceTrav.setBrep(brEnt);
34.   AcBr::ErrorStatus err = AcBr::eInvalidInput;
35.   while (!brepFaceTrav.done()) {
36.    AcBrFace brFace; brepFaceTrav.getFace(brFace);
37.    err = brFace.getPointContainment(asPnt3d(pt),pDesc,pCont);
38.    if (err == Acad::eOk && pDesc == AcGe::kInside) {
40.    } else if (err == Acad::eOk && pDesc == AcGe::kOnBoundary) {
42.    }
43.    brepFaceTrav.next();
44.   }
45.   if (err == Acad::eOk) {
47.   } else {
49.   }
50.   return;
51. }

Below we use the AcBr library function encapsulated by the XDRX API to translate the above ARX code to LISP:

Define a function _isPtInPoly
Parameters: pl ---- closed curve
pnt ---- test point

Return value: 1: outside, 2: inside, 3, on the boundary

Code - Auto/Visual Lisp: [Select]
1. (defun _isPtInPoly (pl pnt / ss brep tr face region relation)
2.   (if (setq ss (xdrx_region_make pl t)) ;PL generates REGION
3.       (setq brep (xdbr::constructor (setq region (entlast))))
4.       ;;Construct AcBrBrep object
5.       (setq tr (xdbr::constructor "brepfacetraverser" brep))
6.       ;;Build Brep to Face traverser
7.
8.       ;;FACE traversal
9.       (while (not (xdbr::traverser:done tr))
10.         ;;The traverser has not reached the end, looping
11.         (setq face (xdbr::getpropertyvalue tr "face"))
12.         ;;Get the AcBrFace object at the current traversal position
13.         (setq relation (xdbr::getpropertyvalue
14.                          face
15.                          "PointRelationToFace"
16.                          pnt
17.                        )
18.         )
19.         ;;Use the PointRelationToFace method to determine the positional relationship between points and faces
20.         (xdrx_object_release face)
21.         ;;Release the face object
22.         (xdbr::traverser:next tr)
23.         ;;The traverser points to the next face
24.       )
25.       (xdrx_entity_delete region)
26.       ;;Delete temporary REGION
27.       (xdrx_object_release tr brep)
28.       ;;Release AcBrBrep object and traverser object
29.     )
30.   )
31.   relation
32. )
33.

The following is a point monitor used to test the positional relationship between the mouse point and the closed curve, and print it to the screen.

Code - Auto/Visual Lisp: [Select]
1. (defun c:tt ()
2.   (defun _callback (dynpt / str)        ; point monitor callback function
3.     (if (not (setq testpnt (osnap dynpt "nea")))
4.       (setq testpnt dynpt)
5.     )
6.     (setq relation (_isPtInPoly crv testpnt))
7.                                         ; The callback function internally calls the point position judgment function _isPtInPoly
8.     (cond ((= relation XD:kInside)
9.            (setq str "The current mouse is inside the polyline!")
10.           )
11.           ((= relation XD:kBoundary)
12.            (setq str "The current mouse is on the polyline!")
13.           )
14.           (t (setq str "The current mouse is outside the polyline!"))
15.     )
16.     str
17.   )
18.   (if (setq crv (car (xdrx_entsel
19.                        "\nPick closed polyline<Exit>:"
20.                        '((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1))
21.                      )
22.                 )
23.       )
24.       (xdrx_begin)
25.       (xdrx_sysvar_push '("osmode" 0))
26.       (xdrx_pointmonitor "_callback")   ;Enable point monitor
27.         "\nMove the mouse and determine the relationship between the current mouse point and the polyline<Exit>:"
28.       )
29.       (xdrx_pointmonitor)               ;Close point monitor
30.       (xdrx_end)
31.     )
32.   )
33.   (princ)
34. )

=============