Author Topic: Block Exploder for Bricscad.  (Read 6796 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7096
  • AKA Daniel
Block Exploder for Bricscad.
« on: September 02, 2008, 08:54:32 AM »
This routine tries to explode a block and convert the attributes to Text.
I have attached the compiled DRX modules , the command name is burst

Code: [Select]
class CommandBlockEx : public OdStaticRxObject <OdEdCommand>
{
public:
  const OdString localName() const { return globalName(); }
  const OdString groupName() const { return  OdString(_T("DRXGLOBAL")); }
  const OdString globalName() const { return OdString(_T("burst")); }

  void execute(OdEdCommandContext* pCmdCtx)
  {
    ASSERT(pCmdCtx != NULL);

    if(pCmdCtx == NULL)
      return;

    OdDbCommandContextPtr pDbCmdCtx(pCmdCtx);
    OdDbUserIOPtr pDbIO = pDbCmdCtx->dbUserIO();

    OdDbDatabasePtr pDb = pDbCmdCtx->database();
    if(pDb.isNull())
      return;

    OdRxObjectPtrArray entsToAdd;

    OdString message = DD_T("\nSelect Blocks to Explode: ");
    OdDbSelectionSetPtr pSelectionSet = pDbIO->select(message);
    OdDbObjectIdArray ids = pSelectionSet->objectIdArray();

    pDbIO->putString(DD_T("\nFiltering non Block Entities: "));

    ProgressMeter meter(ids.length());
    meter.start();

    for(unsigned int i = 0 ; i < ids.length() ; i++ , entsToAdd.clear())
    {
      meter.meterProgress();

      OdDbObjectPtr objectPtr = ids[i].openObject(OdDb::kForRead);

      if(!objectPtr->isKindOf(OdDbBlockReference::desc()))
        continue;

      OdDbBlockReferencePtr pBlockReference = objectPtr;
      if(pBlockReference.isNull())
        continue;

      OdDbObjectIteratorPtr pAttributeIterator =
                pBlockReference->attributeIterator();

      for (pAttributeIterator->start();
           !pAttributeIterator->done();
           pAttributeIterator->step())
      {
        OdDbAttributePtr pAttribute =
          pAttributeIterator->objectId().openObject(OdDb::kForRead);

        OdDbTextPtr pText = OdDbText::createObject();
        pText->setTextString(pAttribute->textString());
        pText->setColor(pAttribute->color());
        pText->setHeight(pAttribute->height());
        pText->setPosition(pAttribute->position());
        pText->setRotation(pAttribute->rotation());
        pText->setTextStyle(pAttribute->textStyle());
        pText->setVerticalMode(pAttribute->verticalMode());
        entsToAdd.push_back((OdRxObjectPtr)pText);
      }
      pBlockReference->explode(entsToAdd);
      pBlockReference->upgradeOpen();
      pBlockReference->erase();

      OdDbBlockTableRecordPtr pBtr =
        pBlockReference->ownerId().openObject(OdDb::kForWrite);

      if(pBtr.isNull())
        continue;

      for(unsigned int j = 0 ; j < entsToAdd.length(); j++)
      {
        OdDbEntityPtr ePtr = (OdDbEntityPtr)entsToAdd[j];
        if(!ePtr->isKindOf(OdDbAttributeDefinition::desc()))
          pBtr->appendOdDbEntity(ePtr);
      }
    }
    meter.stop();
    pDbIO->putString(DD_T("\n "));
  }
};

« Last Edit: January 21, 2010, 10:17:38 AM by Daniel »
Retired

Spike Wilbury

  • Guest
Re: Block Exploder for Bricscad.
« Reply #1 on: September 02, 2008, 10:22:59 AM »
This routine tries to explode a block and convert the attributes to Text.
I have attached the compiled DRX modules , the command name is BlockEx

Code: [Select]
class CommandBlockEx : public OdStaticRxObject <OdEdCommand>
{
public:
  const OdString localName() const { return globalName(); }
  const OdString groupName() const { return  OdString(_T("DRXGLOBAL")); }
  const OdString globalName() const { return OdString(_T("BlockEx")); }

  void execute(OdEdCommandContext* pCmdCtx)
  {
    ASSERT(pCmdCtx != NULL);

    if(pCmdCtx == NULL)
      return;

    OdDbCommandContextPtr pDbCmdCtx(pCmdCtx);
    OdDbUserIOPtr pDbIO = pDbCmdCtx->dbUserIO();

    OdDbDatabasePtr pDb = pDbCmdCtx->database();
    if(pDb.isNull())
      return;

    OdRxObjectPtrArray entsToAdd;

    OdString message = DD_T("\nSelect Blocks to Explode: ");
    OdDbSelectionSetPtr pSelectionSet = pDbIO->select(message);
    OdDbObjectIdArray ids = pSelectionSet->objectIdArray();

    pDbIO->putString(DD_T("\nFiltering non Block Entities: "));

    ProgressMeter meter(ids.length());
    meter.start();

    for(unsigned int i = 0 ; i < ids.length() ; i++ , entsToAdd.clear())
    {
      meter.meterProgress();

      OdDbObjectPtr objectPtr = ids[i].openObject(OdDb::kForRead);

      if(!objectPtr->isKindOf(OdDbBlockReference::desc()))
        continue;

      OdDbBlockReferencePtr pBlockReference = objectPtr;
      if(pBlockReference.isNull())
        continue;

      OdDbObjectIteratorPtr pAttributeIterator =
                pBlockReference->attributeIterator();

      for (pAttributeIterator->start();
           !pAttributeIterator->done();
           pAttributeIterator->step())
      {
        OdDbAttributePtr pAttribute =
          pAttributeIterator->objectId().openObject(OdDb::kForRead);

        OdDbTextPtr pText = OdDbText::createObject();
        pText->setTextString(pAttribute->textString());
        pText->setColor(pAttribute->color());
        pText->setHeight(pAttribute->height());
        pText->setPosition(pAttribute->position());
        pText->setRotation(pAttribute->rotation());
        pText->setTextStyle(pAttribute->textStyle());
        pText->setVerticalMode(pAttribute->verticalMode());
        entsToAdd.push_back((OdRxObjectPtr)pText);
      }
      pBlockReference->explode(entsToAdd);
      pBlockReference->upgradeOpen();
      pBlockReference->erase();

      OdDbBlockTableRecordPtr pBtr =
        pBlockReference->ownerId().openObject(OdDb::kForWrite);

      if(pBtr.isNull())
        continue;

      for(unsigned int j = 0 ; j < entsToAdd.length(); j++)
      {
        OdDbEntityPtr ePtr = (OdDbEntityPtr)entsToAdd[j];
        if(!ePtr->isKindOf(OdDbAttributeDefinition::desc()))
          pBtr->appendOdDbEntity(ePtr);
      }
    }
    meter.stop();
    pDbIO->putString(DD_T("\n "));
  }
};



Hola Daniel,

Being a 200% neophyte in the DRX stuff, I am reading the above function and something attract my attention, why all the castings?

Here:
OdDbTextPtr pText = OdDbText::createObject(); // start like this

Then:
entsToAdd.push_back((OdRxObjectPtr)pText); // saved in a vector like this

And:
OdDbEntityPtr ePtr = (OdDbEntityPtr)entsToAdd[j]; // then it is used like this

Just curiosity, it might be something DRX required, don't know....(and yes I did not read what it is inside of your attached zip file)

Thanks!   :)

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7096
  • AKA Daniel
Re: Block Exploder for Bricscad.
« Reply #2 on: September 02, 2008, 10:30:33 AM »
I dunno, the compiler complained that it wanted a cast.
I probably should have made up an OdDbObjectPtrArray instead of using OdRxObjectPtrArray
Retired

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7096
  • AKA Daniel
Re: Block Exploder for Bricscad.
« Reply #3 on: September 02, 2008, 10:36:13 AM »
Nope that didnít work as explode wants an OdRxObjectPtrArray, these smart pointers do have a cast method that I ought to look into
Retired

Spike Wilbury

  • Guest
Re: Block Exploder for Bricscad.
« Reply #4 on: September 02, 2008, 10:46:21 AM »
Nope that didnít work as explode wants an OdRxObjectPtrArray, these smart pointers do have a cast method that I ought to look into

Daniel,

So the smart pointers are the ones that end with the Ptr, I see, kind a different from the ones I use in ObjectARX.

Thanks! :)


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7096
  • AKA Daniel
Re: Block Exploder for Bricscad.
« Reply #5 on: September 02, 2008, 11:10:07 AM »
Nope that didnít work as explode wants an OdRxObjectPtrArray, these smart pointers do have a cast method that I ought to look into

Daniel,

So the smart pointers are the ones that end with the Ptr, I see, kind a different from the ones I use in ObjectARX.

Thanks! :)




DRX is pretty slick, pretty much everything is C++ classes (RAII), even the ODA version of a resbuf is a class. Almost every class has a create method that returns a smart pointer to a new instance of the object. DRX manages the heap memory and the state of DbObjects for you. Itís very well designed and a real pleasure to code with.
Retired

Spike Wilbury

  • Guest
Re: Block Exploder for Bricscad.
« Reply #6 on: September 02, 2008, 11:17:28 AM »
DRX is pretty slick, pretty much everything is C++ classes (RAII), even the ODA version of a resbuf is a class. Almost every class has a create method that returns a smart pointer to a new instance of the object. DRX manages the heap memory and the state of DbObjects for you. Itís very well designed and a real pleasure to code with.

That sound very good.... I have a friend that he is porting a very huge application (ARX) to DRX.... I need to visit him, and have a look at the code....


To bad, I'm still stuck with just autocad...

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7096
  • AKA Daniel
Re: Block Exploder for Bricscad.
« Reply #7 on: September 02, 2008, 11:46:35 AM »
Well, you might want to get used to smart pointers, Autodesk is using them now too  8-)
http://www.theswamp.org/index.php?topic=22360.0
Retired

Spike Wilbury

  • Guest
Re: Block Exploder for Bricscad.
« Reply #8 on: September 02, 2008, 11:53:29 AM »
Well, you might want to get used to smart pointers, Autodesk is using them now too  8-)
http://www.theswamp.org/index.php?topic=22360.0


Wow, that's so easy..... I don't want that..... :)

But, appears that it is available on a2009 - I'm still in a2007

But it is good to know!!!

Thanks.

I use smart pointers in all my coding, but those looks new to me.... no call of

if (ent.openStatus() == Acad::eOk)
{

}

Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: Block Exploder for Bricscad.
« Reply #9 on: September 03, 2008, 11:06:28 AM »
I used them all the time when doing ARX work...nice little feature.
Me