///////////////////////////////////////////////////////////////////////////////
|
// Copyright (C) 2002-2016, Open Design Alliance (the "Alliance").
|
// All rights reserved.
|
//
|
// This software and its documentation and related materials are owned by
|
// the Alliance. The software may only be incorporated into application
|
// programs owned by members of the Alliance, subject to a signed
|
// Membership Agreement and Supplemental Software License Agreement with the
|
// Alliance. The structure and organization of this software are the valuable
|
// trade secrets of the Alliance and its suppliers. The software is also
|
// protected by copyright law and international treaty provisions. Application
|
// programs incorporating this software must include the following statement
|
// with their copyright notices:
|
//
|
// This application incorporates Teigha(R) software pursuant to a license
|
// agreement with Open Design Alliance.
|
// Teigha(R) Copyright (C) 2002-2016 by Open Design Alliance.
|
// All rights reserved.
|
//
|
// By use of this software, its documentation or related materials, you
|
// acknowledge and accept the above terms.
|
///////////////////////////////////////////////////////////////////////////////
|
|
#ifndef __ODGIFACEEDGEDATATRAITSSAVER_H__
|
#define __ODGIFACEEDGEDATATRAITSSAVER_H__
|
|
#include "Gi/GiGeometry.h"
|
#include "Gi/GiCommonDraw.h"
|
#include "Gi/GiConveyorGeometry.h"
|
|
// Uncomment to enable selection marker restore on exit
|
//#define EX_TRAITS_SELMARK_RESTORE
|
// Uncomment to enable onTraitsModified call on exit
|
//#define EX_TRAITS_TRAITSMOD_ONEXIT
|
// Uncomment to enable traits restoration on exit
|
#define EX_TRAITS_RESTORE_ONEXIT
|
|
#ifdef EX_TRAITS_SELMARK_RESTORE
|
#include "Gi/GiPathNode.h"
|
#endif
|
|
#ifdef EX_TRAITS_TRAITSMOD_ONEXIT
|
#define EX_TRAITS_TRAITSMOD_ONEXIT_SET() \
|
bModified = true
|
#else // EX_TRAITS_TRAITSMOD_ONEXIT
|
#define EX_TRAITS_TRAITSMOD_ONEXIT_SET()
|
#endif // EX_TRAITS_TRAITSMOD_ONEXIT
|
|
#ifdef EX_TRAITS_RESTORE_ONEXIT
|
#define EX_TRAITS_SET(prevStorage, curStorage, param) \
|
prevStorage = curStorage = param
|
#define EX_TRAITS_DEFINE(type, prevStorage, curStorage) \
|
type prevStorage, curStorage
|
#define EX_TRAITS_DEFINE_PTR(type, prevStorage, curStorage) \
|
type prevStorage, *curStorage
|
#else // EX_TRAITS_RESTORE_ONEXIT
|
#define EX_TRAITS_SET(prevStorage, curStorage, param) \
|
curStorage = param
|
#define EX_TRAITS_DEFINE(type, prevStorage, curStorage) \
|
type curStorage
|
#define EX_TRAITS_DEFINE_PTR(type, prevStorage, curStorage) \
|
type curStorage
|
#ifdef EX_TRAITS_SELMARK_RESTORE
|
#undef EX_TRAITS_SELMARK_RESTORE
|
#endif // EX_TRAITS_SELMARK_RESTORE
|
#endif
|
|
class OdGiFaceEdgeDataTraitsSaverBase
|
{
|
protected:
|
enum Components
|
{
|
// LoWord - FaceTraits
|
kFaceColors = (1 << 0),
|
kFaceTrueColors = (1 << 1),
|
kFaceLayers = (1 << 2),
|
kFaceSelectionMarkers = (1 << 3),
|
kFaceMaterials = (1 << 4),
|
kFaceMappers = (1 << 5),
|
kFaceTransparencies = (1 << 6),
|
kFaceVisibilities = (1 << 7),
|
kFaceSelMarkAvail = (1 << 8),
|
kFaceSelMarkOnModify = (1 << 9),
|
// HiWord - EdgeTraits
|
kEdgeColors = (1 << 16),
|
kEdgeTrueColors = (1 << 17),
|
kEdgeLayers = (1 << 18),
|
kEdgeLinetypes = (1 << 19),
|
kEdgeSelectionMarkers = (1 << 20),
|
kEdgeVisibilities = (1 << 21),
|
kEdgeSelMarkAvail = (1 << 22),
|
kEdgeSelMarkOnModify = (1 << 23),
|
// Masks
|
kFaceMask = 0x0000FFFF,
|
kEdgeMask = 0xFFFF0000,
|
// Mask used for restore traits state
|
#ifdef EX_TRAITS_SELMARK_RESTORE
|
kFaceRestoreMask = kFaceMask & ~kFaceVisibilities,
|
kEdgeRestoreMask = kEdgeMask & ~kEdgeVisibilities,
|
#else
|
kFaceRestoreMask = kFaceMask & ~(kFaceVisibilities | kFaceSelectionMarkers | kFaceSelMarkOnModify),
|
kEdgeRestoreMask = kEdgeMask & ~(kEdgeVisibilities | kEdgeSelectionMarkers | kEdgeSelMarkOnModify),
|
#endif
|
// Mask used for reset traits state
|
kFaceSetMask = kFaceMask & ~kFaceVisibilities,
|
kEdgeSetMask = kEdgeMask & ~kEdgeVisibilities
|
};
|
protected:
|
OdGiSubEntityTraits *m_pTraits;
|
OdGiConveyorContext *m_pDrawCtx;
|
OdGsView::RenderMode m_renderMode;
|
OdUInt32 m_components;
|
EX_TRAITS_DEFINE(OdCmEntityColor, m_prevTrueColor, m_curTrueColor);
|
EX_TRAITS_DEFINE_PTR(OdDbStub*, m_prevLayerId, m_curLayerId);
|
#ifdef EX_TRAITS_SELMARK_RESTORE
|
OdGsMarker m_prevSelectionMarker;
|
#endif // EX_TRAITS_SELMARK_RESTORE
|
protected:
|
OdGiFaceEdgeDataTraitsSaverBase(OdGiSubEntityTraits *pTraits, OdGiConveyorContext *pDrawCtx, OdGsView::RenderMode renderMode)
|
: m_pTraits(pTraits), m_pDrawCtx(pDrawCtx), m_renderMode(renderMode), m_components(0)
|
{
|
}
|
// The default constructor will be used for virtual inheritance
|
OdGiFaceEdgeDataTraitsSaverBase()
|
: m_pTraits(NULL), m_pDrawCtx(NULL), m_renderMode(OdGsView::k2DOptimized), m_components(0)
|
{
|
}
|
|
bool setColor(const OdUInt16* pColors, int index)
|
{
|
OdCmEntityColor trueColor; trueColor.setColorIndex(pColors[index]);
|
if (m_curTrueColor != trueColor)
|
{
|
m_curTrueColor = trueColor;
|
m_pTraits->setColor(pColors[index]);
|
return true;
|
}
|
return false;
|
}
|
bool setTrueColor(const OdCmEntityColor* pTrueColors, int index)
|
{
|
if (m_curTrueColor != pTrueColors[index])
|
{
|
m_pTraits->setTrueColor(m_curTrueColor = pTrueColors[index]);
|
return true;
|
}
|
return false;
|
}
|
bool setLayer(OdDbStub **pLayers, int index)
|
{
|
if (m_curLayerId != pLayers[index])
|
{
|
m_pTraits->setLayer(m_curLayerId = pLayers[index]);
|
return true;
|
}
|
return false;
|
}
|
|
bool needExit() const { return m_renderMode != OdGsView::k2DOptimized; }
|
};
|
|
class OdGiFaceDataTraitsSaver : protected virtual OdGiFaceEdgeDataTraitsSaverBase
|
{
|
protected:
|
const OdGiFaceData *m_pFaceData;
|
EX_TRAITS_DEFINE_PTR(OdDbStub*, m_prevMaterialId, m_curMaterialId);
|
EX_TRAITS_DEFINE_PTR(const OdGiMapper*, m_prevMapper, m_curMapper);
|
EX_TRAITS_DEFINE( OdCmTransparency, m_prevTransparency, m_curTransparency);
|
public:
|
OdGiFaceDataTraitsSaver(const OdGiFaceData *pFaceData, OdGiSubEntityTraits *pTraits, OdGiConveyorContext *pDrawCtx,
|
OdGsView::RenderMode renderMode, bool bForEdge = false)
|
: OdGiFaceEdgeDataTraitsSaverBase(pTraits, pDrawCtx, renderMode), m_pFaceData(pFaceData)
|
{
|
if (pFaceData && pTraits)
|
{
|
if (pFaceData->colors())
|
{
|
EX_TRAITS_SET(m_prevTrueColor, m_curTrueColor, pTraits->trueColor());
|
SETBIT_1(m_components, kFaceColors);
|
}
|
if (pFaceData->trueColors())
|
{
|
EX_TRAITS_SET(m_prevTrueColor, m_curTrueColor, pTraits->trueColor());
|
SETBIT_1(m_components, kFaceTrueColors);
|
}
|
if (pFaceData->layerIds())
|
{
|
EX_TRAITS_SET(m_prevLayerId, m_curLayerId, pTraits->layer());
|
SETBIT_1(m_components, kFaceLayers);
|
}
|
if (pFaceData->selectionMarkers())
|
{
|
#ifdef EX_TRAITS_SELMARK_RESTORE
|
if (pDrawCtx->currentGiPath())
|
{
|
m_prevSelectionMarker = pDrawCtx->currentGiPath()->selectionMarker();
|
SETBIT_1(m_components, kFaceSelMarkAvail);
|
}
|
#endif // EX_TRAITS_SELMARK_RESTORE
|
SETBIT_1(m_components, kFaceSelectionMarkers);
|
if (GETBIT(pDrawCtx->drawContextFlags(), OdGiConveyorContext::kForceMarkersOnModified))
|
SETBIT_1(m_components, kFaceSelMarkOnModify);
|
}
|
if (!bForEdge)
|
{
|
if (pFaceData->materials())
|
{
|
EX_TRAITS_SET(m_prevMaterialId, m_curMaterialId, pTraits->material());
|
SETBIT_1(m_components, kFaceMaterials);
|
}
|
if (pFaceData->mappers())
|
{
|
EX_TRAITS_SET(m_prevMapper, m_curMapper, pTraits->mapper());
|
#ifdef EX_TRAITS_RESTORE_ONEXIT
|
// Mapper can point onto internal storage which is similar always, we need store data itself
|
if (m_prevMapper) m_prevMapper = new OdGiMapper(*m_curMapper);
|
#endif // EX_TRAITS_RESTORE_ONEXIT
|
SETBIT_1(m_components, kFaceMappers);
|
}
|
}
|
if (pFaceData->transparency())
|
{
|
EX_TRAITS_SET(m_prevTransparency, m_curTransparency, pTraits->transparency());
|
SETBIT_1(m_components, kFaceTransparencies);
|
}
|
if (pFaceData->visibility())
|
SETBIT_1(m_components, kFaceVisibilities);
|
}
|
}
|
|
#ifdef EX_TRAITS_RESTORE_ONEXIT
|
bool onExit()
|
{
|
bool bModified = false;
|
if (m_components & kFaceRestoreMask)
|
{
|
if (GETBIT(m_components, kFaceColors | kFaceTrueColors) && (m_prevTrueColor != m_curTrueColor))
|
{
|
m_pTraits->setTrueColor(m_prevTrueColor);
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
if (GETBIT(m_components, kFaceLayers) && (m_prevLayerId != m_curLayerId))
|
{
|
m_pTraits->setLayer(m_prevLayerId);
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
#ifdef EX_TRAITS_SELMARK_RESTORE
|
if (GETBIT(m_components, kFaceSelMarkAvail))
|
{
|
m_pTraits->setSelectionMarker(m_prevSelectionMarker);
|
if (GETBIT(m_components, kFaceSelMarkOnModify))
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
#endif // EX_TRAITS_SELMARK_RESTORE
|
if (GETBIT(m_components, kFaceMaterials) && (m_prevMaterialId != m_curMaterialId))
|
{
|
m_pTraits->setMaterial(m_prevMaterialId);
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
if (GETBIT(m_components, kFaceMappers))
|
{ // If mappers is specified them will be different always
|
m_pTraits->setMapper(m_prevMapper);
|
if (m_prevMapper) delete m_prevMapper;
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
if (GETBIT(m_components, kFaceTransparencies) && (m_prevTransparency != m_curTransparency))
|
{
|
m_pTraits->setTransparency(m_prevTransparency);
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
}
|
return bModified;
|
}
|
bool needExit() const
|
{
|
if (!OdGiFaceEdgeDataTraitsSaverBase::needExit())
|
{
|
if (GETBIT(m_components, kFaceMappers) && m_prevMapper)
|
delete m_prevMapper;
|
return false;
|
}
|
return true;
|
}
|
~OdGiFaceDataTraitsSaver()
|
{
|
if (needExit() && onExit())
|
m_pDrawCtx->onTraitsModified();
|
}
|
#endif // EX_TRAITS_RESTORE_ONEXIT
|
|
bool setFaceTraits(int faceIndex)
|
{
|
if (!(m_components & kFaceMask))
|
return true;
|
|
if (GETBIT(m_components, kFaceSelectionMarkers))
|
m_pTraits->setSelectionMarker(m_pFaceData->selectionMarkers()[faceIndex]);
|
|
if (GETBIT(m_components, kFaceVisibilities) && (m_pFaceData->visibility()[faceIndex] == kOdGiInvisible))
|
return false;
|
|
if (m_components & kFaceSetMask)
|
{
|
bool bModified = GETBIT(m_components, kFaceSelMarkOnModify);
|
if (GETBIT(m_components, kFaceColors))
|
bModified |= setColor(m_pFaceData->colors(), faceIndex);
|
if (GETBIT(m_components, kFaceTrueColors))
|
bModified |= setTrueColor(m_pFaceData->trueColors(), faceIndex);
|
if (GETBIT(m_components, kFaceLayers))
|
bModified |= setLayer(m_pFaceData->layerIds(), faceIndex);
|
if (GETBIT(m_components, kFaceMaterials))
|
{
|
OdDbStub **pMaterials = m_pFaceData->materials();
|
if (m_curMaterialId != pMaterials[faceIndex])
|
{
|
m_pTraits->setMaterial(m_curMaterialId = pMaterials[faceIndex]);
|
bModified = true;
|
}
|
}
|
if (GETBIT(m_components, kFaceMappers))
|
{
|
const OdGiMapper* pMappers = m_pFaceData->mappers();
|
m_pTraits->setMapper(m_curMapper = (pMappers + faceIndex));
|
bModified = true;
|
}
|
if (GETBIT(m_components, kFaceTransparencies))
|
{
|
const OdCmTransparency* pTransparencies = m_pFaceData->transparency();
|
if (m_curTransparency != pTransparencies[faceIndex])
|
{
|
m_pTraits->setTransparency(m_curTransparency = pTransparencies[faceIndex]);
|
bModified = true;
|
}
|
}
|
if (m_pDrawCtx->effectivelyVisible())
|
{
|
if (bModified)
|
m_pDrawCtx->onTraitsModified();
|
return true;
|
}
|
else
|
return false;
|
}
|
|
return m_pDrawCtx->effectivelyVisible();
|
}
|
|
bool hasData() const { return (m_components & kFaceMask) != 0; }
|
};
|
|
class OdGiEdgeDataTraitsSaver : protected virtual OdGiFaceEdgeDataTraitsSaverBase
|
{
|
protected:
|
const OdGiEdgeData *m_pEdgeData;
|
EX_TRAITS_DEFINE_PTR(OdDbStub*, m_prevLinetypeId, m_curLinetypeId);
|
public:
|
OdGiEdgeDataTraitsSaver(const OdGiEdgeData *pEdgeData, OdGiSubEntityTraits *pTraits, OdGiConveyorContext *pDrawCtx,
|
OdGsView::RenderMode renderMode, bool bFaceChk = false)
|
: OdGiFaceEdgeDataTraitsSaverBase(pTraits, pDrawCtx, renderMode), m_pEdgeData(pEdgeData)
|
{
|
if (pEdgeData && pTraits)
|
{
|
if (pEdgeData->colors())
|
{
|
if (!bFaceChk || !GETBIT(m_components, kFaceColors | kFaceTrueColors))
|
EX_TRAITS_SET(m_prevTrueColor, m_curTrueColor, pTraits->trueColor());
|
SETBIT_1(m_components, kEdgeColors);
|
}
|
if (pEdgeData->trueColors())
|
{
|
if (!bFaceChk || !GETBIT(m_components, kFaceColors | kFaceTrueColors))
|
EX_TRAITS_SET(m_prevTrueColor, m_curTrueColor, pTraits->trueColor());
|
SETBIT_1(m_components, kEdgeTrueColors);
|
}
|
if (pEdgeData->layerIds())
|
{
|
if (!bFaceChk || !GETBIT(m_components, kFaceLayers))
|
EX_TRAITS_SET(m_prevLayerId, m_curLayerId, pTraits->layer());
|
SETBIT_1(m_components, kEdgeLayers);
|
}
|
if (pEdgeData->linetypeIds())
|
{
|
EX_TRAITS_SET(m_prevLinetypeId, m_curLinetypeId, pTraits->lineType());
|
SETBIT_1(m_components, kEdgeLinetypes);
|
}
|
if (pEdgeData->selectionMarkers())
|
{
|
#ifdef EX_TRAITS_SELMARK_RESTORE
|
if ((!bFaceChk || !GETBIT(m_components, kFaceSelectionMarkers)) && pDrawCtx->currentGiPath())
|
{
|
m_prevSelectionMarker = pDrawCtx->currentGiPath()->selectionMarker();
|
SETBIT_1(m_components, kEdgeSelMarkAvail);
|
}
|
#endif // EX_TRAITS_SELMARK_RESTORE
|
SETBIT_1(m_components, kEdgeSelectionMarkers);
|
if (!bFaceChk || !GETBIT(m_components, kFaceSelectionMarkers))
|
{
|
if (GETBIT(pDrawCtx->drawContextFlags(), OdGiConveyorContext::kForceMarkersOnModified))
|
SETBIT_1(m_components, kEdgeSelMarkOnModify);
|
}
|
else if (GETBIT(m_components, kFaceSelMarkOnModify))
|
SETBIT_1(m_components, kEdgeSelMarkOnModify);
|
}
|
if (pEdgeData->visibility())
|
SETBIT_1(m_components, kEdgeVisibilities);
|
}
|
}
|
|
#ifdef EX_TRAITS_RESTORE_ONEXIT
|
bool onExit(bool bFaceChk = false)
|
{
|
bool bModified = false;
|
if (m_components & kEdgeRestoreMask)
|
{
|
if (GETBIT(m_components, kEdgeColors | kEdgeTrueColors) &&
|
(!bFaceChk || !GETBIT(m_components, kFaceColors | kFaceTrueColors)) && (m_prevTrueColor != m_curTrueColor))
|
{
|
m_pTraits->setTrueColor(m_prevTrueColor);
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
if (GETBIT(m_components, kEdgeLayers) &&
|
(!bFaceChk || !GETBIT(m_components, kFaceLayers)) && (m_prevLayerId != m_curLayerId))
|
{
|
m_pTraits->setLayer(m_prevLayerId);
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
if (GETBIT(m_components, kEdgeLinetypes) && (m_prevLinetypeId != m_curLinetypeId))
|
{
|
m_pTraits->setLineType(m_prevLinetypeId);
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
#ifdef EX_TRAITS_SELMARK_RESTORE
|
if (GETBIT(m_components, kEdgeSelMarkAvail) &&
|
(!bFaceChk || !GETBIT(m_components, kFaceSelectionMarkers)))
|
{
|
m_pTraits->setSelectionMarker(m_prevSelectionMarker);
|
if (GETBIT(m_components, kEdgeSelMarkOnModify))
|
EX_TRAITS_TRAITSMOD_ONEXIT_SET();
|
}
|
#endif // EX_TRAITS_SELMARK_RESTORE
|
}
|
return bModified;
|
}
|
~OdGiEdgeDataTraitsSaver()
|
{
|
if (needExit() && onExit())
|
m_pDrawCtx->onTraitsModified();
|
}
|
#endif // EX_TRAITS_RESTORE_ONEXIT
|
|
bool setEdgeTraits(int edgeIndex)
|
{
|
if (!(m_components & kEdgeMask))
|
return true;
|
|
if (GETBIT(m_components, kEdgeSelectionMarkers))
|
m_pTraits->setSelectionMarker(m_pEdgeData->selectionMarkers()[edgeIndex]);
|
|
if (GETBIT(m_components, kEdgeVisibilities) && (m_pEdgeData->visibility()[edgeIndex] == kOdGiInvisible))
|
return false;
|
|
if (m_components & kEdgeSetMask)
|
{
|
bool bModified = GETBIT(m_components, kEdgeSelMarkOnModify);
|
if (GETBIT(m_components, kEdgeColors))
|
bModified |= setColor(m_pEdgeData->colors(), edgeIndex);
|
if (GETBIT(m_components, kEdgeTrueColors))
|
bModified |= setTrueColor(m_pEdgeData->trueColors(), edgeIndex);
|
if (GETBIT(m_components, kEdgeLayers))
|
bModified |= setLayer(m_pEdgeData->layerIds(), edgeIndex);
|
if (GETBIT(m_components, kEdgeLinetypes))
|
{
|
OdDbStub **pLinetypes = m_pEdgeData->linetypeIds();
|
if (m_curLinetypeId != pLinetypes[edgeIndex])
|
{
|
m_pTraits->setLineType(m_curLinetypeId = pLinetypes[edgeIndex]);
|
bModified = true;
|
}
|
}
|
if (m_pDrawCtx->effectivelyVisible())
|
{
|
if (bModified)
|
m_pDrawCtx->onTraitsModified();
|
return true;
|
}
|
else
|
return false;
|
}
|
|
return m_pDrawCtx->effectivelyVisible();
|
}
|
|
bool hasData() const { return (m_components & kEdgeMask) != 0; }
|
};
|
|
class OdGiFaceEdgeDataTraitsSaver : public OdGiFaceDataTraitsSaver, public OdGiEdgeDataTraitsSaver
|
{
|
public:
|
OdGiFaceEdgeDataTraitsSaver(const OdGiFaceData *pFaceData, const OdGiEdgeData *pEdgeData,
|
OdGiSubEntityTraits *pTraits, OdGiConveyorContext *pDrawCtx,
|
OdGsView::RenderMode renderMode)
|
: OdGiFaceEdgeDataTraitsSaverBase(pTraits, pDrawCtx, renderMode)
|
, OdGiFaceDataTraitsSaver(pFaceData, pTraits, pDrawCtx, renderMode, true)
|
, OdGiEdgeDataTraitsSaver(pEdgeData, pTraits, pDrawCtx, renderMode, true)
|
{
|
}
|
#ifdef EX_TRAITS_RESTORE_ONEXIT
|
~OdGiFaceEdgeDataTraitsSaver()
|
{
|
if (OdGiFaceDataTraitsSaver::needExit())
|
{
|
bool bModified = OdGiFaceDataTraitsSaver::onExit();
|
bModified |= OdGiEdgeDataTraitsSaver::onExit(true);
|
if (bModified)
|
m_pDrawCtx->onTraitsModified();
|
}
|
m_components = 0; // Avoid redundant operations in base class destructors
|
}
|
#endif
|
|
bool hasData() const { return m_components != 0; }
|
};
|
|
#endif // __ODGIFACEEDGEDATATRAITSSAVER_H__
|