设为首页收藏本站

中国膜结构网

 找回密码
 立即注册
膜结构车棚
膜结构车棚膜结构资质国产膜材 膜结构网中国膜结构协会
查看: 215|回复: 2

计算AcDbBlockReference准确的包围盒

[复制链接]
  • TA的每日心情
    开心
    2020-10-20 17:08
  • 签到天数: 1320 天

    连续签到: 3 天

    [LV.10]以坛为家III

    发表于 2020-8-27 11:09 | 显示全部楼层 |阅读模式
    void test()
    {
    ads_name ename;
    ads_point pt;
    if (acedEntSel("Select a block reference:",ename,pt)!=RTNORM)
      return;
    AcDbObjectId id;
    if (acdbGetObjectId(id,ename)!=Acad::eOk)
      return;
    AcDbExtents extents;
    AcDbBlockReference* pRef;
    if (acdbOpenObject(pRef,id,AcDb::kForRead)==Acad::eOk)
    {
      if (Acad::eOk==getBlockRefGeomExtents(pRef,extents))
      {
       //just display the 2d box
       AcGePoint2d minpt(extents.minPoint()[X],extents.minPoint()[Y]);
       AcGePoint2d maxpt(extents.maxPoint()[X],extents.maxPoint()[Y]);
       AcGePoint2dArray points;
       points.append(minpt);
       AcGePoint2d pt(maxpt[X],minpt[Y]);
       points.append(pt);
       points.append(maxpt);
       pt.set(minpt[X],maxpt[Y]);
       points.append(pt);
       AcDbPolyline* pPline;
       if ((pPline=makeSimplePline(points))!=NULL){
        pPline->setClosed(Adesk::kTrue);
        AcDbObjectId id;
        postToDb(pPline,id);
       }
      } else
       acutPrintf("\nCannot calculate accurate extents");
      pRef->close();
    }
    }
    //creates a polyline with 0 width, without bulges
    AcDbPolyline* makeSimplePline(const AcGePoint2dArray& points)
    {
       AcDbPolyline* pPline = new AcDbPolyline(points.length());
       if (pPline==NULL)
        return pPline;
       for (int i=0;i<points.length();i++)
        if (pPline->addVertexAt(i,points<i>)!=Acad::eOk)
    {
            delete pPline;
            pPline = NULL;
            break;
        }
       return pPline;
    }//explodes a 2dpolyline by first converting it to a new polyline
    Acad::ErrorStatus explodeAcDb2dPolyline(const AcDb2dPolyline*
    p2d,AcDbVoidPtrArray& ents){
       if (p2d==NULL)
        return Acad::eInvalidInput;
       AcDbPolyline* pPline;
       if ((pPline=new AcDbPolyline)==NULL)
        return Acad::eOutOfMemory;
       Acad::ErrorStatus es;
       if ((es=pPline->convertFrom((AcDbEntity*&)p2d,Adesk::kFalse))==Acad::eOk)
       {
        es=pPline->explode(ents);
       }
       return es;
    }Acad::ErrorStatus getBlockRefGeomExtents(AcDbBlockReference* pRef, AcDbExtents&
    extents, const AcGeMatrix3d& mat)
    {   
       Acad::ErrorStatus es;
       AcGeMatrix3d xform;
       AcDbEntity* pCopy;
       AcDbEntity* pE;
       xform=mat*pRef->blockTransform();
       AcDbObjectId idBlock = pRef->blockTableRecord();
       AcDbBlockTableRecord* pBlock;
       if ((es=acdbOpenObject(pBlock,idBlock,AcDb::kForRead))==Acad::eOk){
        AcDbBlockTableRecordIterator* pIter;
        if ((es=pBlock->newIterator(pIter))==Acad::eOk){
           for (pIter->start();!pIter->done();pIter->step()){
            AcDbExtents ext;
            if ((es=pIter->getEntity(pE,AcDb::kForRead))==Acad::eOk)
      {
                AcDbBlockReference* pRefNested;
                if ((pRefNested=AcDbBlockReference::cast(pE))!=NULL)
       {
        if ((es=getBlockRefGeomExtents(pRefNested,ext,xform))!=Acad::eOk)
        {
         pE->close();
         break;
        }
                }
       else
       {
        AcRxClass* pDesc = pE->isA();
        if (pDesc==AcDbPolyline::desc() ||
         pDesc==AcDb2dPolyline::desc() ||
         pDesc==AcDbMText::desc())
        {
         //need explode
         AcDbVoidPtrArray array;
         if (pDesc==AcDbPolyline::desc())
         es=pE->explode(array);
         if (pDesc==AcDbMText::desc())
         es=pE->explode(array);     if (pDesc==AcDb2dPolyline::desc())
         es=explodeAcDb2dPolyline(AcDb2dPolyline::cast(pE),array);     if (es==Acad::eOk)
         {
          for(int i=0;i<array.length();i++)
          {
           AcDbExtents ext2;
           AcDbEntity* pPart = ((AcDbEntity*)(array<i>));
           if((es=pPart->getTransformedCopy(xform,pCopy))==Acad::eOk)
           {
            es=pCopy->getGeomExtents(ext2);
            delete pCopy;
           }
           if (es!=Acad::eOk)
           {
            delete pPart;
            if (es==Acad::eNullExtents)
             continue;
            else
             break;
           }
           delete pPart;
           ext.addExt(ext2);
          }
         }
        }
        else
        {
         if((es=pE->getTransformedCopy(xform,pCopy))==Acad::eOk)
         {
          es=pCopy->getGeomExtents(ext);
          delete pCopy;
         }
        }
                }
                if (es!=Acad::eOk)
       {
        pE->close();
        if (es==Acad::eNullExtents)
         continue;
        else
         break;
       }
                extents.addExt(ext);
                pE->close();
            }
            }
            delete pIter;
        }
       }
       pBlock->close();
       //add non constant attributes
       AcDbObjectIterator* pIter;
       if ((pIter=pRef->attributeIterator())==NULL)
        return Acad::eOutOfMemory;
       for (pIter->start();!pIter->done();pIter->step())
       {
        AcDbExtents ext;
        if((es=acdbOpenObject(pE,pIter->objectId(),AcDb::kForRead))==Acad::eOk)
    {
            pE->getGeomExtents(ext);
            if (es!=Acad::eOk)
      {
       pE->close();
       if (es==Acad::eNullExtents)
        continue;
       else
        break;
            }
            extents.addExt(ext);
            pE->close();
        }
       }
       delete pIter;
       return es;
    }//Posts an entity to the database
    //
    Acad::ErrorStatus postToDb(AcDbEntity* ent, AcDbObjectId& objId)
    {
       Acad::ErrorStatus       es;
       AcDbBlockTable*       pBlockTable;
       AcDbBlockTableRecord*  pSpaceRecord;
        if (NULL == ent)
            return Acad::eNullObjectPointer;
        if (NULL == acdbHostApplicationServices()->workingDatabase())
            return Acad::eNoDatabase;
       if ((es = acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead))!= Acad::eOk)
            return es;
       if ((es = pBlockTable->getAt(ACDB_MODEL_SPACE,pSpaceRecord,AcDb::kForWrite))!= Acad::eOk)
        {
            pBlockTable->close();
            return es;
        }
       pBlockTable->close();
       if ((es = pSpaceRecord->appendAcDbEntity(objId, ent)) != Acad::eOk)
        {
            pSpaceRecord->close();
        return es;
       }
       pSpaceRecord->close();
       return ent->close();
    }
    http://www.mjgw.org/ 专业从事膜结构设计、制作加工、施工安装的膜结构咨询服务,能够为客户提供专业的膜结构整体解决方案。做中国最好的膜结构综合服务平台。欢迎大家联系QQ:463017170.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2020-10-20 17:08
  • 签到天数: 1320 天

    连续签到: 3 天

    [LV.10]以坛为家III

     楼主| 发表于 2020-8-27 11:10 | 显示全部楼层
    找到个汉化
    extents

    输出块参考的WCS范围

    parentXform

    输入应用至块参考几何体的变换

    当在非WCS坐标系统中工作时,从AcDbBlockReference::geomExtents()返回的范围可比实际上的几何体更大一些,因为AcDbBlockReference::geomExtents()通过块参考的变换矩阵而不是通过变换实体及计算一个变换的实体集的一个新的边框来变换包含的实体预计算的范围。这导致实体的范围长方体与非世界坐标对齐。这是一个快速的但不提供一个“过大”的包围范围的长方体的方法。

    AcDbBlockReference::geomExtentsBestFit()通过取得被参考的块表记录中的所有实体,对它们应用parentXform,并在结果实体集上计算范围的拷贝来避免这个问题。这比使用AcDbBlockReference::geomExtents()处理更慢,但将导致最紧密地匹配封闭的几何体。

    此方法递归地作用于嵌套的块参考。当此方法在最外层的块参考上调用时(ARX应用程序的标准情况),parentXform应为从最外层块参考至参考拥有调用此方法的块参考的块表记录的块参考的累积变换。

    此方法使用AcDbBlockReference::explode()方法取得实体的拷贝。因为AcDbBlockReference::explode()目前不支持不一致的变换,所以如果调用此方法的块参考或任何嵌套的块参考有不一致的变换,则此方法不成功且将返回Acad::eInvalidInput。

    如果成功返回Acad::eOk。



    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-10-20 17:08
  • 签到天数: 1320 天

    连续签到: 3 天

    [LV.10]以坛为家III

     楼主| 发表于 2020-8-27 11:10 | 显示全部楼层
    我来贴一段代码:

    AcDbExtents CEntity::GetRefBoundingBox (AcDbBlockReference *pRef, const AcGeMatrix3d & mat)
    {
            AcDbExtents ext;
            AcDbExtents RetExt;
            AcDbObjectId recId = pRef->blockTableRecord();
            AcDbBlockTableRecordPointer block(recId,AcDb::kForRead);
            Acad::ErrorStatus es = block.openStatus();
            if (es == eOk)
            {
                    AcDbBlockTableRecordIterator *pItr = NULL;
                    block->newIterator(pItr);
                    AcDbObjectId id;
                    AcDbEntity *pEnt = NULL;
                    for (pItr->start();!pItr->done();pItr->step())
                    {
                            es = pItr->getEntity(pEnt,AcDb::kForWrite);
                            if (es == eOk)
                            {
                                    pEnt->transformBy(mat);
                                    if (pEnt->isKindOf(AcDbBlockReference::desc()))
                                    {
                                            AcGeMatrix3d blkmat=((AcDbBlockReference*)pEnt)->blockTransform();
                                            ext = GetRefBoundingBox((AcDbBlockReference *)pEnt,blkmat);
                                    }
                                    else
                                    {
                                            pEnt->getGeomExtents(ext);
                                    }
                                    pEnt->transformBy(mat.inverse());
                                    RetExt.addExt(ext);
                                    pEnt->close();
                            }
                    }
                    delete pItr;
                    pItr = NULL;
            }
            return RetExt;
    }
    譬如:
    AcDbObjectPointer<AcDbBlockReference> blkref(id,AcDb::kForRead);     //id块参照的id
    AcDbExtents  ext = CEntity::GetRefBoundingBox(blkref.object(),blkref->blockTransform());

    这个代码得到的box跟geomExtentsBestFit是一致的。

    至于lisp中,对于块参照,其boundingbox也是getGeomExtents,而不是geomExtentsBestFit
    其所以如果用LISP方法求,估计也要先变换块内实体,得到真正的box,然后把实体变换回去。



    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    推荐膜材品牌上一条 /5 下一条

    进口膜材 国产膜材 pvdf膜材ptfe膜材ETFE膜材
    最好的膜结构公司 一级膜结构资质 膜结构一级资质
    膜结构设计-膜结构十大品牌-etfe设计-充气膜结构
    诺科膜结构
    遨都膜结构设计
    中国膜结构网
    中国空间膜结构协会

    QQ|申请友链|Archiver|手机版|中国膜结构论坛

    GMT+8, 2020-10-21 23:44 , Processed in 0.327136 second(s), 23 queries .

    Powered by 中国膜结构网->膜材采购->膜结构设计->膜结构安装->膜结构维修

    © 2014-2020 膜结构协会->进口膜材->国产膜材->PVDF膜材->PTFE膜材->ETFE膜材.

    快速回复 返回顶部 返回列表