A polyline consists of connected segments, so that the end of the current segment is the start of the next segment. A point in which two segments are connected is a vertex. Vertices define the track along which segments are drawn (linear, arc) and influence the geometrical shape of a polyline curve.
The polyline objects provide methods for getting the number of vertices, getting the coordinates of vertices, adding a new vertex, inserting a vertex, deleting a vertex, relocating an existing vertex, and identifying a vertex. In the following examples, the p2dPL variable stores a pointer to the two-dimensional polyline object, and the p3dPL variable stores a pointer to the three-dimensional polyline object.
Two-dimensional and three-dimensional polylines do not store the number of vertices or segments and do not enumerate them. Two-dimensional and three-dimensional polylines are containers that store their own vertices which are structurally independent from the polyline entity, but the polyline is the owner of them. Each vertex is an instance of the vertex entity implemented as an individual class. Properties of vertices are accessed through the interface of the two-dimensional vertex entity or three-dimensional vertex entity. Two-dimensional and three-dimensional polyline objects allow getting an iterator for self-containers through which vertices are accessed. By using this iterator, the program can calculate the number of vertices.
To calculate the number of vertices for a two-dimensional or three-dimensional polyline, use the vertexIterator() method which returns the iterator object that provides the traversing through the polyline container of vertices. Next, use the start() method to set the iterator on the first vertex, the step() method to move the iterator to the following vertex in the container, and the done() method to check whether the iterator finishes the traversing. Additionally, declare a variable of integer value to use as a counter of vertices in traversing through the container.
For example, a two-dimensional polyline:
OdInt16 count = 0;
OdDbObjectIteratorPtr itVertex = p2dPL->vertexIterator();
for(itVertex->start() ; !itVertex->done() ; itVertex->step()) count++;
odPrintConsoleString(L"\n2D Polyline Vertices = %d", count);
For example, a three-dimensional polyline:
OdInt16 number = 0;
OdDbObjectIteratorPtr itVertex = p3dPL->vertexIterator();
for(itVertex->start() ; !itVertex->done() ; itVertex->step()) number++;
odPrintConsoleString(L"\n3D polyline Vertices = %d", number);
Polylines can add a new vertex at any position. A new vertex automatically adds a new segment from the previous vertex to the new vertex. The number of vertices increases by one.
To add a vertex to a two-dimensional polyline, use the appendVertex() method which requires a pointer to an existing two-dimensional vertex entity as an argument of the OdDb2dVertex type and returns an object ID associated with this vertex when it is added to the database. To create an instance of the two-dimensional vertex entity, use the createObject() method of it (pseudo-constructor). The two-dimensional vertex entity requires three-dimensional coordinates of a point for specifying the two-dimensional position and the Z-coordinate is ignored. For example:
OdDb2dVertexPtr p2dVertex;
p2dVertex = OdDb2dVertex::createObject();
p2dVertex->setPosition( OdGePoint3d(0.5, 0.5, 1.0) );
OdDbObjectId id2dVertex1 = p2dPL->appendVertex(p2dVertex);
p2dVertex = OdDb2dVertex::createObject();
p2dVertex->setPosition( OdGePoint3d(3.2, 4.8, 1.0) );
OdDbObjectId id2dVertex2 = p2dPL->appendVertex(p2dVertex);
p2dVertex = OdDb2dVertex::createObject();
p2dVertex->setPosition( OdGePoint3d(6.5, 1.2, 1.0) );
OdDbObjectId id2dVertex3 = p2dPL->appendVertex(p2dVertex);
To add a vertex to a three-dimensional polyline, use the appendVertex() method which requires a pointer to an existing three-dimensional vertex entity as an argument of the OdDb3dPolylineVertex type and returns an object ID associated with this vertex when it is added to the database. To create an instance of the three-dimensional vertex entity, use the createObject() method of it (pseudo-constructor). The three-dimensional vertex entity requires three-dimensional coordinates of a point for specifying the three-dimensional position. For example:
OdDb3dPolylineVertexPtr p3dVertex;
p3dVertex = OdDb3dPolylineVertex::createObject();
p3dVertex->setPosition( OdGePoint3d(0.5, 0.5, 0.5) );
OdDbObjectId id3dVertex1 = p3dPL->appendVertex(p3dVertex);
p3dVertex = OdDb3dPolylineVertex::createObject();
p3dVertex->setPosition( OdGePoint3d(6.5, 1.2, 1.5) );
OdDbObjectId id3dVertex2 = p3dPL->appendVertex(p3dVertex);
p3dVertex = OdDb3dPolylineVertex::createObject();
p3dVertex->setPosition( OdGePoint3d(3.2, 4.8, 2.5) );
OdDbObjectId id3dVertex3 = p3dPL->appendVertex(p3dVertex);
Polylines allow insertion of a vertex between existing vertices to change the curve. Two-dimensional and three-dimensional polyline entities insert a vertex after the specified vertex using its object ID or pointer to an existing instance.
To insert a vertex to a two-dimensional or three-dimensional polyline, use the insertVertexAt() method which has two implementations. In both implementations this method requires a pointer to an existing instance of the vertex entity to be inserted in the polyline's container as the second argument and returns the object ID associated with the inserted vertex. The first argument requires an object ID in the first implementation or a pointer in the second implementation for the vertex stored in the polyline's container after which the new vertex must be added.
For example, a two-dimensional polyline:
// Two-dimensional polyline contains 3 vertices
p2dVertex = OdDb2dVertex::createObject();
p2dVertex->setPosition( OdGePoint3d(4.5, 2.5, 1.0) );
p2dPL->insertVertexAt(id2dVertex2, p2dVertex); // insert after second vertex, new vertex becomes third vertex
p2dVertex = OdDb2dVertex::createObject();
p2dVertex->setPosition( OdGePoint3d(2.5, 0.8, 1.0) );
p2dPL->insertVertexAt(id2dVertex1, p2dVertex); // insert after first vertex, new vertex becomes second vertex
For example, a three-dimensional polyline:
// Three-dimensional polyline contains 3 vertices
p3dVertex = OdDb3dPolylineVertex::createObject();
p3dVertex->setPosition( OdGePoint3d(4.6, 2.4, 2.0) );
p3dPL->insertVertexAt(id3dVertex2, p3dVertex); // insert after second vertex, new vertex becomes third vertex
p3dVertex = OdDb3dPolylineVertex::createObject();
p3dVertex->setPosition( OdGePoint3d(2.3, 0.6, 1.0) );
p3dPL->insertVertexAt(id3dVertex1, p3dVertex); // insert after first vertex, new vertex becomes second vertex
Note: To insert a new vertex at the beginning of a two-dimensional or three-dimensional polyline, pass kNull as an ID or NULL as a pointer value for the first argument. For example:
p2dVertex = OdDb2dVertex::createObject();
p2dVertex->setPosition( OdGePoint3d(0.1, 0.2, 1.0) );
p2dPL->insertVertexAt(NULL, p2dVertex); // insert before first vertex, new vertex becomes first vertex
p3dVertex = OdDb3dPolylineVertex::createObject();
p3dVertex->setPosition( OdGePoint3d(0.2, 0.3, 0.1) );
p3dPL->insertVertexAt(NULL, p3dVertex); // insert before first vertex, new vertex becomes first vertex
Two-dimensional and three-dimensional polylines provide two mechanisms for getting a vertex:
To get an iterator, use the vertexIterator() method which returns the iterator object. Next, use the start() method to set the iterator on the first vertex, step() method to move the iterator to the following vertex in the container, and done() method to check whether the iterator finishes the traversing. To get a vertex, use the entity() method of the iterator which returns a smart pointer to the current vertex that the iterator indicates, or NULL if the iterator is done. To get the properties of a vertex, the returned pointer must be converted to the OdDb2dVertex type for a two-dimensional vertex entity or OdDb3dPolylineVertex type for a three-dimensional vertex entity. Next, use the methods of the vertex entity for working with its properties.
For example, a two-dimensional polyline:
OdInt32 index;
OdGePoint3d ocs, wcs;
OdDb2dVertexPtr p2dVertex;
OdDbObjectIteratorPtr itVertex = p2dPL->vertexIterator();
for(itVertex->start(), index = 0 ; !itVertex->done() ; index++, itVertex->step())
{
p2dVertex = (OdDb2dVertexPtr)itVertex->entity();
ocs = p2dVertex->position();
wcs = p2dPL->vertexPosition(*p2dVertex);
odPrintConsoleString(L"\nVertex (%d) places in OCS(%g,%g), in WCS(%g,%g,%g)",
index, ocs.x, ocs.y, wcs.x, wcs.y, wcs.z);
}
For example, a three-dimensional polyline:
OdGePoint3d wcs;
OdDb3dPolylineVertexPtr p3dVertex;
OdDbObjectIteratorPtr itVertex = p3dPL->vertexIterator();
for(itVertex->start() ; !itVertex->done() ; itVertex->step())
{
p3dVertex = (OdDb3dPolylineVertexPtr)itVertex->entity();
wcs = p3dVertex->position();
odPrintConsoleString(L"\nVertex (%d) places in WCS(%g,%g,%g)",
p3dVertex->handle().ascii().c_str(), wcs.x, wcs.y, wcs.z);
}
Two-dimensional and three-dimensional polylines store their own vertices as independent entities in the container. Each entity gets an object ID when it is added to the database or is appended to the polyline container. Using an ID, the polyline can get a smart pointer to the vertex entity from its own container instead of traversing, but the ID must be associated with a vertex at first, that is, the two-dimensional or three-dimensional vertex entity must be appended to the two-dimensional or three-dimensional polyline entity. To get a vertex by ID, use the openVertex() method which requires an instance of the OdDbObjectId type associated with a vertex as the first argument, an instance of the OdDb::OpenMode type as the second argument, an erase status of a boolean type as the third optional argument, and returns a smart pointer to the vertex entity stored in the polyline container and associated with the specified object ID.
For example, a two-dimensional polyline:
OdDb2dVertexPtr p2dVertex = OdDb2dVertex::createObject();
p2dVertex->setPosition( OdGePoint3d(1.2, 3.4, 0) );
OdDbObjectId id2dVertex = p2dPL->appendVertex(p2dVertex);
p2dVertex = NULL;
OdDb2dVertexPtr p2dCorner = p2dPL->openVertex(id2dVertex, OdDb::kForWrite);
OdGePoint3d ocs = p2dCorner->position();
OdGePoint3d wcs = p2dPL->vertexPosition(*p2dCorner);
odPrintConsoleString(L"\nVertex (%d) places in OCS(%g,%g), in WCS(%g,%g,%g)",
p2dCorner->handle().ascii().c_str(), ocs.x, ocs.y, wcs.x, wcs.y, wcs.z);
For example, a three-dimensional polyline:
OdDbObjectId id3dVertex = p3dPL->appendVertex(OdDb3dPolylineVertex::createObject());
OdDb2dVertexPtr p3dCorner = p3dPL->openVertex(id3dVertex, OdDb::kForWrite);
OdGePoint3d wcs = p3dCorner->position();
odPrintConsoleString(L"\nVertex (%d) places in WCS(%g,%g,%g)",
p3dCorner->handle().ascii().c_str(), wcs.x, wcs.y, wcs.z);
A two-dimensional polyline allows association of an integer identifier with a vertex. The three-dimensional polyline does not use identifiers. Identifiers can be used for accessing a vertex. The initial value is zero by default.
To get an identifier of a vertex of a two-dimensional polyline, get the two-dimensional vertex entity using an iterator or object ID and use the vertexIdentifier() method of this vertex which returns its identifier as an integer type. For example:
OdInt32 id, index;
OdDbObjectIteratorPtr itVertex = p2dPL->vertexIterator();
for(itVertex->start(), index = 0 ; !itVertex->done() ; index++, itVertex->step())
{
id = ((OdDb2dVertexPtr)itVertex->entity())->vertexIdentifier();
odPrintConsoleString(L"\nVertex(%ld)ID = %ld", index, id);
}
To set an identifier for a vertex of a two-dimensional polyline, get the two-dimensional vertex entity using an iterator or object ID and use the setVertexIdentifier() method of this vertex which requires an identifier as an argument of an integer type. For example:
OdInt32 index;
OdDbObjectIteratorPtr itVertex = p2dPL->vertexIterator();
for(itVertex->start(), index = 0 ; !itVertex->done() ; index++, itVertex->step())
{
p2dPL->openVertex(itVertex->objectId(), OdDb::kForWrite)->setVertexIdentifier(0x8000 | index);
}
The location of a two-dimensional or three-dimensional polyline's vertices can be changed using the smart pointers to the corresponding vertex entities stored in the polyline's container. After relocating a vertex, the polyline changes its curve.
To relocate a vertex of a two-dimensional polyline, get the two-dimensional vertex entity using an iterator or object ID and use the setPosition() method of this vertex which requires new OCS coordinates for the vertex as an argument of the OdGePoint3d type. New coordinates for a vertex are two-dimensional in OCS, but this method specifies the new location as three-dimensional coordinates where the Z-coordinate is ignored. For example:
OdGePoint3d point3d;
OdDb2dVertexPtr p2dVertex;
OdDbObjectIteratorPtr itVertex = p2dPL->vertexIterator();
for(itVertex->start() ; !itVertex->done() ; itVertex->step())
{
p2dVertex = p2dPL->openVertex(itVertex->objectId(), OdDb::kForWrite);
point3d = p2dVertex->position();
point3d.x += 5; point3d.y -= 5;
p2dVertex->setPosition(point3d);
}
To relocate a vertex of a three-dimensional polyline, get the three-dimensional vertex entity using an iterator or object ID and use the setPosition() method of this vertex which requires new WCS coordinates for this vertex as an argument of the OdGePoint3d type. For example:
OdGePoint3d point3d;
OdDb3dPolylineVertexPtr p3dVertex;
OdDbObjectIteratorPtr itVertex = p3dPL->vertexIterator();
for(itVertex->start() ; !itVertex->done() ; itVertex->step())
{
p3dVertex = p3dPL->openVertex(itVertex->objectId(), OdDb::kForWrite);
point3d = p3dVertex->position();
point3d.x += 10; point3d.y -= 10; point3d.z *= 2;
p3dVertex->setPosition(point3d);
}
Deleting a vertex from a two-dimensional or three-dimensional polyline erases the entity from the database and the polyline's container. The number of vertices decreases by one.
To delete a vertex from a two-dimensional or three-dimensional polyline, get the required vertex entity for Write mode using an iterator or object ID and use the erase() method of this vertex, and pass it a "true" value as an argument. The erase() method returns an error code if this vertex entity is not deleted or zero if this vertex entity is deleted successfully. The vertex is deleted from the polyline object and database object together.
For example, a two-dimensional polyline:
// Continue example for inserting
p2dVertex = p2dPL->openVertex(id2dVertex2, OdDb::kForWrite);
OdResult result = p2dVertex->erase(true);
if(result)
odPrintConsoleString(L"\nError: %d - %s", result, p2dPL->database()->appServices()->getErrorDescription(result));
For example, a three-dimensional polyline:
// Continue example for inserting
p3dVertex = p3dPL->openVertex(id3dVertex3, OdDb::kForWrite);
OdResult result = p3dVertex->erase(true);
if(result)
odPrintConsoleString(L"\nError: %d - %s", result, p3dPL->database()->appServices()->getErrorDescription(result));
The reverseCurve() method reverses a two-dimensional or three-dimensional polyline curve, so that the first vertex becomes the last vertex, and vice versa. This method does not have arguments. A first call reverses the curve, and a second call returns it to its original curve. For example:
// 2D Polyline
p2dPL->reverseCurve();
// 3D Polyline
p3dPL->reverseCurve();
Overview of Two-Dimensional and Three-Dimensional Polylines
Types of Polylines and Vertices
Specific Properties of Polylines
Computed Properties of Polylines
Example of Working with Polylines
Copyright © 2002 – 2020. Open Design Alliance. All rights reserved.
|