Share

AcDbHatch

Class Hierarchy

AcRxObject
    AcGiDrawable
        AcDbObject
            AcDbEntity
                AcDbHatch

C++

class AcDbHatch : public AcDbEntity;

File

dbhatch.h

Description

AcDbHatch is a planar entity that can be created and placed in an arbitrary plane in 3D space.

The hatch plane can be uniquely defined by a normal vector in WCS (World Coordinate System) and an elevation indicating the distance from the WCS origin to the hatch plane. The hatch plane adopts a standard AutoCAD object coordinate system (OCS). Its origin coincides with the WCS origin and its X and Y axes are calculated using the arbitrary axis algorithm.

The hatch boundary defines the area to be filled with the specified hatch pattern. The internal representation of the hatch boundary consists of a set of planar loops. Each loop is made of a collection of 2D edges of line, circular arc, elliptic arc and spline. If the hatch boundary contains two or more loops, the areas enclosed by individual loops must be completely disjoint or one will completely enclose the other.

A loop must be simple, closed, and continuous, intersecting itself only at its endpoints. Furthermore, its start point and end point must coincide. When defining the hatch boundary, the application must ensure that the loops and edges are well defined and structured. If the boundary contains two or more loops, they must be organized into a nested structure in which the external loop is constructed first, then followed by all its internal loops in nested order. If there is more than one external loop, repeat the process. AutoCAD provides limited validation of the hatch boundary in order to maintain API efficiency and performance.

The internal representations of hatch boundary edges are GELIB 2D geometry, including AcGeLineSeg2d, AcGeCircArc2d, AcGeEllipArc2d and AcGeNurbCurve2d. If the hatch boundary consists of a polyline, special methods are provided to construct the loop.

Associative hatching allows the application to create a hatch entity that is associative to the boundaries of existing AutoCAD database entities, including LINE, ARC, CIRCLE, ELLIPSE, SPLINE, POLYLINE, TEXT, MTEXT, ATTRIBUTE DEFINITION, ATTRIBUTE, SHAPE, SOLID, TRACE, TOLERANCE, REGION, VIEWPORT, 3D FACE, BLOCK INSERT, XREF, LWPOLYLINE, RASTER etc. When you edit the source geometry, the hatch entity will adapt to the changes automatically.

When using a custom entity, you must define an explode method in order for the hatching to work. Your explode method should break your entity down into less complicated entities.

When defining a hatch boundary using existing database entities, the application must ensure that the selected objects have a valid hatch boundary and are coplanar with the hatch plane. The selected objects must also form well-defined loops. You also need to set the associativity flag before you set the hatch boundary. insertLoopAt() and appendLoop() methods will extract the geometry from database objects and maintain the database object IDs with the loop structure for associative hatch.

If the hatch boundary contains two or more loops for a solid fill operation, the areas enclosed by the individual loops must be completely disjoint or one will completely enclose the other. Also, each loop must be simple, closed, and continuous, in which it intersects itself only at its endpoints. If the hatch boundary does not meet these requirements, the results may be unpredictable and inconsistent between the regular hatch and the solid fill pattern.

Mlines are complex entities that can produce more than one loop, which means they will be rejected as hatch boundaries. If you use the AcDbHatch API and select an AcDbMline object to be hatched, no hatching will be displayed, and appendloop() will return eInvalidInput. To work around this, you can explode the mline, get the resulting edges, and produce loops from them. If AcDbMline::explode() produces a set of edges that do not form a single closed loop, you can create a region by using the edges to construct an AcDbRegion object. You can then explode the region to get simple closed loops, and pass those loops to the AcDbHatch object.

Your application should check the return status of each API call and delete the hatch entity if the status is eInvalidInput.

Currently, AutoCAD supports three hatch pattern types that are User-defined, Predefined, and Custom. See the HatchPatternType enum for more information.

The following methods enable the application to set and get hatch pattern-related data. If you call AcDbHatch::setPatternScale() (or any of the pattern methods), the scale value changes but the pattern does not change on the display. This is by design. You need to call AcDbHatch::setPattern() after changing the pattern scale, angle, name, etc. One call to this function is sufficient for all combinations of pattern changes.

AutoCAD currently supports three hatch styles, which are Normal, Outer, and Ignore. See the HatchStyle enum for more information.

The following methods provide the application to set and get hatch style. These methods are provided for compatibility purposes; it is recommended to always use Normal style.

AcDbHatch::HatchStyle style() const;
Acad::ErrorStatus setStyle(AcDbHatch::HatchStyle hstyle);

After defining the hatch boundary and specifying the hatch pattern and style, the application must elaborate the hatch lines or solid fill for display. The AcDbHatch class implementation maintains the computed hatch lines and solid fill to support worldDraw() and viewportDraw() methods for hatch entity display. However, the computed hatch lines and solid fill are not saved with the drawing or DXF files for file size efficiency. Instead, AutoCAD recomputes the hatch lines or solid fill when a DWG or DXF file is opened by AutoCAD.

If the hatch boundary definition loops or edges get changed or removed, the application must re-elaborate the hatch lines or solid fill to update the display.

The hatch boundary definition loops and edges are not displayed. This should not present a problem because the hatch entity is always associative with existing geometry in the AutoCAD database in most cases.

Notes

AutoCAD always assumes that the x-axis for an AcGeCircArc2d hatch boundary is an AcGeVector2d of (1.0, 0.0). Also,calling the explode function on a solid hatch will cause eNotApplicable to be returned.

Example

The following samples have not been compiled or debugged, and may contain syntax errors. They show the procedure for acquiring AcDbHatch entities in the API environment.

The following example shows how to acquire a hatch entity on the WCS XY plane. The hatch boundary consists of an external rectangular loop with an internal circular hole. The hatch pattern is SOLID with current AutoCAD default color. The newly created hatch is not associative.

