Author Topic: Let LISP use the ARX AcBr library(1)-Find the intersection of Line and 3DSOLID  (Read 1625 times)

0 Members and 2 Guests are viewing this topic.

xdcad

  • Swamp Rat
  • Posts: 514
Find the intersection of Line and 3DSOLID



Background:

Surface: AcDbSurface
Entity: 3DSOLID

ARX offers AcGeCurveSurfInt, which allows you to get the intersection of 3D curves and surfaces. The AcGeCurveSurfInt construction method or AcGeCurveSurfInt ::Set allows you to import curves and surfaces. It requires AcGeSurface, so we need to convert from AcDbSurface to AcGeSurface. This requires AcBrBrip as an intermediate object.

The ARX implementation code is as follows:

Code - C++: [Select]
  1. static AcGePoint3dArray Intersect(AcDbSurface* pSurface, AcGeLine3d line)
  2. {
  3.         AcGePoint3dArray returnPtArray;
  4.         AcDbBody* pBody = new AcDbBody();
  5.  
  6.         // 2013
  7.         // Acad::ErrorStatus es = pBody->setASMBody(pSurface->ASMBodyCopy());
  8.         //before 20123
  9.         Acad::ErrorStatus es = pBody->setBody(pSurface->body());
  10.  
  11.         //build AcBrBrep
  12.         AcBrBrep* pBrep = new AcBrBrep();
  13.         //
  14.         if (AcBr::eOk == pBrep->set(*pBody))
  15.         {
  16.                 AcBrBrepFaceTraverser* pFaceTrav = new AcBrBrepFaceTraverser;
  17.                 if (AcBr::eOk == pFaceTrav->setBrep(*pBrep))
  18.                 {
  19.                         for (pFaceTrav->restart(); !pFaceTrav->done(); pFaceTrav->next())
  20.                         {
  21.                                 AcBrFace face;
  22.  
  23.                                 if (AcBr::eOk == pFaceTrav->getFace(face))
  24.                                 {
  25.                                         double area = 0.0f;
  26.                                         face.getSurfaceArea(area);
  27.  
  28.                                         acutPrintf(L"\nSurface Area: %f", area);
  29.  
  30.                                         //*****whole surface of the Brep face******        
  31.                                         //AcGeNurbSurface nurbSurface;
  32.                                         //face.getSurfaceAsNurb(nurbSurface);
  33.                                         //AcGeCurveSurfInt curveSI;
  34.                                         ////input the curve and line
  35.                                         //curveSI.set(line,nurbSurface);
  36.                                         ////get the count of intersect points
  37.                                         //int count = curveSI.numIntPoints(err_1);
  38.                                         //    if(err_1 == AcGe::kXXOk && count >0 )
  39.                                         //    {      
  40.                                         //        AcGeIntersectError err_2;
  41.                                         //        for(int index = 0 ;index < count; index ++)
  42.                                         //        {
  43.                                         //           AcGePoint3d pt =
  44.                                         //             curveSI.intPoint(index,err_2);      
  45.                                         //            returnPtArray.append(pt);
  46.                                         //        }      
  47.                                         //      
  48.                                         //    }
  49.                                         //**********
  50.  
  51.                                         //****real surface of the orignal AcDbSurface      
  52.                                         AcGeExternalBoundedSurface** nurbs = NULL;
  53.                                         Adesk::UInt32 numNurbs = 0;
  54.                                         face.getSurfaceAsTrimmedNurbs(numNurbs, nurbs);
  55.                                         //*****
  56.  
  57.                                         for (Adesk::UInt32 i = 0; i < numNurbs; i++)
  58.                                         {
  59.                                                 AcGeCurveSurfInt curveSI;
  60.                                                 AcGeIntersectError  err_1 = AcGe::kXXOk;
  61.                                                 //input the curve and line
  62.                                                 curveSI.set(line, *nurbs[i]);
  63.  
  64.                                                 //get the count of intersect points
  65.                                                 int count = curveSI.numIntPoints(err_1);
  66.                                                 if (err_1 == AcGe::kXXOk && count > 0)
  67.                                                 {
  68.                                                         AcGeIntersectError err_2;
  69.                                                         for (int index = 0; index < count; index++)
  70.                                                         {
  71.                                                                 AcGePoint3d pt =
  72.                                                                         curveSI.intPoint(index, err_2);
  73.                                                                 returnPtArray.append(pt);
  74.                                                         }
  75.                                                 }
  76.                                                 delete nurbs[i];
  77.                                         }
  78.                                         // your responsibility to delete the
  79.                                         // array of surfaces
  80.                                         delete[] nurbs;
  81.                                 }
  82.                         }
  83.                 }
  84.                 delete pFaceTrav;
  85.         }
  86.         delete pBrep;
  87.         return returnPtArray;
  88. }
  89. static void getIntersectPts(void)
  90. {
  91.         ads_name ename;
  92.         ads_point pickpt;
  93.         AcDbObjectId objId;
  94.         AcDbObject* pObj;
  95.  
  96.         int rc;
  97.         // select a surface
  98.         rc = acedEntSel(L"\nSelect Surface: ", ename, pickpt);
  99.         if (rc != RTNORM)
  100.         {
  101.                 if (rc != RTCAN)
  102.                         acutPrintf(L"\nError selecting entity ");
  103.                 return;
  104.         }
  105.         acdbGetObjectId(objId, ename);
  106.         acdbOpenObject(pObj, objId, AcDb::kForRead);
  107.         AcDbSurface* pEntity1 = AcDbSurface::cast(pObj);
  108.         if (!pEntity1)
  109.         {
  110.                 acutPrintf(L"\nSelection Invalid...");
  111.                 pObj->close();
  112.                 return;
  113.         }
  114.         // call Intersect
  115.         AcGePoint3dArray points =
  116.                 Intersect(pEntity1, AcGeLine3d(AcGePoint3d(0, 0, 0),
  117.                         AcGePoint3d(0, 0, 1)));
  118.         if (points.length() > 0)
  119.         {
  120.                 // iterate the points
  121.         }
  122.         pObj->close();
  123. }


