Planar clipping sections generation for custom entities

Andrew Markovich

March 16, 2017

Teigha vectorization framework provides ability to clip geometry inside rendered scene, using OdGiOrthoClipperEx conveyor node which is always available inside default geometry vectorization conveyor. OdGiOrthoClipperEx conveyor node provides ability to generate planar geometry sections, so any application can invoke planar sections generation functionality without creating any additional objects and modifications inside geometry vectorization conveyor. This article describes simplest way to invoke planar clipping sections generation for native and custom database entities using Teigha vectorization framework API.

Sections generation support for custom entity

Custom database entity creation

For example we will use simple custom entity with minimal implementation which draws dodecahedron. The main thing which must be done to enable sections generation for entity is a following call:

// Enable sections generation

This call informs vectorization framework that sections can be generated for following geometry primitives, like shell, polygon or mesh.

Now we can attach our custom dodecahedron entity to working database:

void attachDodecahedronEntity(OdDbDatabase *pDb)
    OdSmartPtr<DodecahedronEntity> pEnt = DodecahedronEntity::createObject();
    pEnt->setValues(OdGePoint3d::kOrigin, 10.0);

If we render result (our database contains no other entities) we get picture like that:

Append planar clipping boundary

We can append any number of clipping boundaries directly inside entity subWorldDraw or subViewportDraw overridden methods using OdGiGeometry::pushClipBoundary and OdGiGeometry::popClipBoundary methods and this clipping boundaries will influence entity geometry and nested entities geometry. This technique is useful for database hierarchy, where we can apply clipping of entities inside blocks, but can’t be used in applications which require clipping of the entire drawing without modifications inside database entities. For this case (and to simplify our example application) we can attach clipping boundary directly to OdGsView object using setViewport3dClipping method, and this clipping boundary will be used to clip all contents inside this OdGsView object:

void appendClippingBoundary(OdGsView *pView)
{ // Setup clipping plane
    OdGiPlanarClipBoundary::ClipPlaneArray clipPlanes;
    clipPlanes.push_back(OdGiPlanarClipBoundary::ClipPlane(OdGePoint3d::kOrigin - OdGeVector3d::kYAxis * 4.0, OdGeVector3d::kYAxis));
    OdGiPlanarClipBoundary bnd; bnd.setClipPlanes(clipPlanes);
    // Setup viewport clipping
    OdGiClipBoundary emptyBoundary;
    pView->setViewport3dClipping(&emptyBoundary, &bnd);

We can specify set of clipping planes using OdGiPlanarClipBoundary class. In this example we keep OdGiClipBoundary object empty since clipping plane completely set in World Coordinates Space (WCS). If we will render clip result we will got picture like that:

Sections generation for clipping boundary

Enable sections generation for clipping boundary

To enable sections generation make following changes in our example appendClippingBoundary function:

OdGiPlanarClipBoundary bnd; bnd.setClipPlanes(clipPlanes);
// Setup traits resolver for section geometry
OdGiSectionGeometryOutputPtr pSectionGeometry = OdRxObjectImpl<OdGiSectionGeometryOutput>::createObject();
pSectionGeometry->setTraitsOverrideFlags(OdGiSubEntityTraitsChangedFlags::kColorChanged | OdGiSubEntityTraitsChangedFlags::kMaterialChanged);
// Setup viewport clipping

In this example we create OdGiSectionGeometryOutput object, which is used to handle section geometry onto application side. This object was attached to planar clipping boundary (OdGiPlanarClipBoundary). All generated closed and opened sections will come through this OdGiSectionGeometryOutput object, so we can customize properties and representation of output sections geometry.

If we will render result of our changes we will got picture like that:

Multiple clipping planes

We can use any number of clipping planes to generate geometry sections. For example, extend our appendClippingBoundary function by specifying secondary clipping plane:

clipPlanes.push_back(OdGiPlanarClipBoundary::ClipPlane(OdGePoint3d::kOrigin - OdGeVector3d::kYAxis * 4.0, OdGeVector3d::kYAxis));
// Secondary clipping plane
clipPlanes.push_back(OdGiPlanarClipBoundary::ClipPlane(OdGePoint3d::kOrigin + OdGeVector3d::kXAxis * 4.0, -OdGeVector3d::kXAxis));
OdGiPlanarClipBoundary bnd; bnd.setClipPlanes(clipPlanes);

The result of changes will look like that: