newer 发表于 2021-1-7 18:07:16

Accessing sub-entities using AssocPersSubentityIdPE in ARX or .Net


问题:
How do I access the sub-entities of an AutoCAD entity in ObjectARX or .Net?

解答:
Below are two samples in C++ and C# that illustrate how to access the AssocPersSubentityIdPE and use it to iterate through the vertices and edges of the selected entity.


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Use: Retrieves entity vertices & edges using AssocPersSubentityIdPE
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ArxSubEntityPE()
{
         Acad::ErrorStatus err;

         ads_name name;
         ads_point pt;

         if(acedEntSel(L"\nSelect an Entity: ", name, pt) != RTNORM)
                      return;

         AcDbObjectId id;
         acdbGetObjectId(id, name);

         AcDbObjectPointerpEntity(id, AcDb::kForRead);

         // Get the Protocol extension associated with the entity
         AcDbAssocPersSubentIdPE* const pAssocPersSubentIdPE =
             AcDbAssocPersSubentIdPE::cast(pEntity->queryX(AcDbAssocPersSubentIdPE::desc()));

         if( pAssocPersSubentIdPE == NULL)
                      return;

         AcArrayvertexIds;
         pAssocPersSubentIdPE->getAllSubentities(pEntity, AcDb::kVertexSubentType, vertexIds);

         acutPrintf(L"\n- Vertex Subentities: ");

         for (int i = 0; i < vertexIds.length(); ++i)
         {
                      AcDbFullSubentPath path(id, vertexIds);

                      AcDbPoint* pPoint = AcDbPoint::cast(pEntity->subentPtr(path));

                      if (pPoint != NULL)
                      {
                                  AcGePoint3d pos = pPoint->position();
                                  acutPrintf(L"\n . Vertex: [%.2f, %.2f, %.2f]", pos.x, pos.y, pos.z);
                                  delete pPoint;
                      }
         }

         AcArrayedgeIds;
         pAssocPersSubentIdPE->getAllSubentities(pEntity, AcDb::kEdgeSubentType, edgeIds);

         acutPrintf(L"\n- Edge Subentities: ");

         for (int i = 0; i < edgeIds.length(); ++i)
         {
                      AcDbFullSubentPath path(id, edgeIds);

                      AcDbEntity* pSubEntity = pEntity->subentPtr(path);

                      if (pSubEntity != NULL)
                      {
                                  acutPrintf(L"\n . %s", pSubEntity->isA()->name());
                                  delete pSubEntity;
                      }
         }
}





///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Use: Retrieves entity vertices & edges using AssocPersSubentityIdPE
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

public void SubEntityPE()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    PromptEntityOptions peo = new PromptEntityOptions("\nSelect an Entity: ");

    PromptEntityResult per = ed.GetEntity(peo);

    if (per.Status != PromptStatus.OK)
      return;

    //Using AssocPersSubentityIdPE
    using (Transaction Tx = db.TransactionManager.StartTransaction())
    {
      Entity entity = Tx.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;

      ObjectId[] entId = new ObjectId[] { entity.ObjectId };

      IntPtr pSubentityIdPE = entity.QueryX(AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE)));

      if (pSubentityIdPE == IntPtr.Zero)
            //Entity doesn't support the subentityPE
            return;

      AssocPersSubentityIdPE subentityIdPE = AssocPersSubentityIdPE.Create(pSubentityIdPE, false)
            as AssocPersSubentityIdPE;

      SubentityId[] vertexIds = subentityIdPE.GetAllSubentities(entity, SubentityType.Vertex);

      ed.WriteMessage("\n- Vertex Subentities: ");

      foreach (SubentityId subentId in vertexIds)
      {
            FullSubentityPath path = new FullSubentityPath(entId, subentId);
            DBPoint vertex = entity.GetSubentity(path) as DBPoint;

            if (vertex != null)
            {
                ed.WriteMessage("\n . Vertex: [{0}, {1}, {2}]", vertex.Position.X, vertex.Position.Y, vertex.Position.Z);
                vertex.Dispose();
            }
      }


      SubentityId[] edgeIds = subentityIdPE.GetAllSubentities(entity, SubentityType.Edge);

      ed.WriteMessage("\n- Edge Subentities: ");

      foreach (SubentityId subentId in edgeIds)
      {
            FullSubentityPath path = new FullSubentityPath(entId, subentId);
            Entity edgeEntity = entity.GetSubentity(path);

            if (edgeEntity != null)
            {
                ed.WriteMessage("\n . " + edgeEntity.ToString());
                edgeEntity.Dispose();
            }
      }
    }
}


页: [1]
查看完整版本: Accessing sub-entities using AssocPersSubentityIdPE in ARX or .Net