Here's the LISP code for the ACBR library function of the XDRX API to implement the above ARX functionality:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:tt ()
  2.   (defun _traversface (e ln)
  3.     (setq gln (xdge::constructor ln))
  4.     ;;Construct a straight line geometric object AcGeLineSeg3d
  5.     (setq body (xdrx_body_make))
  6.     ;;Create a memory AcDbBody object
  7.     (xdrx_set_body body e)
  8.     ;;Set the model data of the selected surface or 3DSOLID object to the BODY object
  9.     (setq br (xdbr::constructor body))
  10.     ;;Create AcBrBrep from BODY
  11.     (setq tr (xdbr::constructor "brepfacetraverser" br))
  12.     ;;Build Brep->Face traverser
  13.     ;;FACE traversal
  14.     (setq i    0
  15.           ints nil
  16.     )
  17.     (while (not (xdbr::traverser:done tr))
  18.       (if (setq face (xdbr::getpropertyvalue tr "face"))
  19.         ;;Get AcBrFace at the current traversal position
  20.         (progn
  21.           (setq gface
  22.                  (xdbr::getpropertyvalue face "SurfaceAsTrimmedNurbs")
  23.           )
  24.           ;;AcBrFace->SurfaceAsTrimmedNurbsGeometric object
  25.           (setq j -1)
  26.           (repeat (length gface)
  27.             (setq gface1 (nth (setq j (1+ j)) gface))
  28.             (setq
  29.               mInt (xdge::constructor "kCurveSurfaceInt" gln gface1)
  30.             )
  31.             ;;Construct curve and surface intersection kCurveSurfaceInt object
  32.             (if (> (xdge::getpropertyvalue mint "numintpoints") 0)
  33.               ;;The number of intersection points is greater than 0
  34.               (progn
  35.                 (setq ar (xdbr::getpropertyvalue face "area"))
  36.                 (xdrx_prompt
  37.                   (xdrx_string_format
  38.                     "\nIntersection found, Surface[%d] Area: %f"
  39.                     (setq i (1+ i))
  40.                     ar
  41.                   )
  42.                 )
  43.                 (setq
  44.                   ints (cons (xdge::getpropertyvalue mint "intpoints")
  45.                              ints
  46.                        )
  47.                 )
  48.                 ;;Save the intersection point to a global variable
  49.               )
  50.             )
  51.           )
  52.           (xdrx_object_release face)
  53.         )
  54.       )
  55.       (xdbr::traverser:next tr)
  56.     )
  57.     (xdrx_setvar "pdmode" 35)
  58.     (xdrx_entity_setcolor (xdrx_point_make ints) 2)
  59.     (xdrx_object_release tr br body)
  60.   )
  61.   (if
  62.     (and
  63.       (setq e (car (xdrx_entsel
  64.                      "\nSelect Surface,3DSOLID<Exit>:"
  65.                      '((0 . "SURFACE,3DSOLID"))
  66.                    )
  67.               )
  68.       )
  69.       (setq
  70.         ln (car (xdrx_entsel "\nSelect Line<Exit>:" '((0 . "LINE"))))
  71.       )
  72.     )
  73.      (progn
  74.        (xdrx_begin)
  75.        (_traversface e ln)
  76.        (xdrx_end)
  77.      )
  78.   )
  79.   (princ)
  80. )

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 15, 2023, 12:20:01 PM 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

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8825
  • AKA Daniel
Nice work! Wrapping C++ for lisp is not an easy task!

domenicomaria

  • Swamp Rat
  • Posts: 725
I downloaded the 4 rar files, extracted the contents and obtained the file XDRX-API-2023-11-15.exe
...
then I double clicked on the file name and got an error message in Chinese!
...
Can someone translate?

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8825
  • AKA Daniel
google says this

domenicomaria

  • Swamp Rat
  • Posts: 725
however,
what could be very very useful for implementing VLisp,
is a C++ wrapping, OPEN SOURCE...
...
and "TheSwamp" could be the right place with the right people
to carry out such a project...

xdcad

  • Swamp Rat
  • Posts: 514
google says this
Sorry,The file was damaged when uploaded. have re-upload it. Please re-download it.
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

xdcad

  • Swamp Rat
  • Posts: 514
I downloaded the 4 rar files, extracted the contents and obtained the file XDRX-API-2023-11-15.exe
...
then I double clicked on the file name and got an error message in Chinese!
...
Can someone translate?

Sorry,The file was damaged when uploaded. have re-upload it. Please re-download it.
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

domenicomaria

  • Swamp Rat
  • Posts: 725
Yes.
I downloaded the RAR files again and installed the software...
And I end up with 2175 new features !
It seems interesting ...

Code - Auto/Visual Lisp: [Select]
  1. (acad_strlsort
  2.    (vl-remove nil
  3.               (mapcar '(lambda (i) (if (wcmatch i "XDRX-*") i nil))
  4.                       (atoms-family 1)
  5.               )
  6.    )
  7. )

« Last Edit: November 16, 2023, 04:50:44 AM by domenicomaria »

domenicomaria

  • Swamp Rat
  • Posts: 725
Code - Auto/Visual Lisp: [Select]
  1. (acad_strlsort
  2.    (vl-remove nil
  3.               (mapcar '(lambda (i) (if (wcmatch i "XD*") i nil))
  4.                       (atoms-family 1)
  5.               )
  6.    )
  7. )

while the FULL LIST is contained in the attached txt file.

5702 new functions (and constants) ! ! !
« Last Edit: November 16, 2023, 08:06:04 AM by domenicomaria »

xdcad

  • Swamp Rat
  • Posts: 514
Thank you, more than 5000 functions, all-inclusive
There are 2 functions in it
xdrx-getpropertyvalue: Contains C++ methods for querying all objects
xdrx-setpropertyvalue: Contains C++ methods for editing all objects

For example:
Code: [Select]
Create MPolygon entity:
(xdrx-mpolygon-make (car (xdrx-entsel "\nPick up closed POLY lines:" '((0 . "*polyline")))))

Code: [Select]
Query the area, length, and number of boundary LOOPs of the MPolygon entity:

(xdrx-getpropertyvalue (entlast) "area" "length" "numloops")
(273809.0 2401.56 1)

For MPOLYGON objects, parameters are only given to entities, and supported methods can be queried.

命令: (xdrx-getpropertyvalue (entlast))
Class AcDbMPolygon:
    ├─Area (None or Int)
    ├─OverLapLoops([T])
    ├─HasChildLoop([T])
    ├─ChildLoops(ParentLoop [T])
    ├─ClosestLoopTo / LoopIndexAt (Int or Point)
    ├─Detach
    ├─DetachLoopAt (Point or Int)
    ├─Elevation
    ├─ExtractLoopAt (Point or Int)
    ├─IsBalanced
    ├─LoopAtGsMarker
    ├─LoopDirection
    ├─MPolygonLoopAt (Int or Point)
    ├─GetLoopAt / LoopAt (Int or Point)
    ├─GetLoopsAt
    ├─GetLoops (None or T)
    ├─MPolygonLoops (None or T)
    ├─OffsetVector
    ├─ParentLoop
    ├─PatternDefinitionAt
    ├─Perimeter
    ├─Length
    ├─Normal
    ├─NumMPolygonLoops
    ├─NumLoops
    ├─NumPatternDefinitions
    ├─IncludesTouchingLoops
    ├─IsPointInsideMPolygon
    ├─IsPointOnLoopBoundary
    ├─SelfCrosses
    ├─PatternAngle
    ├─patternColor
    ├─PatternScale
    ├─PatternDouble
    ├─PatternSpace
    ├─PatternName
    ├─PatternType
    ├─Perimeter
    ├─RootLoop / RootLoopAt (Int or Point)
    ├─RootLoopIndexAt / RootLoopIndex (Int or Point)
    ├─RootLoops
Class AcDbEntity:
    ├─9PT
    ├─BoundingBox
    ├─Color (None or T[real color])
    ├─ColorIndex(None or T)
    ├─Centroid
    ├─ECS
    ├─Elevation
    ├─Ename
    ├─GeomExtents
    ├─ GripPoints
    ├─IsMemoryEntity
    ├─Layer(None or T or NIL)
    ├─Layout
    ├─Linetype(None or T or NIL)
    ├─LinetypeScale
    ├─LineWeight
    ├─OrthoProject(Plane  T)
    ├─Project(Plane Normal T)
    ├─PersistentReactor
    ├─Plane
    ├─PlotStyleName
    ├─StretchPoint
    ├─Transparency
    ├─Visibility
    ├─XDir
Class AcDbObject:
    ├─ClassName
    ├─OriginalDatabase
    ├─Database
    ├─ExtensionDictionary
    ├─FieldDictionary
    ├─IsA
    ├─IsAProxy
    ├─IsErased
    ├─IsReallyClosing
    ├─Handle
    ├─HasFields
    ├─HasPersistentReactor
    ├─MyParent
    ├─ObjectID
    ├─Owner
    ├─xData

For example:
Code: [Select]
(setq loop (xdrx-getpropertyvalue (entlast) "getloops"))
(<图元名: 2a18bcc51d0>)

Get LOOPS of MPOLYGON, AcGe Object.

Code: [Select]
命令: (xdrx-object-type (car loop))
"AcGe::kCompositeCrv3d"

命令: (xdrx-object-isa (car loop))
"AcGe::kCompositeCrv3d"

Only give entity parameters and query the methods supported by AcGe.

命令: (xdrx-getpropertyvalue (car loop))

------       Geom Entity Method       ------
<kCompositeCrv3d>:
   Edit Functions:
        ├───setCurveList
   Query Functions:
        ├───getCurveList
        ├───getCurveList
        ├───Vertices
        ├───Bulges
        ├───LineSegAt
        ├───ArcSegAt
        ├───PointAt
        ├───BulgeAt
        ├───isOnlyLines
        ├───isOnlyArcs
        ├───hasBulges
        ├───OnSegAt
        ├───ToBox
        ├───NumVerts
        ├───globalToLocalParam
        ├───localToGlobalParam
<kCurve3d>:
   Bounding Box Functions:
        ├───boundBlock
        ├───orthoBoundBlock
   Closest Point Functions:
        ├───closestPointTo
        ├───projClosestPointTo
   Degeneracy Functions:
        ├───isDegenerate
   Distance Functions:
        ├───distanceTo
   Edit Functions:
        ├───setInterval
   Evaluation Functions:
        ├───evalPoint
   Geometric Inquiry Functions:
        ├───hasEndPoint
        ├───hasStartPoint
        ├───isClosed
        ├───isCoplannarWith
        ├───isLinear
        ├───isPeriodic
        ├───isPlannar
   Length Functions:
        ├───divide
        ├───area
        ├───areaOf
        ├───length
        ├───paramAtLength
        ├───porintAtLength
   Parameterization Functions:
        ├───paramOf
        ├───reverseParam
   Point Containment Functions:
        ├───isOn
        ├───orthoProject
        ├───project
   Query Functions:
        ├───startParam
        ├───endParam
        ├───firstdeiv
        ├───firstderiv-
        ├───secondDeriv
        ├───secondDeriv-
        ├───getClosestPointTo
        ├───getInterval
        ├───getLocalClosestPoints
        ├───getNormalPoint
        ├───getProjClosestPointTo
        ├───getSamplePoints
        ├───getSplitCurves
        ├───getTrimmedOffset
   Subdivide Functions:
        ├───explode
<kEntity3d>:
   Equality Checking Functions:
        ├───isEqualTo
   Point Containment Functions:
        ├───isOn
   Type Identification Functions:
        ├───isKindOf
        ├───type
------       DB Entity Method       ------
Class AcDbPolyline:
    ├─ToBox
    ├─AllInnerAngles
    ├─AllOuterAngles
    ├─Angle
    ├─AngularLineVector
    ├─AllSegs
    ├─SegAt
    ├─ArcSegs
    ├─ArcSegAt
    ├─ArcSegIndex
    ├─LineSegIndex
    ├─BulgeAt
    ├─Bulges
    ├─Elevation
    ├─ConstantWidth
    ├─PerpLine (Int and T)
    ├─Direction
    ├─Get
    ├─LineSegAt
    ├─Length
    ├─Lengths
    ├─HasBulges
    ├─HasPlinegen
    ├─HasWidth
    ├─InAngle
    ├─IsSelfCrossting
    ├─isInnerAngle
    ├─isOuterAngle
    ├─IsOnlyLines
    ├─NearIndex
    ├─Normal
    ├─NumVerts
    ├─OnSegAt
    ├─PointAt
    ├─PrevNextIndex
    ├─-Index+
    ├─SegType
    ├─SelfIntPoints
    ├─SelfIntParams
    ├─Thickness
    ├─Vertices
    ├─FeaturePoints
    ├─WidthsAt
    ├─StartWidth
    ├─EndWidth
    ├─OutLine (NULL or Index or (Index and (Int or Real))
Class AcDbCurve:
    ├─Area
    ├─Centroid
    ├─DistanceTo
    ├─Divide
    ├─Direction
    ├─EndParam
    ├─EndPoint
    ├─GetClosestEnt
    ├─GetClosestPointTo
    ├─GetFirstDeriv
    ├─GetFirstDeriv-
    ├─GetSecondDeriv
    ├─GetSecondDeriv-
    ├─GetPointAtParam
    ├─GetPointAtDist
    ├─GetPointsAtDist
    ├─GetPointsAtDists
    ├─GetParamAtPoint
    ├─GetParamAtDist
    ├─GetDistAtPoint
    ├─GetDistAtParam
    ├─GetSamplePoints
    ├─IsClosed
    ├─IsOn
    ├─IsPeriodic
    ├─MidPoint
    ├─PerpLine
    ├─StartPoint
    ├─StartParam
    ├─Length
Class AcDbEntity:
    ├─9PT
    ├─BoundingBox
    ├─Color (None or T[real color])
    ├─ColorIndex(None or T)
    ├─Centroid
    ├─ECS
    ├─Elevation
    ├─Ename
    ├─GeomExtents
    ├─ GripPoints
    ├─IsMemoryEntity
    ├─Layer(None or T or NIL)
    ├─Layout
    ├─Linetype(None or T or NIL)
    ├─LinetypeScale
    ├─LineWeight
    ├─OrthoProject(Plane  T)
    ├─Project(Plane Normal T)
    ├─PersistentReactor
    ├─Plane
    ├─PlotStyleName
    ├─StretchPoint
    ├─Transparency
    ├─Visibility
    ├─XDir
Class AcDbObject:
    ├─ClassName
    ├─OriginalDatabase
    ├─Database
    ├─ExtensionDictionary
    ├─FieldDictionary
    ├─IsA
    ├─IsAProxy
    ├─IsErased
    ├─IsReallyClosing
    ├─Handle
    ├─HasFields
    ├─HasPersistentReactor
    ├─MyParent
    ├─ObjectID
    ├─Owner
    ├─xData
« Last Edit: November 16, 2023, 08:44:42 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

domenicomaria

  • Swamp Rat
  • Posts: 725
Code - Auto/Visual Lisp: [Select]
  1. (setq atoms-family-lst
  2.    (acad_strlsort
  3.       (vl-remove nil
  4.                  (mapcar '(lambda (i)
  5.                              (if   (wcmatch i "XD*")
  6.                                 i
  7.                                 nil
  8.                              )
  9.                           )
  10.                           (atoms-family 1)
  11.                  )
  12.       )
  13.    )
  14. )
  15.  
  16. (setq atoms-type-name-lst (mapcar '(lambda (i) (list (type (eval (read i ) ) ) i) ) atoms-family-lst) )
  17.  
  18. (setq int-lst       (vl-remove-if '(lambda (i) (/= (car i) 'INT       ) ) atoms-type-name-lst) )
  19.  
  20.  
  21. (setq subr-lst      (vl-remove-if '(lambda (i) (/= (car i) 'SUBR      ) ) atoms-type-name-lst) )
  22.  
  23.  
  24. (setq exrxsubr-lst  (vl-remove-if '(lambda (i) (/= (car i) 'EXRXSUBR ) ) atoms-type-name-lst) )
  25.  
  26.  
  27.    (strcat
  28.       "\n\n int-lst length      : " (itoa (length int-lst     ) )
  29.       "\n\n subr-lst length     : " (itoa (length subr-lst    ) )
  30.       "\n\n exrxsubr-lst length : " (itoa (length exrxsubr-lst) )
  31.    )
  32. )

