A layout object can be associated with:
In the following examples, the pLayout variable stores a pointer to the layout object, the pBlock variable stores a pointer to the block record object, and the pViewport variable stores a pointer to the paper viewport object.
The layout object stores the ID of the block record object with which it is associated. The initial value is OdDb::kNull when the layout is created by a pseudo-constructor. (When the ID is OdDb::kNull this property is not applicable.) The value stores the actual ID when the layout is created using the createLayout() method of the database object.
To get the associated block record object, use the getBlockTableRecordId() method which returns the OdDbObjectId instance associated with the block record object. Then, use the safeOpenObject() method to get a smart pointer to this object. For example:
OdDbObjectId idBlock = pLayout->getBlockTableRecordId();
OdDbBlockTableRecordPtr pBlock = idBlock.safeOpenObject();
odPrintConsoleString(L"\nAssociated block = %x - \"%s\"",
idBlock.getHandle().ascii().c_str(), pBlock->getName().c_str());
To associate the layout with a different block record object, use the setBlockTableRecordId() method which requires the ID of the block record object as the OdDbObjectId instance and does not return a value. The database stores all blocks in the block table object. To get the ID of a block, use the getBlockTableId() method of the database object to get the ID of the block table object and the getAt() method of the block table object to get the ID of the block record object using its name. For example:
OdDbBlockTablePtr pBlocks = pLayout->database()->getBlockTableId().safeOpenObject();
OdDbObjectId idBlock = pBlocks->getAt("MyBlock");
if(!idBlock.isNull()) pLayout->setBlockTableRecordId(idBlock);
This code creates the single-sided association from a layout to a block. To create the association from a block to a layout, use the setLayoutId() method of the block record object which requires an ID of the layout object. Continuing the example:
OdDbBlockTableRecordPtr pBlock = idBlock.safeOpenObject(OdDb::kForWrite);
if(!pBlock.isNull()) pBlock->setLayoutId( pLayout->ObjectId() );
To be correct, the association must be double-sided between the layout and block. For example:
pBlock->setLayoutId( pLayout->ObjectId() );
pLayout->setBlockTableRecordId( pBlock->ObjectId() );
Alternatively, the layout object has the addToLayoutDict() method that adds the layout object in the dictionary and creates the double-sided association with the specified block record object. For example:
OdString sName;
OdInt16 number = pDb->countLayouts();
try {
pBlock = OdDbBlockTableRecord::createObject();
sName.format(L"*Block_Layout_%d", number);
pBlock->setName(sName);
pLayout = OdDbLayout::createObject();
sName.format(L"Layout_%d", number);
pLayout->setLayoutName(sName);
pLayout->addToLayoutDict(pDb, pBlocks->add(pBlock))
}
catch(OdError& e) { odPrintConsoleString(L"\nError: %d - %s\n", e.code(), e.description().c_str()); }
Note: The createLayout() method creates the layout object, block record object, and association between them at the same time.
The layout object stores an ID of the viewport object with which it is associated. If the ID is OdDb::kNull the layout does not have an active viewport. The initial value is OdDb::kNull.
To get the active viewport object, use the activeViewportId() method which returns the OdDbObjectId instance associated with the paper viewport object. Then, use the safeOpenObject() method to get a smart pointer to this object. For example:
OdDbObjectId idViewport = pLayout->activeViewportId();
if(!idViewport.isNull())
{
OdDbViewportPtr pViewport = idViewport.safeOpenObject();
odPrintConsoleString(L"\nActive viewport = %x - (%fx%f)", pViewport->handle().ascii().c_str(),
pViewport->width(), pViewport->height());
}
To make the viewport object active, use the setActiveViewportId() method which requires the ID of the paper space viewport as the OdDbObjectId instance and does not return a value. The database stores paper space viewports as entities in the corresponding associated block. Only one paper space viewport is active in the layout. To get the ID of the paper space viewport using its handle, use the getOdDbObjectId() method of the database object, and then, use the safeOpenObject() method to get a smart pointer to the viewport. For example:
OdDbBlockTableRecordPtr pBlock = pLayout->getBlockTableRecordId().safeOpenObject(OdDb::kForWrite);
if(!pBlock.isNull())
{
OdDbViewportPtr pViewport = OdDbViewport::createObject();
OdDbObjectId idViewport = pBlock->appendOdDbEntity(pViewport);
pViewport = NULL;
pLayout->setActiveViewportId(idViewport);
}
Note: The paper space viewport must be closed before activating. When the viewport is being closed, it calls the subClose() method that registers itself in the internal table of the layout object. After registering it, the layout object knows that this paper space viewport exists in the associated block. Until then, closing is not performed and the viewport object cannot be set to active for the layout object. If the viewport is not added or is not closed, the setActiveViewportId() method throws the eInvalidInput exception, and errors occur. For example:
pViewport = OdDbViewport::createObject();
idViewport = pBlock->appendOdDbEntity(pViewport)
pLayout->setActiveViewportId(idViewport);
// Error: 5 - Invalid input.
To close the viewport object, release all references to it, that is, objects must not point to it. The example below sets the smart pointer to NULL for the new viewport object.
Note: The model space viewport cannot be set as active for the paper layout. The setActiveViewportId() method throws an exception, and errors occur. For example:
OdDbObjectId idViewport = pLayout->database()->getActiveViewportId();
OdDbLayoutPtr pPaperLayout = pLayouts->getAt(L"Layout1", OdDb::kForWrite);
pPaperLayout->setActiveViewportId(idViewport);
// Error: 63 - Object of class AcDbViewportTableRecord can't be cast to AcDbViewport.
Note: The model space viewport also cannot be set active for the model layout. For example:
OdDbLayoutPtr pModelLayout = pLayouts->getAt(L"Model", OdDb::kForWrite);
pModelLayout->setActiveViewportId(idViewport);
// Error: 63 - Object of class AcDbViewportTableRecord can't be cast to AcDbViewport.
Note: To make a model space viewport active for the model space layout, use the SetActiveViewport() method of the viewport table object which requires an ID of the viewport record object to be set active as an argument of the OdDbObjectId type. For example:
OdDbViewportTableRecordPtr pVTR = OdDbViewportTableRecord::createObject();
pVTR->setName("*Active");
pVTR->setLowerLeftCorner( OdGePoint2d(0.2, 0.1) );
pVTR->setUpperRightCorner( OdGePoint2d(0.6, 0.9) );
OdDbViewportTablePtr pVPorts = pDb->getViewportTableId(true).saveOpenObject(OdDb::kForWrite);
OdDbObjectId idVTR = pViewports->add(pVTR);
pVPorts->SetActiveViewport(idVTR);
One of the paper space viewports is the overall viewport (the initialized layout always has the overall viewport). The overall viewport envelops the geometry inside the layout. The layout object stores the ID of the overall viewport object.
To get the overall viewport object, use the overallVportId() method which returns the OdDbObjectId instance associated with the paper space viewport object being set as overall. Then, use the safeOpenObject() method to get a smart pointer to this object. For example:
OdDbObjectId idOverall = pLayout->overallVportId();
if(!idOverall.isNull())
{
OdDbViewportPtr pOverall = idOverall.safeOpenObject();
odPrintConsoleString(L"\nOverall viewport = %x - (%fx%f)", pOverall->handle().ascii().c_str(),
pOverall->width(), pOverall->height());
}
Note: The system assigns the overall viewport.
Extents and Limits of the Layout Object
Example of Working with the Layout Object
Copyright © 2002 – 2021. Open Design Alliance. All rights reserved.
|