Acad::ErrorStatus acqHatch1()
{
    AcDbHatch* pHatch = new AcDbHatch();
    // Set hatch plane
    //
    AcGeVector3d normal(0.0, 0.0, 1.0);
    pHatch->setNormal(normal);
    pHatch->setElevation(0.0);

    // Set non associative hatch
    //
    pHatch->setAssociative(Adesk::kFalse);

    // Set hatch pattern to SolidFill type
    //
    pHatch->setPattern(AcDbHatch::kPreDefined, "SOLID");

    // Set hatch style to kNormal
    //
    pHatch->setHatchStyle(AcDbHatch::kNormal);

    // Construct hatch external boundary
    //
    AcGePoint2dArray vertexPts;
    AcGeDoubleArray vertexBulges;
    vertexPts.setPhysicalLength(0).setLogicalLength(5);
    vertexPts[0].set(2.0, 2.0);
    vertexPts[1].set(8.0, 2.0);
    vertexPts[2].set(8.0, 8.0);
    vertexPts[3].set(2.0, 8.0);
    vertexPts[4].set(2.0, 2.0);
    vertexBulges.setPhysicalLength(0).setLogicalLength(5);
    for (int i = 0; i < 5; i++)
        vertexBulges[i] = 0.0;

    // Append an external loop (rectangle) to hatch boundary

    pHatch->appendLoop(AcDbHatch::kExternal, vertexPts, vertexBulges);

    // Construct a circle
    //
    AcGePoint2d cenPt(5.0, 5.0);
    double TWOPI = 2.0 * 3.1415926535897932;
    AcGeCircArc2d *cirArc = new AcGeCircArc2d();
    cirArc->setCenter(cenPt);
    cirArc->setRadius(1.0);
    cirArc->setAngles(0.0, TWOPI);

    // Append an internal circular loop to hatch boundary
    //
    AcGeIntArray edgeTypes;
    AcGeVoidPointerArray edgePtrs;
    edgeTypes.append(AcDbHatch::kCirArc);
    edgePtrs.append((void*)cirArc);
    pHatch->appendLoop(AcDbHatch::kDefault, edgePtrs, edgeTypes);

    // Elaborate solid fill
    //
    pHatch->evaluateHatch();

    // Post hatch entity to database
    //
   AcDbObjectId newId;
    postToModelSpace(pHatch, newId);

    return eOk;
}

The following example shows how to acquire an associative hatch entity on the WCS XY plane. The hatch boundary consists of an external rectangular loop with an internal circular hole. The hatch pattern is the ANSI31 predefined type with current AutoCAD default color. The newly created hatch is associative, in which you can change the source boundary geometry to update the hatch pattern.

Acad::ErrorStatus acqHatch2()
{
    AcDbHatch* pHatch = new AcDbHatch();
    // Set hatch plane
    //
    AcGeVector3d normal(0.0, 0.0, 1.0);
    pHatch->setNormal(normal);
    pHatch->setElevation(0.0);

    // Set hatch pattern to ANSI31 predefined type
    //
    pHatch->setHatchPattern(AcDbHatch::kPreDefined, "ANSI31");

    // Set Associativity
    //
    pHatch->setAssociative(Adesk::kTrue);

    // Construct database AcDbLines
    //
    AcGePoint2d vertexPts[4];
    AcDbObjectId lineId, cirId, hatchId;
    AcDbObjectIdArray dbObjIds;
    AcDbLine *line;
    vertexPts[0].set(2.0, 2.0, 0.0);
    vertexPts[1].set(8.0, 2.0, 0.0);
    vertexPts[2].set(8.0, 8.0, 0.0);
    vertexPts[3].set(2.0, 8.0, 0.0);

    for (int i = 0; i < 4; i++) {
        line =  new AcDbLine();
        line->setStartPoint(vertexPts[i])
        line->setEndPoint(vertexPts[(i == 3) ? 0 : i+1])
        line->postToDb(line, lineId);
        dbObjIds.append(lineId);
    }

    // Append an external rectangular loop to hatch boundary
    //
    pHatch->appendLoop(AcDbHatch::kExternal, dbObjIds);

    // Create a AcDbCircle and post it to database
    //
    AcGePoint2d cenPt(5.0, 5.0, 0.0);
    AcGeVector3d normal(0.0, 0.0, 1.0);
    AcDbCircle *circle = new AcDbCircle();
    circle->setNormal(normal);
    circle->setCenter(cenPt);
    circle->setRadius(1.0);
    circle->postToDb(circle, cirId);
    dbObjIds.setLogicalLength(0);
    dbObjIds.append(cirId);

    // Append an internal loop (circle) to hatch boundary
    //
    pHatch->appendLoop(AcDbHatch::kDefault, dbObjIds);

    // Elaborate hatch lines
    //
    pHatch->evaluateHatch();

    // Get all associative source boundary object Ids for later use.
    //
    dbObjIds.setLogicalLength(0);
    pHatch->getAssocObjIds(dbObjIds);

    // Post hatch entity to database
    //
    pHatch->postToDb(pHatch, hatchId);

    // Attach hatchId to all source boundary objects for notification.
    //
    AcDbEntity *pEnt;
    int numObjs = dbObjIds.length();
    Acad::ErrorStatus es;
    for (i = 0; i < numObjs; i++) {
        es = acdbOpenAcDbEntity(pEnt, dbObjIds[i], AcDb::kForWrite);
        if (es == Acad::eOk) {
            pEnt->addPersistentReactor(hatchId);
            pEnt->close();
        }
    }
    return eOk;
}

Links

AcDbHatch Enumerations, AcDbHatch Methods

Was this information helpful?