Author Topic: Adding attributes to a block  (Read 2510 times)

0 Members and 1 Guest are viewing this topic.

Helios

  • Guest
Adding attributes to a block
« on: September 29, 2009, 11:05:21 AM »
Hello all,

I can add a line to a block (m_CurSpace) using code below.
Now I need to add an Attribute definition too.
Since C++ and ARX are not exactly my cup of tea, I was wondering if anyone could show me an example how to add an Attribute definition to a block.

TIA,

Arno van Eeuwen


Acad::ErrorStatus CadDrawing::AddLine(const AcGePoint3d &p1, const AcGePoint3d &p2)
 {
   Acad::ErrorStatus es = Acad::eNullHandle;
   
   if(NULL != m_pCurDb)
   {
   
     AcDbObjectPointer<AcDbLine> line;
   
     if ((es = line.create()) != Acad::eOk)   return es;
     
     if ((es = line->setStartPoint(p1)) != Acad::eOk)  return es;
   
      if ((es = line->setEndPoint(p2)) != Acad::eOk)   return es;
           
     return m_CurSpace->appendAcDbEntity(line));     
   
   }
   return es;
 } 

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6964
  • AKA Daniel
Re: Adding attributes to a block
« Reply #1 on: September 30, 2009, 02:27:51 AM »
I'm headed out of town, if someone else doesn't post an example, I will try when I get back.  :-)

Helios

  • Guest
Re: Adding attributes to a block
« Reply #2 on: September 30, 2009, 04:32:04 AM »
A simple example should do it, or a hint where to find some documentation on this.

Looking forward to any response.

Arno


It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6964
  • AKA Daniel
Re: Adding attributes to a block
« Reply #3 on: October 09, 2009, 02:28:40 AM »
...A simple example should do it...

Here's a quick sample  :-)

Code: [Select]

 typedef AcDbObjectPointer<AcDbBlockReference> AcDbBlockReferencePointer;

 static void ArxBlockSamp_doit(void)
 {

  TCHAR blockName[134]; // alloc space for our blockname
  AcDbObjectId btrId = AcDbObjectId::kNull ; // create a null ID
  AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();

  if(acedGetString(0,_T("\nEnter a Block Name: "),blockName) != RTNORM)
  {
   acdbFail( _T("@acedGetString"));
   return;
  }

  //call helper to get the ID of block
  if(getBlockTableRecordId(blockName,btrId,pDb) != eOk)
  {
   acdbFail( _T("@getBlockRecordId"));
   return;
  }

  // smart pointer to block
  AcDbBlockTableRecordPointer pBlockTableRecordPointer(btrId,AcDb::kForWrite);
  if(pBlockTableRecordPointer.openStatus() != eOk)
  {
   acdbFail( _T("@pBlockTableRecordPointer.openStatus"));
   return;
  }

  // a pointer to a new AcDbAttributeDefinition, I use a normal pointer
  // here because I want to use the ctor & I want to use it later
  AcDbAttributeDefinition *pAttributeDefinition =
     new AcDbAttributeDefinition(pBlockTableRecordPointer->origin(),
                                 _T("Text"), _T("Tag"), _T("Prompt"));

  // add the new AcDbAttributeDefinition to block
  if(pBlockTableRecordPointer->appendAcDbEntity(pAttributeDefinition) != eOk)
  {
   delete pAttributeDefinition;
   acdbFail( _T("@pBlockTableRecordPointer->appendAcDbEntity"));
   return;
  }

  pAttributeDefinition->downgradeOpen(); // make sure its readonly
  AcDbObjectIdArray blockReferenceIds;   // array to hold BlockReferenceIds
  pBlockTableRecordPointer->getBlockReferenceIds(blockReferenceIds);

  // helper to update BlockReferences
  updateBlockReferences(blockReferenceIds, pAttributeDefinition );
  pAttributeDefinition->close(); // clean up;
  acutPrintf(_T("Ok!"));
 }

 static void updateBlockReferences(const AcDbObjectIdArray &blockReferenceIds,
                                   AcDbAttributeDefinition *pAttributeDefinition)
 {
  for(int i = 0 ; i <  blockReferenceIds.length() ; i++)
  {
   AcDbBlockReferencePointer pBlockReferencePointer(blockReferenceIds[i],AcDb::kForWrite);
   AcGeMatrix3d mat = pBlockReferencePointer->blockTransform();
   AcDbAttribute *pAttribute =
         new AcDbAttribute(pAttributeDefinition->position().transformBy(mat),
                           pAttributeDefinition->textStringConst(),
                           pAttributeDefinition->tagConst());

   if(pBlockReferencePointer->appendAttribute(pAttribute)!= eOk)
   {
    delete pAttribute;
    continue;
   }
   pAttribute->close();
  }
 }

 static Acad::ErrorStatus getBlockTableRecordId(LPCTSTR name, AcDbObjectId &btrId,
                                                AcDbDatabase *pDb)
 {
  Acad::ErrorStatus stat = eOk;
  AcDbBlockTablePointer pBlocktable(pDb->blockTableId(), AcDb::kForRead);
  stat = pBlocktable.openStatus();
  if(stat != eOk)
   return stat;
  if(pBlocktable->has(name))
   return pBlocktable->getAt(name,btrId);
  else
   return Acad::eNotInDatabase;
 }

Helios

  • Guest
Re: Adding attributes to a block
« Reply #4 on: October 09, 2009, 08:28:14 AM »
Thank you Daniel.
This should keep me going.
Obviously a little more complicated than adding lines.....   :|

Arno