Jump to content

LISP uses the ARX-AcBr library to set different colors for each face of 3DSOLID


Recommended Posts

Posted

Video_2024-04-16_131838.gif.57b192e39e517f3ae5c32e7a104df1e1.gif

 

We know that there is no command in CAD to set a different color for each face of 3DSOLID. We can do it through the ACBR API.

Using ACBRAPI, iterate over each face (FACE) and set the color of each face by the child entity ID of the child entity path

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

What is "ACBR API"?


AcBr API is ARX's application development interface for processing topological objects. It is used to process the topological relationships of three-dimensional geometric entities such as AcDbRegion, AcDb3DSolid, and AcDbBody.
Except for ARX, other development interfaces such as VLISP do not provide encapsulated interfaces.


Through this API, you can easily query the data and topological relationships of "volumes, surfaces, rings, edges, and points" of geometric model entities.
AcBrEntity is the base class of this interface and cannot be instantiated by itself. It derives subclasses such as AcBrBrep, AcBrFace, AcBrLoop, AcBrEdge, AcBrVertex and AcBrShell. And through the topology traverser AcBrTraverser class, the entire model entity is traversed in the order of body, surface, ring, edge, and point.

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

void TestBrep(void) 
{ 
    Adesk::Int32 len; 
    ads_name  ssname0; 
  struct resbuf *buffer; 
    buffer = acutBuildList(-4, _T("<AND"), 
              RTDXF0, _T("3DSOLID"), 
              -4, _T("AND>"), RTNONE); 
    acutPrintf(_T("\nSelect a box:")); 
    acedSSGet(NULL, NULL, NULL, buffer, ssname0); 
   acutRelRb(buffer); 
  if (RTNORM == acedSSLength(ssname0, &len)) 
    { 
        ads_name  ent; 
        AcDbObjectId entId; 
    for(long k = 0; k < len; k++) 
        { 
            acedSSName(ssname0, k, ent); 
            acdbGetObjectId(entId, ent); 
      settingDifferentColorToEachFace(entId); 
        } 
        acedSSFree(ssname0); 
    } 
} 
 
void settingDifferentColorToEachFace(AcDbObjectId solidId) 
{ 
  AcCmColor specialColor; 
  AcDb3dSolid* pSolid; 
    if (Acad::eOk == acdbOpenObject(pSolid, solidId, AcDb::kForRead)) 
    { 
        AcDbFullSubentPath path(solidId, AcDbSubentId()); 
    AcBrBrep brep; 
        AcBr::ErrorStatus bs = brep.setSubentPath(path); 
        if (bs != AcBr::eOk) 
            return; 
   //Initialize the BrepFace traverser 
        AcBrBrepFaceTraverser bft; 
        bs = bft.setBrep(brep); 
        if (bs != AcBr::eOk) 
            return;  
        AcArray<AcDbSubentId> arrSubentId; 
        // Traverse all faces 
        for (;!bft.done();bft.next()) 
        { 
            AcBrFace face; 
            bs = bft.getFace(face);     
            if (bs != Acad::eOk) 
            { 
                acutPrintf(L"\ngetFace failed"); 
                break; 
            } 
            AcDbFullSubentPath    Path(kNullSubent); 
            AcDbSubentId          subentId; 
            AcBr::ErrorStatus bss = face.getSubentPath(Path); 
            subentId = Path.subentId(); 
            arrSubentId.append(subentId); 
        } 
        pSolid->upgradeOpen(); 
        for (int i = 0; i < arrSubentId.length(); i++) 
        { 
      specialColor.setColorIndex(i); 
            pSolid->setSubentColor(arrSubentId[i],specialColor); 
        } 
        pSolid->downgradeOpen(); 
    } 
    pSolid->close(); 
} 
 

 

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

The following is the LISP code implemented by the AcBr library function of the XDRX API:
The code is as follows: three-layer loop traversal structure.
 

(defun c:tt ()
   (defun _traversface (e)
     (setq br (xdbr::constructor e))
     (setq tr (xdbr::constructor "brepfacetraverser" br))
     ;;FACE traversal
     (setq ids nil)
     (while (not (xdbr::traverser:done tr));Traverse the face
       (if (setq face (xdbr::getpropertyvalue tr "face")); Get the face AcBrFace at the current traversal pointer position
         (progn (setq SubEntPath (xdbr::getpropertyvalue face "subentpath");Get the subentity path of the face
                      SubEntId (xdrx_getpropertyvalue SubEntPath "subentid");;Get the subentity ID
                      ids (cons SubEntId ids);save to global table
                )
                (xdrx_object_release SubEntPath);;Release the subentity path variable
         )
       )
       (xdbr::traverser:next tr);;The traverser points to the next position
     )
     (xdrx_object_release tr br);;Release the traverser and BREP variables
     (setq i 0)
     (repeat (length ids);Set the color of the fruit body surface
       (setq clr (xdrx-math-rand 1 128))
       (xdrx_setpropertyvalue
         e
         "subentcolor"
         (list (setq SubEntId (nth i ids)) clr)
       )
       (setq i (1+ i))
       (xdrx_object_release SubEntId);;Release the subentity ID variable
       (xdrx_prompt
         (xdrx_string_formatex "\n - Face[%d]-Color[%d]" i clr)
       )
     ) ;
   )
   (if (setq e (car (xdrx_entsel "\nSelect 3DSOLID<Exit>:" '((0 . "3DSOLID")))))
     (progn 
       (xdrx_begin)
       (_traversface e)
       (xdrx_end)
     )
   )
   (princ)
)

 

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

 

The above LISP code uses XDRX-API
Before trying the forum code, please download and install XDRX - API

 

xdcad/XDrx-API: Autolisp development library written in ObjectARX (github.com)

https://github.com/xdcad/XDrx-API

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...