Hide menu


Drawings in CAD Exchanger data model are intended to represent 2D design documents associated with 3D models or existing in their own right (if they were generated by 2D CAD software). Drawings in general contain one or more sheets depicting the design in multiple views to capture all the necessary parts of it in 2D form.

Example of a technical drawing

Drawings are an integral part of DWG and DXF formats, and can be stored in other formats, such as CATIA, Creo, NX, SolidWorks.

Drawings API is currently in preview. To use it in C++ one must define the preprocessor macro __CADEX_PREVIEW_DRAWINGS to 1. As the API changes to accommodate the needs of users compatibility will be preserved as much as possible but is ultimately not guaranteed.

Structure of drawings

ModelData_Drawing is the key class encapsulating all the information for a drawing of a single model. ModelData_Model contains an object of this class if the imported model contained drawing data. The structure of drawings themselves is quite simple and consists of 2 types of elements - sheets and views. The diagram below illustrates the structure of a possible drawing:

Example of the structure of a two-sheet drawing

Here's how the original example from this article could be mapped into this structure:

Example of a drawing with its structure highlighted

Sheets are counterparts of physical sheets of paper used in real-world drawings. As such they have paper size and orientation. A single sheet may not be enough to capture all of the pertinent details of a 3D model, so a drawing often contains multiple sheets, each containing a few model views. ModelData_DrawingSheet class is used to represent this concept in CAD Exchanger.

A view is just that - depiction of the model from some side or angle. There exist multiple specific types of views in engineering practice (e.g. cut views, broken views, detail views). CAD Exchanger SDK does not differentiate between them and its ModelData_DrawingView serves as a container to capture the 2D geometry required to describe the appearance of the model from a given angle.

Layers are logical groups of drawing elements, and each element can be a part of only a single layer. Layers are used to organize objects in a drawing by their function or purpose. They allow to control properties such as visibility, line type or color for all objects within them. Note that ModelData_DrawingLayer class is used for layers in drawings, whereas ModelData_Layer is used for layers in 3D data.

The example drawing at the top of the page is composed of a single sheet with 4 views (3 side views and 1 isometric view).

Elements of drawings

The actual contents of drawings are 2D geometry, stored in instances of ModelData_DrawingView. CAD Exchanger's drawings are capable of representing 2D geometry in the form of curves (ModelData_DrawingCurveSet), piecewise contour (ModelData_DrawingPiecewiseContour) and points (ModelData_DrawingPointSet). These forms of geometry representation are complementary, meaning that a single view can contain a few elements of different types to completely describe the geometry of the view. This situation is different from the distinction between B-Rep and polygonal representations of parts in CAD Exchanger, because the latter is considered a set of alternative descriptions of the same shape.

Aside from the model geometry drawings can contain dimensions (ModelData_DrawingDimension), hatches (ModelData_DrawingHatch) and text blocks (ModelData_DrawingText). There are multiple types of dimensions available, please see the documentation for the classes derived from ModelData_DrawingDimension to learn how these types are defined.

Generally, drawings contain other types of data too, most importantly various annotations - notes, multileaders, tables, etc. These are currently not representable with CAD Exchanger drawings but may be added in the future.


ModelData_DrawingView contains shared appearances of the drawing elements. ModelData_DrawingView::ElementAppearance() returns element's own appearance if it exists otherwise returns layer's appearance.

The appearance for drawing element defines how this object should be visualized and contain the following components:

  • generic color.
  • line styles.
See also
Visual Appearances


Drawing structure

The drawing structure is fixed and there are only 2 levels of nesting. SheetIterator and ViewIterator are provided for structure classes to enable the traversal of their child entities. A general strategy for applying these iterators is shown below:

ModelData_Drawing aDrawing = /* ... */;
for (ModelData_Drawing::SheetIterator anIt1 (aDrawing); anIt1.HasNext();) {
ModelData_DrawingSheet aSheet = anIt1.Next();
/* process sheet... */
for (ModelData_DrawingSheet::ViewIterator anIt2 (aSheet); anIt2.HasNext();) {
ModelData_DrawingView aView = anIt2.Next();
/* process view... */
for (ModelData_Drawing::LayerIterator anIt3 (aDrawing); anIt3.HasNext();) {
ModelData_DrawingLayer aLayer = anIt3.Next();
/* process layer... */

Drawing contents

Once you have an object of ModelData_DrawingView class, its contents can be accessed either with an iterator or with a visitor. ElementIterator can be used if all the elements need to be processed uniformly, without regard for their specific type, or when an element at a specific position needs to be retrieved. See below for an example of using an iterator:

ModelData_DrawingView aView = /* ... */;
size_t anElemIndex = 5;
size_t anIndex = 0;
for (ModelData_DrawingView::ElementIterator anIt (aView); anIt.HasNext(); anIndex++) {
ModelData_DrawingElement anElem = anIt.Next();
if (anIndex == anElemIndex) {
/* process the required element... */

ModelData_DrawingElementVisitor makes sense for all the other cases, when the type of the drawing element matters, or when only some types have to be processed. ModelData_DrawingElementVoidVisitor is also provided to simplify the implementation of derived class in the latter case. Here's how to use it to count only the 2D analytical curves in the view:

class AnalyticalCurveCounter : public ModelData_DrawingElementVoidVisitor
void operator (ModelData_DrawingCurveGeometry& theElement) override
myCurveCount += theElement.NumberOfCurves();
size_t myCurveCount = 0;
ModelData_DrawingView aView = /* ... */;
AnalyticalCurveCounter aCounter;
aView.Accept (aCounter);
/* use aCounter.myCurveCount... */