xdcad

  • Swamp Rat
  • Posts: 514
Code - Auto/Visual Lisp: [Select]
  1. (setq atoms-family-lst
  2.    (acad_strlsort
  3.       (vl-remove nil
  4.                  (mapcar '(lambda (i)
  5.                              (if   (wcmatch i "XD*")
  6.                                 i
  7.                                 nil
  8.                              )
  9.                           )
  10.                           (atoms-family 1)
  11.                  )
  12.       )
  13.    )
  14. )
  15.  
  16. (setq atoms-type-name-lst (mapcar '(lambda (i) (list (type (eval (read i ) ) ) i) ) atoms-family-lst) )
  17.  
  18. (setq int-lst       (vl-remove-if '(lambda (i) (/= (car i) 'INT       ) ) atoms-type-name-lst) )
  19.  
  20.  
  21. (setq subr-lst      (vl-remove-if '(lambda (i) (/= (car i) 'SUBR      ) ) atoms-type-name-lst) )
  22.  
  23.  
  24. (setq exrxsubr-lst  (vl-remove-if '(lambda (i) (/= (car i) 'EXRXSUBR ) ) atoms-type-name-lst) )
  25.  
  26.  
  27.    (strcat
  28.       "\n\n int-lst length      : " (itoa (length int-lst     ) )
  29.       "\n\n subr-lst length     : " (itoa (length subr-lst    ) )
  30.       "\n\n exrxsubr-lst length : " (itoa (length exrxsubr-lst) )
  31.    )
  32. )

thanks...


AcGe, AcDb, AcBr, UI,
Mathematics, Geometry, EXCEL, SQL, General...

I will try my best to introduce them to you by category.
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