Part 2 of 2: Generating Cut Geometry for Planar Clipping Boundaries

Andrew Markovich

September 05, 2019

This is the second article in a two-part series about how Kernel SDK supports cut geometry for planar clipping boundaries. For the first article, click here.

Using cut geometry generation together with section geometry

There is no limitation to using the cut geometry output interface together with the section geometry output interface, but to make output sections visible we need to customize the cut geometry to be transparent:

OdGiCuttedGeometryOutputPtr pTraitsSetsCutting = OdGiCuttedGeometryOutput::createObject();
  pTraitsSetsCutting->setTraitsOverrideFlags(OdGiSubEntityTraitsChangedFlags::kColorChanged | OdGiSubEntityTraitsChangedFlags::kMaterialChanged | OdGiSubEntityTraitsChangedFlags::kTransparencyChanged);
  pTraitsSetsCutting->traitsOverrides().setColor(5);
  pTraitsSetsCutting->traitsOverrides().setTransparency(OdCmTransparency(0.5));
  bnd.setCuttedGeometryOutput(pTraitsSetsCutting);

Now we can additionally attach the section output interface together with the cut geometry:

bnd.setSectionGeometryOutput(pTraitsSetsSection);
bnd.setCuttedGeometryOutput(pTraitsSetsCutting);

The following vectorized image has both geometries (blue semi-transparent cut geometry and red sections):

 

blue semi-transparent cut geometry and red sections

 

If your application invokes cut geometry and section geometry generation together, you should take into account the following rules for using the non-sectionable geometry clipping flag, which is available in both interfaces. This table show how the clipping engine interprets non-sectionable geometry flags if cut and section geometry output is set together:

Non-sectionable geometry clipping flag in section geometry output Non-sectionable geometry clipping flag in cut geometry output Final flag value invoked by clipping engine
false false false
false true true
true false true
true true true

So, if you want to disable non-sectionable geometry clipping, this flag must be set to ‘false’ for both output interfaces, otherwise non-sectionable geometry clipping is used by the clipping engine.

The following illustration shows usage of the non-sectionable geometry clipping flag to output section and cut geometry together in the sample file from the previous article’s “Disabling non-sectionable geometry clipping” section.

Disabling non-sectionable geometry clipping

 

Enabling sectioning for non-sectionable entities

To check whether the clipping engine correctly processes all types of geometry primitives (not only shells and polylines invoked by 3dSolid and other modeler entities), enable sectioning for all kinds of entities inside the database. For this task we can invoke overruling functionality:

class MakeSectionableDrawableOverrule : public OdStaticRxObject
{
  bool bMakeSectionable, b3dSolid, bSubDMesh, bOthers;
  public:
    MakeSectionableDrawableOverrule(bool makeSectionable, bool triDeSolid, bool subDMesh, bool others = false)
      : bMakeSectionable(makeSectionable), b3dSolid(triDeSolid), bSubDMesh(subDMesh), bOthers(others)
    {
      OdRxOverrule::setIsOverruling(true);
      if (bOthers) OdRxOverrule::addOverrule(OdDbEntity::desc(), this);
      if (b3dSolid) OdRxOverrule::addOverrule(OdDb3dSolid::desc(), this);
      if (bSubDMesh) OdRxOverrule::addOverrule(OdDbSubDMesh::desc(), this);
    }
    ~MakeSectionableDrawableOverrule()
    {
      if (bSubDMesh) OdRxOverrule::removeOverrule(OdDbSubDMesh::desc(), this);
      if (b3dSolid) OdRxOverrule::removeOverrule(OdDb3dSolid::desc(), this);
      if (bOthers) OdRxOverrule::removeOverrule(OdDbEntity::desc(), this);
      OdRxOverrule::setIsOverruling(false);
    }
    virtual bool isApplicable(const OdRxObject* pOverruledSubject) const
    {
      return true;
    }
    virtual OdUInt32 setAttributes(const OdGiDrawable* pSubject, OdGiDrawableTraits *traits)
    {
      OdUInt32 drawFlags = OdGiDrawableOverrule::setAttributes(pSubject, traits);
      OdGiSubEntityTraits *pTraits = OdGiSubEntityTraits::cast(traits);
      if (pTraits)
        pTraits->setSectionable(bMakeSectionable);
      return drawFlags;
    }
};

This helper class is invoked in an internal regression test and is used to make all types of entities sectionable. In the constructor, overruling is enabled for specific or all types of entities; in the destructor, the attached overruling is disabled. To overrule entity behavior for part of the code, we can add a single line of code:

MakeSectionableDrawableOverrule _over(true, false, false, true);
  // Vectorize database . . .

When we use this overruling for cutting geometry generation, we can see the following image for our sample drawing:

 

overruling for cutting geometry generation

 

The bottom-left and bottom-right images show that all entities aren’t clipped anymore and treated as sectionable, so the cut part of geometry was generated for them. Using this overruling technique we can enable or disable sectioning for any entity types separately, or for all types at the same time – this gives more flexible control for sectioning functionality.

Conclusion

Availability of cut geometry output includes a set of possible outputs for the clipping engine:

  • OdGiOrthoClipperEx::output() — Stable output for clipped geometry.
  • OdGiOrthoClipperEx::sectionOutput() — Optional output for section geometry.
  • OdGiOrthoClipperEx::cuttingOutput() — Optional output for cut geometry.

There are no limitations to invoke cut geometry output using OdGiOrthoClipperEx directly (OdGiGeometry::pushClipBoundary functionality limits usage of cut geometry output to planar clipping boundaries only); cut geometry can be generated for any kind of polygon clipping boundaries too.

Cut geometry rendering is a practical feature for applications based on ODA SDKs that support sectioning of 3D models and for engineering and modeling applications that want to extend the set of sectioning visualization effects.