[Back to Blog](/blog) # Using .dgn Line Styles in a .dwg File (Part 4 of 4)

Andrew Markovich February 28, 2019 [\#Example](/blog/tag/example) [\#.dwg](/blog/tag/dwg)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

This article is part of a series of articles about using DGN line styles in a .dwg file. For the previous article, see [Part 3](https://www.opendesign.com/blog/2019/january/using-dgn-line-styles-dwg-file-part-3-4).

#### Creating point line style components

A point line style component provides the ability to set up symbol components to be vectorized for each stoke pattern dash (or gap) or for curve start/end points. Also it provides the ability to set up a symbol component to be vectorized on each polyline vertex. To set up symbols for stroke pattern dashes (and gaps), first create the stroke pattern component. In this example we use a simple stroke pattern component from the [previous article](https://www.opendesign.com/blog/2019/january/using-dgn-line-styles-dwg-file-part-3-4):

```
// Create Stroke LineStyle Component
OdDbLSStrokePatternComponentPtr pLsComponent = OdDbLSStrokePatternComponent::createObject();
pLsComponent->setComponentType(kLSStrokePatternComponent);
pLsComponent->setComponentUID(dgnLS_UID);

// Append strokes
pLsComponent->insertStroke(0.008)->setDash();
pLsComponent->insertStroke(0.003)->setGap();
pLsComponent->insertStroke(0.002)->setDash();
pLsComponent->insertStroke(0.003)->setGap();

// Add component into LineStyles dictionary
OdDbDictionaryPtr pDict = ::oddbDgnLSGetComponentsDictionary(pDb, OdDb::kForWrite, true);
pDict->setAt(OD_T("DemoDgnLineStyleStrokeComponentForPointComponent"), pLsComponent);

```

This set of strokes and gaps generates the following line style:

![image0](/files/inline-images/0.jpg)Now we can create a new point component (this code is typical for creating all DGN line style components) and attach the existing stroke pattern component to it:

```
// Create Point Component
OdDbLSPointComponentPtr pPtComponent = OdDbLSPointComponent::createObject();
pPtComponent->setComponentType(kLSPointComponent);
::oddbDgnLSIncrementUID(dgnLS_UID);
pPtComponent->setComponentUID(dgnLS_UID);

// Set up stroke component for point component
pPtComponent->setStrokeComponent(pLsComponent->objectId());

```

Note: The underlying stroke pattern component dashes are not vectorized when attached to a point component. To vectorize the stroke pattern component together with point component symbols, creation of a compound component is required. Compound components will be discussed in a future blog article.

To use point components, add an additional include file in the program source code:

```
#include "DgnLS/DbLSPointComponent.h"
```

Now, for example, connect the existing symbol component to the second segment in the stroke pattern component (this is the first gap in the stroke pattern):

```
// Set symbol for stroke component gaps
OdDbLSSymbolReference lsRef;
lsRef.setSymbolComponent(pSymComponent->objectId());
lsRef.setJustify(OdDbLSSymbolReference::kLSJustifyCenter);
pPtComponent->insertSymbolForStroke(&lsRef, 1);

```

The OdDbLSSymbolReference structure in this code represents a set of symbol parameters, for example, rotation, offsets, justification and some additional flags. In this example, attach the symbol component ID to the OdDbLSSymbolReference structure using the OdDbLSSymbolReference::setSymbolComponent method. Additionally, set the justification to display the symbol in the center of the stroke pattern gap. The justification parameter must be set to attach the symbol for a stroke. And finally, call the OdDbLSPointComponent::insertSymbolForStroke method to attach the symbol to the point component.

And attach the second symbol component to vectorize it on the ends of curves:

```
// Set symbol for line end
lsRef.setSymbolComponent(pSymComponent->objectId());
lsRef.setJustify(OdDbLSSymbolReference::kLSNoJustify);
pPtComponent->insertSymbolForVertex(&lsRef, OdDbLSSymbolReference::kLSAtEnd);

```

Finally, attach our point component to the DGN line style components dictionary:

```
// Add component into LineStyles dictionary
pDict->setAt(OD_T("DemoDgnPointComponent"), pPtComponent);
```

All of the next code was detailed in a previous article to create the line style definition component, attach it to OdDbLinetypeTableRecord and create a line entity for testing line style visualization. Here we use it again but with a small difference: attach to the line style definition a new point line style component instead of a stroke pattern component.

```
// Create LineStyle Definition
OdDbLSDefinitionPtr pLSDef = OdDbLSDefinition::createObject();
pLSDef->setComponent(pPtComponent->objectId());
pLSDef->setComponentUID(pPtComponent->componentUID());

// Create Linetype Table Record
OdDbLinetypeTableRecordPtr pLtpRec = OdDbLinetypeTableRecord::createObject();
pLtpRec->setName(OD_T("DemoDgnLineStylePoint"));
pLtpRec->setComments(OD_T("Point component"));
OdDbObjectId lsId = OdDbLinetypeTable::cast(pDb->getLinetypeTableId().safeOpenObject(OdDb::kForWrite))->add(pLtpRec);
// Attach LineStyle Definition to Linetype Table Record
pLtpRec->createExtensionDictionary();
OdDbDictionaryPtr pLtpDict = OdDbDictionary::cast(pLtpRec->extensionDictionary().openObject(OdDb::kForWrite));
pLtpDict->setAt(::oddbDgnLSGetDefinitionKeyName(), pLSDef);

// Create line for LineStyle testing
OdDbLinePtr pLine = OdDbLine::createObject();
pLine->setDatabaseDefaults(pDb);
pLine->setLinetype(lsId);
pLine->setEndPoint(OdGePoint3d(1.0, 0.0, 0.0));
OdDbBlockTableRecord::cast(pDb->getActiveLayoutBTRId().safeOpenObject(OdDb::kForWrite))->appendOdDbEntity(pLine);

```

The line style that results after executing the code looks like the following images (at different zoom levels):

![image1](/files/inline-images/1.jpg)![image2](/files/inline-images/2.jpg)![image3](/files/inline-images/3.jpg)![image4](/files/inline-images/4.jpg)The block containing four helixes is displayed for each linetype (stroke) pattern repetition, and the block containing the polyline arrow is displayed at the end point of the OdDbLine entity.

#### Point component creation (full command source code)

```
#include "DbLinetypeTable.h"
#include "DbLinetypeTableRecord.h"
#include "DbLine.h"
#include "DbHelix.h"
#include "DbPolyline.h"
#include "DbBlockTable.h"
#include "DgnLS/DbLSDefinition.h"
#include "DgnLS/DbLSStrokePatternComponent.h"
#include "DgnLS/DbLSPointComponent.h"
#include "DgnLS/DbLSSymbolComponent.h"
#include "DgnLS/DbLSMisc.h"

static OdDbHelixPtr createHelix(OdGePoint3d location, double radius)
{
  OdDbHelixPtr helPtr = OdDbHelix::createObject();
  helPtr->setStartPoint(location - OdGeVector3d::kZAxis);
  helPtr->setConstrain(OdDbHelix::kTurns);
  helPtr->setBaseRadius(radius);
  helPtr->setTopRadius(radius / 5);
  helPtr->setTurns(4.0);
  helPtr->setAxisVector(OdGeVector3d::kZAxis);
  helPtr->createHelix();
  return helPtr;
}

static OdDbBlockTableRecordPtr createSegmentBlock()
{ const double fBlockScale = 1.0 / 1000.0;
  OdDbBlockTableRecordPtr btrPtr = OdDbBlockTableRecord::createObject();
  btrPtr->appendOdDbEntity(createHelix(OdGePoint3d(-fBlockScale, -fBlockScale, 0.0), fBlockScale));
  btrPtr->appendOdDbEntity(createHelix(OdGePoint3d( fBlockScale, -fBlockScale, 0.0), fBlockScale));
  btrPtr->appendOdDbEntity(createHelix(OdGePoint3d(-fBlockScale,  fBlockScale, 0.0), fBlockScale));
  btrPtr->appendOdDbEntity(createHelix(OdGePoint3d( fBlockScale,  fBlockScale, 0.0), fBlockScale));
  btrPtr->setName(OD_T("4helix"));
  return btrPtr;
}

static OdDbBlockTableRecordPtr createArrowBlock()
{
  const double fBlockScale = 1.0 / 1000.0;
  OdDbPolylinePtr pPl = OdDbPolyline::createObject();
  pPl->addVertexAt(0, OdGePoint2d(-fBlockScale, -fBlockScale));
  pPl->addVertexAt(1, OdGePoint2d(-fBlockScale,  fBlockScale));
  pPl->addVertexAt(2, OdGePoint2d( fBlockScale,  0.0));
  pPl->setClosed(true);
  OdDbBlockTableRecordPtr btrPtr = OdDbBlockTableRecord::createObject();
  btrPtr->appendOdDbEntity(pPl);
  btrPtr->setName(OD_T("arrow"));
  return btrPtr;
}

static OdDbObjectId appendBlock(OdDbDatabase *pDb, OdDbBlockTableRecordPtr btrPtr)
{
  return OdDbBlockTable::cast(pDb->getBlockTableId().openObject(OdDb::kForWrite))->add(btrPtr);
}

void _CreateDgnLineStyle_Point_func(OdEdCommandContext* pCmdCtx)
{
  OdDbDatabasePtr pDb = pCmdCtx->baseDatabase();
  OdDbUserIOPtr pIO = pCmdCtx->userIO();

  ::odrxDynamicLinker()->loadModule(OdDgnLSModuleName);

  // We need GUID for DgnLS objects
  OdUInt8 dgnLS_UID[16];
  ::oddbDgnLSInitializeImportUID(dgnLS_UID);

  // Create Stroke LineStyle Component
  OdDbLSStrokePatternComponentPtr pLsComponent = OdDbLSStrokePatternComponent::createObject();
  pLsComponent->setComponentType(kLSStrokePatternComponent);
  pLsComponent->setComponentUID(dgnLS_UID);

  // Append strokes
  pLsComponent->insertStroke(0.008)->setDash();
  pLsComponent->insertStroke(0.003)->setGap();
  pLsComponent->insertStroke(0.002)->setDash();
  pLsComponent->insertStroke(0.003)->setGap();

  // Add component into LineStyles dictionary
  OdDbDictionaryPtr pDict = ::oddbDgnLSGetComponentsDictionary(pDb, OdDb::kForWrite, true);
  pDict->setAt(OD_T("DemoDgnLineStyleStrokeComponentForPointComponent"), pLsComponent);

  // Create symbol component for first block
  OdDbLSSymbolComponentPtr pSymComponent = OdDbLSSymbolComponent::createObject();
  pSymComponent->setComponentType(kLSSymbolComponent);
  pSymComponent->setDescription(OD_T("DemoDgnSymbol1"));
  ::oddbDgnLSIncrementUID(dgnLS_UID);
  pSymComponent->setComponentUID(dgnLS_UID);

  // Attach block to symbol component
  pSymComponent->setBlockTableRecord(::appendBlock(pDb, ::createSegmentBlock()));

  // Add component into LineStyles dictionary
  pDict->setAt(OD_T("DemoDgnSymbolForSegment"), pSymComponent);

  // Create Point Component
  OdDbLSPointComponentPtr pPtComponent = OdDbLSPointComponent::createObject();
  pPtComponent->setComponentType(kLSPointComponent);
  ::oddbDgnLSIncrementUID(dgnLS_UID);
  pPtComponent->setComponentUID(dgnLS_UID);

  // Set up stroke component for point component
  pPtComponent->setStrokeComponent(pLsComponent->objectId());

  // Set symbol for stroke component gaps
  OdDbLSSymbolReference lsRef;
  lsRef.setSymbolComponent(pSymComponent->objectId());
  lsRef.setJustify(OdDbLSSymbolReference::kLSJustifyCenter);
  pPtComponent->insertSymbolForStroke(&lsRef, 1);

  // Create symbol component for second block
  pSymComponent = OdDbLSSymbolComponent::createObject();
  pSymComponent->setComponentType(kLSSymbolComponent);
  pSymComponent->setDescription(OD_T("DemoDgnSymbol2"));
  ::oddbDgnLSIncrementUID(dgnLS_UID);
  pSymComponent->setComponentUID(dgnLS_UID);

  // Attach block to symbol component
  pSymComponent->setBlockTableRecord(::appendBlock(pDb, ::createArrowBlock()));

  // Add component into LineStyles dictionary
  pDict->setAt(OD_T("DemoDgnSymbolForLineEnd"), pSymComponent);

  // Set symbol for line end
  lsRef.setSymbolComponent(pSymComponent->objectId());
  lsRef.setJustify(OdDbLSSymbolReference::kLSNoJustify);
  pPtComponent->insertSymbolForVertex(&lsRef, OdDbLSSymbolReference::kLSAtEnd);

  // Add component into LineStyles dictionary
  pDict->setAt(OD_T("DemoDgnPointComponent"), pPtComponent);

  // Create LineStyle Definition
  OdDbLSDefinitionPtr pLSDef = OdDbLSDefinition::createObject();
  pLSDef->setComponent(pPtComponent->objectId());
  pLSDef->setComponentUID(pPtComponent->componentUID());

  // Create Linetype Table Record
  OdDbLinetypeTableRecordPtr pLtpRec = OdDbLinetypeTableRecord::createObject();
  pLtpRec->setName(OD_T("DemoDgnLineStylePoint"));
  pLtpRec->setComments(OD_T("Point component"));
  OdDbObjectId lsId = OdDbLinetypeTable::cast(pDb->getLinetypeTableId().safeOpenObject(OdDb::kForWrite))->add(pLtpRec);
  // Attach LineStyle Definition to Linetype Table Record
  pLtpRec->createExtensionDictionary();
  OdDbDictionaryPtr pLtpDict = OdDbDictionary::cast(pLtpRec->extensionDictionary().openObject(OdDb::kForWrite));
  pLtpDict->setAt(::oddbDgnLSGetDefinitionKeyName(), pLSDef);

  // Create line for LineStyle testing
  OdDbLinePtr pLine = OdDbLine::createObject();
  pLine->setDatabaseDefaults(pDb);
  pLine->setLinetype(lsId);
  pLine->setEndPoint(OdGePoint3d(1.0, 0.0, 0.0));
  OdDbBlockTableRecord::cast(pDb->getActiveLayoutBTRId().safeOpenObject(OdDb::kForWrite))->appendOdDbEntity(pLine);
}

```

## Get started today

**Try ODA software free for 60 days.  
No risk, no credit card required.**

[Try for Free](https://staging.opendesign.com/free-trial)
