Scale Mechanical Symbols

Dmytro Kabenok

August 13, 2021

With Mechanical SDK you can configure two types of scale factors for mechanical symbols (classes derived from AcmSymbol):

  • arrowhead scale (leader)
  • scale of the main symbol and all sub-symbols (excluding the leader)

Default values are taken from the corresponding standard if no arrowhead scale is specified during symbol creation. Each symbol standard (AcmSymbolStd derived class) by default depends on the parameters in the master standard (AcmStandard class). If the master standard settings change, parameters in the symbol standards change accordingly (if the dependency is not broken).

To get or set the value of the global symbol scale, use the functions odmGetSymbolScale() and odmSetSymbolScale(). They are declared in the file “OdmSymScale.h”. The value of the global symbol scale does not depend on the standard and is stored in a separate object in the database.

The default value of the arrowhead scale for metric standards is 3.5 and for English standards (ANSI) is 0.12. The default scale of the main symbol and all sub-symbols does not depend on the measurement and is equal to 1.0.

You can make the parameters in the symbol standard independent of the master standard. Set the flag responsible for the "by standard" as false for the field that you do not want to update if there are changes to the parameters in the master standard. For example, you can call the method setArwScaleByStandard() of the AcmSymbolStd class with the input parameter as false, and it removes the dependency from the master standard only for this field (if the input value is set to true, it restores the dependency and copies the value from the master standard). You can also call the setArwScale() method with a new scale value; this also removes the dependency from the master standard.


Create a simple symbol with default data taken from the master standard. For example, create an AmdtEdge symbol:

// Create AmdtEdge and set default values
AmdtEdgePtr pEdgeSym = AmdtEdge::createObject();
if (pEdgeSym->setSymbolDefaults(pDb) != Acm::eOk) // pDb - pointer to the database

// Customize AmdtEdge
pEdgeSym->setValue(Acm::EdgeMax, L"12.2");
pEdgeSym->setValue(Acm::EdgeMin, L"-3.2");

// Create the leader points array and add the leader
OdGePoint3dArray leadPoints;
leadPoints.append(OdGePoint3d(10.0, 11.0, 0.0));
leadPoints.append(OdGePoint3d(15.5, 18.5, 0.0));
if (pEdgeSym->addLeader(leadPoints) != Acm::eOk)

// Set the origin

// Open the model space object and append the entity to the model space
OdDbBlockTableRecordPtr pBTR = pDb->getModelSpaceId().safeOpenObject(OdDb::kForWrite);

As a result, you get the following symbol:


As a result, you get the following symbol


Now change the scale factor for the symbol leader. To do this, use the method described previously and change the value in the symbol standard; all symbols that are created based on this symbol standard will have the new value. You can also change the value for only the current symbol using methods from the symbol leader: setArrowType() and setArrowScale().

AmdtEdgePtr pEdgeSym2 = AmdtEdge::createObject();
if (pEdgeSym2->setSymbolDefaults(pDb) != Acm::eOk)

pEdgeSym2->setValue(Acm::EdgeMax, L"12.2");
pEdgeSym2->setValue(Acm::EdgeMin, L"-3.2");

OdGePoint3dArray leadPoints;
leadPoints.append(OdGePoint3d(50.0, 11.0, 0.0));
leadPoints.append(OdGePoint3d(55.5, 18.5, 0.0));

if (pEdgeSym2->addLeader(leadPoints) != Acm::eOk)


// Get the leader
AcmCLeader* pLeader = pEdgeSym2->getLeader(0);
if (!pLeader)

// For setting the new arrow scale in the symbol leader you need to override the arrow type.
// Value Acm::kByStandard was set by default, it disables logic for arrowScale changing.
//// Set the new arrow scale

// Or you can use the next code, that was described in the overview, but keep in
// mind that changes in parameters in the symbol standard may affect all
// previously created symbols (related to this symbol standard).
  AmdtEdgeStdPtr pSymbStd = AmdtEdgeStd::cast(pEdgeSym2->serverId().openObject(OdDb::kForWrite));
  if (pSymbStd.isNull())


OdDbBlockTableRecordPtr pBTR = pDb->getModelSpaceId().safeOpenObject(OdDb::kForWrite);

Two symbols are created as a result but with different scales for the leaders:


Two symbols are created


And finally, to use the global symbol scale:

AmdtEdgePtr pEdgeSym3 = AmdtEdge::createObject();
if (pEdgeSym3->setSymbolDefaults(pDb) != Acm::eOk)


pEdgeSym3->setValue(Acm::EdgeMax, L"12.2");
pEdgeSym3->setValue(Acm::EdgeMin, L"-3.2");

OdGePoint3dArray leadPoints;
leadPoints.append(OdGePoint3d(25.0, 31.0, 0.0));
leadPoints.append(OdGePoint3d(31.5, 43.5, 0.0));
if (pEdgeSym3->addLeader(leadPoints) != Acm::eOk)

odmSetSymbolScale(pDb, 3.0);  // Change the global symbol scale; value by default is 1.0
pEdgeSym3->setScale(odmGetSymbolScale(pDb)); // update scale for the current symbol

OdDbBlockTableRecordPtr pBTR = pDb->getModelSpaceId().safeOpenObject(OdDb::kForWrite);

Three symbols with different scales are created when executing all the code from this article:

  • AmdtEdge with default scale factors
  • AmdtEdge with a modified leader scale factor
  • AmdtEdge with an updated global symbol scale factor


Three symbols with different scales