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

0 Members and 1 Guest are viewing this topic.

xdcad

  • Swamp Rat
  • Posts: 505
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;
pointAcGe point object
relationAcBr 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. {
  3.   Acad::ErrorStatus es;
  4.   AcBr::ErrorStatus ebr;
  5.   ads_name en;
  6.   ads_point pt;
  7.   if (acedEntSel(_T("\nSelect contour: "), en, pt) != RTNORM)
  8.     return;
  9.   AcDbObjectId eId; acdbGetObjectId(eId,en);
  10.   AcDbObjectPointer<AcDbCurve> pline(eId,AcDb::kForRead) ;
  11.   if ((es = pline.openStatus()) != Acad::eOk) {
  12.     acutPrintf(_T("\npline.openStatus()=%s"),acadErrorStatusText(es));
  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)  {
  21.     acutPrintf(_T("\nAcDbRegion::createFromCurves(ar,regions)=%s"),acadErrorStatusText(es));
  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) {
  28.     acutPrintf(_T("\nbrEnt.set(sol)=%s"),acadErrorStatusText((Acad::ErrorStatus)(Adesk::UInt32)ebr));
  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) {
  39.      acedAlert(_T("In")); return;
  40.    } else if (err == Acad::eOk && pDesc == AcGe::kOnBoundary) {
  41.      acedAlert(_T("On")); return;
  42.    }
  43.    brepFaceTrav.next();
  44.   }
  45.   if (err == Acad::eOk) {
  46.     acedAlert(_T("Out"));
  47.   } else {
  48.     acedAlert(_T("Unknown error"));
  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.     (progn
  4.       (setq brep (xdbr::constructor (setq region (entlast))))
  5.       ;;Construct AcBrBrep object
  6.       (setq tr (xdbr::constructor "brepfacetraverser" brep))
  7.       ;;Build Brep to Face traverser
  8.  
  9.       ;;FACE traversal
  10.       (while (not (xdbr::traverser:done tr))
  11.         ;;The traverser has not reached the end, looping
  12.         (setq face (xdbr::getpropertyvalue tr "face"))
  13.         ;;Get the AcBrFace object at the current traversal position
  14.         (setq relation (xdbr::getpropertyvalue
  15.                          face
  16.                          "PointRelationToFace"
  17.                          pnt
  18.                        )
  19.         )
  20.         ;;Use the PointRelationToFace method to determine the positional relationship between points and faces
  21.         (xdrx_object_release face)
  22.         ;;Release the face object
  23.         (xdbr::traverser:next tr)
  24.         ;;The traverser points to the next face
  25.       )
  26.       (xdrx_entity_delete region)
  27.       ;;Delete temporary REGION
  28.       (xdrx_object_release tr brep)
  29.       ;;Release AcBrBrep object and traverser object
  30.     )
  31.   )
  32.   relation
  33. )
  34.  

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.     (progn
  25.       (xdrx_begin)
  26.       (xdrx_sysvar_push '("osmode" 0))
  27.       (xdrx_pointmonitor "_callback")   ;Enable point monitor
  28.       (getpoint
  29.         "\nMove the mouse and determine the relationship between the current mouse point and the polyline<Exit>:"
  30.       )
  31.       (xdrx_pointmonitor)               ;Close point monitor
  32.       (xdrx_end)
  33.     )
  34.   )
  35.   (princ)
  36. )



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

The above LISP code uses the XDRX-API, which can be downloaded from https://github.com/xdcad/XDrx-API

The XDRX API encapsulates AcDb, AcEd, AcGe, AcBr... C++ library, using C++ methods to develop LISP programs.Thousands of Lisp functions are available.
« Last Edit: November 17, 2023, 04:51:41 AM by xdcad »
The code I wrote uses XDRX-API,which can be downloaded from github.com and is updated at any time.
===================================
https://github.com/xdcad
https://sourceforge.net/projects/xdrx-api-zip/
http://bbs.xdcad.net