union of OCCT approach for NO hatching and the new implemented case for hatching used on a presentation.
namespace
{
static volatile Standard_Integer THE_CLIP_PLANE_COUNTER = 0;
+
+ static Handle(Graphic3d_AspectFillArea3d) defaultAspect()
+ {
+ const Graphic3d_MaterialAspect aMaterial (Graphic3d_NOM_DEFAULT);
+ Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
+ anAspect->SetDistinguishOff();
+ anAspect->SetFrontMaterial (aMaterial);
+ anAspect->SetHatchStyle (Aspect_HS_HORIZONTAL);
+ anAspect->SetInteriorStyle (Aspect_IS_SOLID);
+ anAspect->SetInteriorColor (aMaterial.Color());
+ anAspect->SetSuppressBackFaces (false);
+ return anAspect;
+ }
}
// =======================================================================
// purpose :
// =======================================================================
Graphic3d_ClipPlane::Graphic3d_ClipPlane()
+: myAspect (defaultAspect()),
+ myPrevInChain(NULL),
+ myPlane (0.0, 0.0, 1.0, 0.0),
+ myEquation (0.0, 0.0, 1.0, 0.0),
+ myEquationRev(0.0, 0.0,-1.0, 0.0),
+ myChainLenFwd(1),
+ myFlags (Graphic3d_CappingFlags_None),
+ myEquationMod(0),
+ myAspectMod (0),
+ myIsOn (Standard_True),
+ myIsCapping (Standard_False)
{
+ makeId();
init();
}
// purpose :
// =======================================================================
Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Graphic3d_Vec4d& theEquation)
+: myAspect (defaultAspect()),
+ myPrevInChain(NULL),
+ myPlane (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.w()),
+ myEquation (theEquation),
+ myEquationRev(0.0, 0.0,-1.0, 0.0),
+ myChainLenFwd(1),
+ myFlags (Graphic3d_CappingFlags_None),
+ myEquationMod(0),
+ myAspectMod (0),
+ myIsOn (Standard_True),
+ myIsCapping (Standard_False)
{
+ makeId();
init (gp_Pln (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.a()));
updateInversedPlane();
}
-
+
// =======================================================================
// function : Graphic3d_ClipPlane
// purpose :
// =======================================================================
-Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Graphic3d_ClipPlane& theOther)
-: Standard_Transient (theOther)
+Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther)
+: Standard_Transient(theOther),
+ myAspect (defaultAspect()),
+ myPrevInChain(NULL),
+ myPlane (theOther.myPlane),
+ myEquation (theOther.myEquation),
+ myEquationRev(theOther.myEquationRev),
+ myChainLenFwd(1),
+ myFlags (theOther.myFlags),
+ myEquationMod(0),
+ myAspectMod (0),
+ myIsOn (theOther.myIsOn),
+ myIsCapping (theOther.myIsCapping)
{
+ *myAspect = *theOther.CappingAspect();
*mySectionStyle = *theOther.CappingSectionStyle();
+
+ makeId();
init (theOther.myPlane,
theOther.myEquationRev,
theOther.myIsOn,
// function : Graphic3d_ClipPlane
// purpose :
// =======================================================================
-Graphic3d_ClipPlane::Graphic3d_ClipPlane (const gp_Pln& thePlane)
+Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
+: myAspect (defaultAspect()),
+ myPrevInChain(NULL),
+ myPlane (thePlane),
+ myChainLenFwd(1),
+ myFlags (Graphic3d_CappingFlags_None),
+ myEquationMod(0),
+ myAspectMod (0),
+ myIsOn (Standard_True),
+ myIsCapping (Standard_False)
{
+ thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
+ makeId();
init (thePlane);
updateInversedPlane();
}
myEquation = theEquation;
updateInversedPlane();
myOrientationDirty = Standard_True;
+ myEquationMod++;
}
// =======================================================================
thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
updateInversedPlane();
myOrientationDirty = Standard_True;
+ myEquationMod++;
}
// =======================================================================
return new Graphic3d_ClipPlane(*this);
}
+// =======================================================================
+// function : SetCappingMaterial
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingMaterial (const Graphic3d_MaterialAspect& theMat)
+{
+ myAspect->SetFrontMaterial (theMat);
+ myAspect->SetInteriorColor (theMat.Color());
+ ++myAspectMod;
+}
+
+// =======================================================================
+// function : SetCappingTexture
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture)
+{
+ if (!theTexture.IsNull())
+ {
+ myAspect->SetTextureMapOn();
+ Handle(Graphic3d_TextureSet) aTextureSet = myAspect->TextureSet();
+ if (aTextureSet.IsNull() || aTextureSet->Size() != 1)
+ {
+ aTextureSet = new Graphic3d_TextureSet (theTexture);
+ }
+ else
+ {
+ aTextureSet->SetFirst (theTexture);
+ }
+ myAspect->SetTextureSet (aTextureSet);
+ }
+ else
+ {
+ myAspect->SetTextureMapOff();
+ myAspect->SetTextureSet (Handle(Graphic3d_TextureSet)());
+ }
+ ++myAspectMod;
+}
+
+// =======================================================================
+// function : SetCappingHatch
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingHatch (const Aspect_HatchStyle theStyle)
+{
+ myAspect->SetHatchStyle (theStyle);
+ ++myAspectMod;
+}
+
+// =======================================================================
+// function : SetCappingCustomHatch
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingCustomHatch (const Handle(Graphic3d_HatchStyle)& theStyle)
+{
+ myAspect->SetHatchStyle (theStyle);
+ ++myAspectMod;
+}
+
+// =======================================================================
+// function : SetCappingHatchOn
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingHatchOn()
+{
+ myAspect->SetInteriorStyle (Aspect_IS_HATCH);
+ ++myAspectMod;
+}
+
+// =======================================================================
+// function : SetCappingHatchOff
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingHatchOff()
+{
+ myAspect->SetInteriorStyle (Aspect_IS_SOLID);
+ ++myAspectMod;
+}
+
+// =======================================================================
+// function : SetCappingAspect
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
+{
+ myAspect = theAspect;
+ ++myAspectMod;
+}
+
+// =======================================================================
+// function : setCappingFlag
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::setCappingFlag (bool theToUse, int theFlag)
+{
+ if (theToUse)
+ {
+ myFlags |= theFlag;
+ }
+ else
+ {
+ myFlags &= ~(theFlag);
+ }
+ ++myAspectMod;
+}
+
+// =======================================================================
+// function : makeId
+// purpose :
+// =======================================================================
+void Graphic3d_ClipPlane::makeId()
+{
+ myId = TCollection_AsciiString ("Graphic3d_ClipPlane_") //DynamicType()->Name()
+ + TCollection_AsciiString (Standard_Atomic_Increment (&THE_CLIP_PLANE_COUNTER));
+}
+
// =======================================================================
// function : SetCappingSectionStyle
// purpose :
// function : init
// purpose :
// =======================================================================
-void Graphic3d_ClipPlane::init (const gp_Pln& thePlane,
- const Graphic3d_Vec4d& theEquationRev,
- const Standard_Boolean theIsOn,
- const Standard_Boolean theIsCapping,
+void Graphic3d_ClipPlane::init (const gp_Pln& /*thePlane*/,
+ const Graphic3d_Vec4d& /*theEquationRev*/,
+ const Standard_Boolean /*theIsOn*/,
+ const Standard_Boolean /*theIsCapping*/,
const Standard_Boolean theOverrideStyle,
const Handle(Graphic3d_AspectFillCapping)& theStyle)
{
- if (myEntityUID.IsEmpty())
- {
- myEntityUID = TCollection_AsciiString ("Graphic3d_ClipPlane_") //DynamicType()->Name()
- + TCollection_AsciiString (Standard_Atomic_Increment (&THE_CLIP_PLANE_COUNTER));
- }
-
- myPrevInChain = NULL;
- myEquationRev = theEquationRev;
- myChainLenFwd = 1;
- myPlane = thePlane;
- myPlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
- myIsOn = theIsOn;
- myIsCapping = theIsCapping;
myOverrideObjectStyle = theOverrideStyle;
mySectionStyle = theStyle.IsNull() ? new Graphic3d_AspectFillCapping() : theStyle;
myOrientationDirty = Standard_True;
void Graphic3d_ClipPlane::SetChainNextPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
{
myOrientationDirty = Standard_True;
+ ++myEquationMod;
if (!myNextInChain.IsNull())
{
myNextInChain->myPrevInChain = NULL;
OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, mySectionStyle.get());
- OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myEntityUID);
+ OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myId);
OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myPlane);
public: // @name user-defined graphical attributes
+ //! Set material for rendering capping surface.
+ //! @param theMat [in] the material.
+ Standard_EXPORT void SetCappingMaterial (const Graphic3d_MaterialAspect& theMat);
+
+ //! @return capping material.
+ const Graphic3d_MaterialAspect& CappingMaterial() const { return myAspect->FrontMaterial(); }
+
+ //! Set texture to be applied on capping surface.
+ //! @param theTexture [in] the texture.
+ Standard_EXPORT void SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture);
+
+ //! @return capping texture map.
+ Handle(Graphic3d_TextureMap) CappingTexture() const { return !myAspect->TextureSet().IsNull() && !myAspect->TextureSet()->IsEmpty()
+ ? myAspect->TextureSet()->First()
+ : Handle(Graphic3d_TextureMap)(); }
+
+ //! Set hatch style (stipple) and turn hatching on.
+ //! @param theStyle [in] the hatch style.
+ Standard_EXPORT void SetCappingHatch (const Aspect_HatchStyle theStyle);
+
+ //! @return hatching style.
+ Aspect_HatchStyle CappingHatch() const { return (Aspect_HatchStyle)myAspect->HatchStyle()->HatchType(); }
+
+ //! Set custom hatch style (stipple) and turn hatching on.
+ //! @param theStyle [in] the hatch pattern.
+ Standard_EXPORT void SetCappingCustomHatch (const Handle(Graphic3d_HatchStyle)& theStyle);
+
+ //! @return hatching style.
+ const Handle(Graphic3d_HatchStyle)& CappingCustomHatch() const { return myAspect->HatchStyle(); }
+
+ //! Turn on hatching.
+ Standard_EXPORT void SetCappingHatchOn();
+
+ //! Turn off hatching.
+ Standard_EXPORT void SetCappingHatchOff();
+
+ //! @return True if hatching mask is turned on.
+ Standard_Boolean IsHatchOn() const { return myAspect->InteriorStyle() == Aspect_IS_HATCH; }
//! This ID is used for managing associated resources in graphical driver.
//! The clip plane can be assigned within a range of IO which can be
//! @return clip plane resource identifier string.
const TCollection_AsciiString& GetId() const
{
- return myEntityUID;
+ return myId;
}
+public:
+
+ //! Return capping aspect.
+ //! @return capping surface rendering aspect.
+ const Handle(Graphic3d_AspectFillArea3d)& CappingAspect() const { return myAspect; }
+
+ //! Assign capping aspect.
+ Standard_EXPORT void SetCappingAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect);
+
+ //! Flag indicating whether material for capping plane should be taken from object.
+ //! Default value: FALSE (use dedicated capping plane material).
+ bool ToUseObjectMaterial() const { return (myFlags & Graphic3d_CappingFlags_ObjectMaterial) != 0; }
+
+ //! Set flag for controlling the source of capping plane material.
+ void SetUseObjectMaterial (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectMaterial); }
+
+ //! Flag indicating whether texture for capping plane should be taken from object.
+ //! Default value: FALSE.
+ bool ToUseObjectTexture() const { return (myFlags & Graphic3d_CappingFlags_ObjectTexture) != 0; }
+
+ //! Set flag for controlling the source of capping plane texture.
+ void SetUseObjectTexture (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectTexture); }
+
+ //! Flag indicating whether shader program for capping plane should be taken from object.
+ //! Default value: FALSE.
+ bool ToUseObjectShader() const { return (myFlags & Graphic3d_CappingFlags_ObjectShader) != 0; }
+
+ //! Set flag for controlling the source of capping plane shader program.
+ void SetUseObjectShader(bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectShader); }
+
+ //! Return true if some fill area aspect properties should be taken from object.
+ bool ToUseObjectProperties() const { return myFlags != Graphic3d_CappingFlags_None; }
+
public:
//! Returns style used for drawing capping section.
{
return myAspectMod;
}
+
+private:
+
+ //! Generate unique object id for OpenGL graphic resource manager.
+ void makeId();
+
+ //! Set capping flag.
+ Standard_EXPORT void setCappingFlag (bool theToUse, int theFlag);
+
+public:
+
//! Flag indicating whether section style of the plane should overrides similar property of object presentation.
//! Default value: FALSE (use dedicated presentation aspect style).
bool ToOverrideCappingAspect() const { return myOverrideObjectStyle; }
private:
+ Handle(Graphic3d_AspectFillArea3d) myAspect; //!< fill area aspect
Handle(Graphic3d_AspectFillCapping) mySectionStyle; //!< Style set for drawing capped solid section.
Handle(Graphic3d_ClipPlane) myNextInChain; //!< next plane in a chain of planes defining logical AND operation
Graphic3d_ClipPlane* myPrevInChain; //!< previous plane in a chain of planes defining logical AND operation
- TCollection_AsciiString myEntityUID; //!< Unique identifier for the plane
+ TCollection_AsciiString myId; //!< resource id
gp_Pln myPlane; //!< plane definition
Graphic3d_Vec4d myEquation; //!< plane equation vector
Graphic3d_Vec4d myEquationRev; //!< reversed plane equation
namespace
{
- static const OpenGl_CappingPlaneResource* THE_DEFAULT_ASPECT = new OpenGl_CappingPlaneResource (new Graphic3d_AspectFillCapping);
+ static const OpenGl_CappingPlaneResource* THE_DEFAULT_ASPECT = new OpenGl_CappingPlaneResource (NULL, new Graphic3d_AspectFillCapping);
static const TCollection_AsciiString THE_QUAD_PARRAY = "OpenGl_CappingAlgo_Quad";
static const TCollection_AsciiString THE_PLANE_STYLE = "OpenGl_CappingAlgo_CappingStyle_";
theWorkspace->SetAllowFaceCulling (wasCullAllowed);
}
+ //! Render infinite capping plane.
+ //! @param theWorkspace [in] the GL workspace, context state.
+ //! @param thePlane [in] the graphical plane, for which the capping surface is rendered.
+ static void renderPlane (const Handle(OpenGl_Workspace)& theWorkspace,
+ const Handle(OpenGl_CappingPlaneResource)& thePlane)
+ {
+ const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+ const bool wasCullAllowed = theWorkspace->SetAllowFaceCulling (true);
+
+ // set identity model matrix
+ aContext->ModelWorldState.Push();
+ aContext->ModelWorldState.SetCurrent (OpenGl_Mat4::Map (*thePlane->Orientation()->mat));
+ aContext->ApplyModelViewMatrix();
+
+ thePlane->Primitives().Render (theWorkspace);
+
+ aContext->ModelWorldState.Pop();
+ aContext->ApplyModelViewMatrix();
+
+ theWorkspace->SetAllowFaceCulling (wasCullAllowed);
+ }
+
//! Render capping for specific structure.
static void renderCappingForStructure (StencilTestSentry& theStencilSentry,
const Handle(OpenGl_Workspace)& theWorkspace,
const Handle(Graphic3d_ClipPlane)& aPlane = theClipChain;
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+ const Handle(Graphic3d_ClipPlane)& aRenderPlane = thePlane->Plane();
const Handle(Graphic3d_Camera) aCamera = theWorkspace->View() != NULL
? theWorkspace->View()->Camera()
: Handle(Graphic3d_Camera)();
// clear stencil only if something has been actually drawn
theStencilSentry.Init();
+ const OpenGl_Aspects* aGroupAspectFace = aGroupIter.Value()->GlAspects();
+ const OpenGl_CappingPlaneResource* aGroupAspectCapping = aGroupIter.Value()->AspectFillCapping();
+ const OpenGl_CappingPlaneResource* anAspectCapping =
+ thePlane && (!aGroupAspectCapping || aGroupAspectCapping->Aspect().IsNull() || aPlane->ToOverrideCappingAspect())
+ ? thePlane.get()
+ : aGroupAspectCapping;
+
+ if (anAspectCapping == NULL)
+ {
+ anAspectCapping = THE_DEFAULT_ASPECT;
+ }
+
+ const OpenGl_Aspects* anAspectFace = anAspectCapping->CappingFaceAspect (aGroupAspectFace);
+ const Standard_Boolean hasHatch = anAspectCapping->Aspect()->ToDrawHatch();
+
+ if (!hasHatch)
+ {
+ // check if capping plane should be rendered within current pass (only opaque / only transparent)
+ const OpenGl_Aspects* anObjAspectFace = aRenderPlane->ToUseObjectProperties() ? aGroupIter.Value()->GlAspects() : NULL;
+ //const OpenGl_Aspects* anObjAspectFace = aRenderPlane->CappingSectionStyle()->ToUseObjectProperties() ? aGroupIter.Value()->GlAspects() : NULL;
+ thePlane->Update (aContext, anObjAspectFace != NULL ? anObjAspectFace->Aspect() : Handle(Graphic3d_Aspects)());
+ theWorkspace->SetAspects (thePlane->AspectFace());
+ theWorkspace->SetRenderFilter (aPrevFilter);
+ if (!theWorkspace->ShouldRender (&thePlane->Primitives()))
+ {
+ continue;
+ }
+ }
+
// suppress only opaque/transparent filter since for filling stencil the whole geometry should be drawn
theWorkspace->SetRenderFilter (anAnyFilter);
aContext->ShaderManager()->UpdateClippingState();
glClear (GL_STENCIL_BUFFER_BIT);
- glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ const bool aColorMaskBack = aContext->SetColorMask (false);
// override aspects, disable culling
theWorkspace->SetAspects (&theWorkspace->NoneCulling());
glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT);
// render closed primitives
- aGroupIter.Value()->Render (theWorkspace);
+ if (hasHatch)
+ {
+ aGroupIter.Value()->Render (theWorkspace);
+ }
+ else
+ {
+ // render closed primitives
+ if (aRenderPlane->ToUseObjectProperties())
+ {
+ aGroupIter.Value()->Render (theWorkspace);
+ }
+ else
+ {
+ for (; aGroupIter.More(); aGroupIter.Next())
+ {
+ if (aGroupIter.Value()->IsClosed())
+ {
+ aGroupIter.Value()->Render (theWorkspace);
+ }
+ }
+ }
+ }
// override material, cull back faces
theWorkspace->SetAspects (&theWorkspace->FrontCulling());
aContext->ShaderManager()->UpdateClippingState();
// render capping plane using the generated stencil mask
- glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ aContext->SetColorMask (aColorMaskBack);
if (theWorkspace->UseDepthWrite())
{
glDepthMask (GL_TRUE);
glEnable (GL_DEPTH_TEST);
}
- const OpenGl_Aspects* aGroupAspectFace = aGroupIter.Value()->GlAspects();
- const OpenGl_CappingPlaneResource* aGroupAspectCapping = aGroupIter.Value()->AspectFillCapping();
- const OpenGl_CappingPlaneResource* anAspectCapping =
- thePlane && (!aGroupAspectCapping || aGroupAspectCapping->Aspect().IsNull() || aPlane->ToOverrideCappingAspect())
- ? thePlane.get()
- : aGroupAspectCapping;
-
- if (anAspectCapping == NULL)
+ if (!hasHatch)
{
- anAspectCapping = THE_DEFAULT_ASPECT;
+ theWorkspace->SetAspects (thePlane->AspectFace());
+ renderPlane (theWorkspace, thePlane);
}
-
- const OpenGl_Aspects* anAspectFace = anAspectCapping->CappingFaceAspect (aGroupAspectFace);
- const Standard_Boolean hasHatch = anAspectCapping->Aspect()->ToDrawHatch();
- const OpenGl_Aspects* anAspectHatching = hasHatch ? anAspectCapping->HatchingFaceAspect() : NULL;
- const Standard_Boolean hasTextureHatch = hasHatch && !anAspectCapping->Aspect()->TextureHatch().IsNull();
- const Standard_Boolean isRotatePers = hasTextureHatch && !aCamera.IsNull() && anAspectCapping->Aspect()->IsHatchRotationPersistent();
- const Standard_Boolean isZoomPers = hasTextureHatch && !aCamera.IsNull() && anAspectCapping->Aspect()->IsHatchZoomPersistent();
-
- Standard_ShortReal aHatchScale = 1.0;
- Standard_ShortReal aHatchAngle = 0.0;
-
- if (isRotatePers || isZoomPers)
+ else
{
+ const OpenGl_Aspects* anAspectHatching = hasHatch ? anAspectCapping->HatchingFaceAspect() : NULL;
+ const Standard_Boolean hasTextureHatch = hasHatch && !anAspectCapping->Aspect()->TextureHatch().IsNull();
+ const Standard_Boolean isRotatePers = hasTextureHatch && !aCamera.IsNull() && anAspectCapping->Aspect()->IsHatchRotationPersistent();
+ const Standard_Boolean isZoomPers = hasTextureHatch && !aCamera.IsNull() && anAspectCapping->Aspect()->IsHatchZoomPersistent();
+
+ Standard_ShortReal aHatchScale = 1.0;
+ Standard_ShortReal aHatchAngle = 0.0;
- if (isRotatePers)
+ if (isRotatePers || isZoomPers)
{
- if (aRotateAngle == 0.0)
+
+ if (isRotatePers)
{
- const gp_Dir aPlaneSide (aPlaneMat.GetValue (0, 0), aPlaneMat.GetValue (1, 0), aPlaneMat.GetValue (2, 0));
- const gp_Dir aPlaneUp (aPlaneMat.GetValue (0, 2), aPlaneMat.GetValue (1, 2), aPlaneMat.GetValue (2, 2));
- const gp_Dir& aCameraUp = aCamera->Up();
- const gp_Vec aCameraPln = aPlaneSide.Dot (aCameraUp) * aPlaneSide + aPlaneUp.Dot (aCameraUp) * aPlaneUp;
- if (aCameraPln.Magnitude() > Precision::Confusion())
+ if (aRotateAngle == 0.0)
{
- const gp_Dir& aCameraDir = aCamera->Direction();
- aRotateAngle = static_cast<Standard_ShortReal> (aCameraPln.AngleWithRef (aPlaneUp, aCameraDir) / M_PI * 180.0);
+ const gp_Dir aPlaneSide (aPlaneMat.GetValue (0, 0), aPlaneMat.GetValue (1, 0), aPlaneMat.GetValue (2, 0));
+ const gp_Dir aPlaneUp (aPlaneMat.GetValue (0, 2), aPlaneMat.GetValue (1, 2), aPlaneMat.GetValue (2, 2));
+ const gp_Dir& aCameraUp = aCamera->Up();
+ const gp_Vec aCameraPln = aPlaneSide.Dot (aCameraUp) * aPlaneSide + aPlaneUp.Dot (aCameraUp) * aPlaneUp;
+ if (aCameraPln.Magnitude() > Precision::Confusion())
+ {
+ const gp_Dir& aCameraDir = aCamera->Direction();
+ aRotateAngle = static_cast<Standard_ShortReal> (aCameraPln.AngleWithRef (aPlaneUp, aCameraDir) / M_PI * 180.0);
+ }
}
- }
- aHatchAngle = aRotateAngle;
- }
+ aHatchAngle = aRotateAngle;
+ }
- if (isZoomPers)
- {
- if (aViewScale == ShortRealLast())
+ if (isZoomPers)
{
- const Standard_Real aFocus = aCamera->IsOrthographic()
- ? aCamera->Distance()
- : (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
- ? Standard_Real(aCamera->ZFocus() * aCamera->Distance())
- : Standard_Real(aCamera->ZFocus()));
-
- const gp_XYZ aViewDim = aCamera->ViewDimensions (aFocus);
- aViewScale = static_cast<Standard_ShortReal> (aViewDim.Y() / aContext->Viewport()[3]);
- }
+ if (aViewScale == ShortRealLast())
+ {
+ const Standard_Real aFocus = aCamera->IsOrthographic()
+ ? aCamera->Distance()
+ : (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
+ ? Standard_Real(aCamera->ZFocus() * aCamera->Distance())
+ : Standard_Real(aCamera->ZFocus()));
+
+ const gp_XYZ aViewDim = aCamera->ViewDimensions (aFocus);
+ aViewScale = static_cast<Standard_ShortReal> (aViewDim.Y() / aContext->Viewport()[3]);
+ }
- if (!anAspectHatching->TextureSet(aContext)->IsEmpty())
- aHatchScale = 1.0f / (aViewScale * anAspectHatching->TextureSet(aContext)->First()->SizeY());
+ if (!anAspectHatching->TextureSet(aContext)->IsEmpty())
+ aHatchScale = 1.0f / (aViewScale * anAspectHatching->TextureSet(aContext)->First()->SizeY());
+ }
}
- }
- renderSection (theWorkspace, theQuad, anAspectFace, hasHatch ? anAspectCapping->HatchingFaceAspect() : NULL, aPlaneMat, aHatchScale, aHatchAngle);
+ renderSection (theWorkspace, theQuad, anAspectFace, hasHatch ? anAspectCapping->HatchingFaceAspect() : NULL, aPlaneMat, aHatchScale, aHatchAngle);
+ }
// turn on the current plane to restore initial state
aContext->ChangeClipping().ResetCappingFilter();
// function : RenderCapping
// purpose :
// =======================================================================
-#include <Message_Alerts.hxx>
-#include <Message_PerfMeter.hxx>
void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace,
const OpenGl_Structure& theStructure)
{
- Message_PerfMeter aPerfMeter;
- MESSAGE_INFO ("RenderCapping", "", &aPerfMeter, NULL);
-
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
if (!aContext->Clipping().IsCappingOn())
{
continue;
}
- Standard_SStream aStream;
- aClipChain->DumpJson (aStream);
- MESSAGE_INFO_STREAM(aStream, "ClipChain", "", &aPerfMeter, NULL);
-
Standard_Integer aSubPlaneIndex = 1;
for (const Graphic3d_ClipPlane* aSubPlaneIter = aClipChain.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get(), ++aSubPlaneIndex)
{
if (!aContext->GetResource (aResId, aPlaneRes))
{
// share and register for release once the resource is no longer used
- aPlaneRes = new OpenGl_CappingPlaneResource (aSubPlaneIter->CappingSectionStyle());
+ aPlaneRes = new OpenGl_CappingPlaneResource (aSubPlaneIter, aSubPlaneIter->CappingSectionStyle());
aContext->ShareResource (aResId, aPlaneRes);
}
// function : OpenGl_CappingPlaneResource
// purpose :
// =======================================================================
-OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_AspectFillCapping)& theAspect)
-: myCappingAspect(),//defaultMaterial()),
+OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane,
+ const Handle(Graphic3d_AspectFillCapping)& theAspect)
+: myPrimitives (NULL),
+ myPrimitivesUsed (Standard_False),
+ myOrientation (OpenGl_IdentityMatrix),
+ myAspect (NULL),
+ myPlaneRoot (thePlane),
+ myEquationMod ((unsigned int )-1),
+ myAspectMod ((unsigned int )-1),
+ myCappingAspect(),//defaultMaterial()),
myHatchingAspect(),//defaultMaterial()),
myHatchingState (0)
{
+ if (theAspect.IsNull() || !theAspect->ToDrawHatch())
+ {
+ // Fill primitive array
+ Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
+ Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (anAlloc);
+ Graphic3d_Attribute anAttribInfo[] =
+ {
+ { Graphic3d_TOA_POS, Graphic3d_TOD_VEC4 },
+ { Graphic3d_TOA_NORM, Graphic3d_TOD_VEC4 },
+ { Graphic3d_TOA_UV, Graphic3d_TOD_VEC4 }
+ };
+ if (anAttribs->Init (12, anAttribInfo, 3))
+ {
+ memcpy (anAttribs->ChangeData(), THE_CAPPING_PLN_VERTS, sizeof(THE_CAPPING_PLN_VERTS));
+ myPrimitives.InitBuffers (NULL, Graphic3d_TOPA_TRIANGLES, NULL, anAttribs, NULL);
+ myPrimitivesUsed = Standard_True;
+ }
+ }
+
myCappingAspect.SetAspect (defaultMaterial());
myHatchingAspect.SetAspect (defaultMaterial());
// =======================================================================
OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
{
+ if (myPrimitivesUsed)
+ {
+ Release (NULL);
+ }
}
// =======================================================================
// =======================================================================
void OpenGl_CappingPlaneResource::SetAspect (const Handle(Graphic3d_AspectFillCapping)& theAspect)
{
- myAspect = theAspect;
+ myGraphicAspect = theAspect;
if (theAspect.IsNull())
{
return;
}
+ if (!theAspect->ToDrawHatch())
+ return;
+
if (!theAspect->ToUseObjectMaterial()
|| !theAspect->ToUseObjectTexture()
|| !theAspect->ToUseObjectShader())
}
}
+// =======================================================================
+// function : Update
+// purpose :
+// =======================================================================
+void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theCtx,
+ const Handle(Graphic3d_Aspects)& theObjAspect)
+{
+ if (!myPrimitivesUsed)
+ return;
+
+ updateTransform (theCtx);
+ updateAspect (theObjAspect);
+}
+
// =======================================================================
// function : Release
// purpose :
// =======================================================================
void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext)
{
+ if (myPrimitivesUsed)
+ {
+ OpenGl_Element::Destroy (theContext, myAspect);
+ myPrimitives.Release (theContext);
+ myEquationMod = (unsigned int )-1;
+ myAspectMod = (unsigned int )-1;
+ }
myCappingAspect .Release (theContext);
myHatchingAspect.Release (theContext);
}
// =======================================================================
const OpenGl_Aspects* OpenGl_CappingPlaneResource::CappingFaceAspect (const OpenGl_Aspects* theObjectAspect) const
{
- if (myAspect.IsNull())
+ if (myGraphicAspect.IsNull())
{
return NULL;
}
Handle(Graphic3d_Aspects) aFillAspect = myCappingAspect.Aspect();
- if (myAspect->ToUseObjectMaterial() && theObjectAspect != NULL)
+ if (myGraphicAspect->ToUseObjectMaterial() && theObjectAspect != NULL)
{
// only front material currently supported by capping rendering
aFillAspect->SetFrontMaterial (theObjectAspect->Aspect()->FrontMaterial());
}
else
{
- aFillAspect->SetFrontMaterial (myAspect->Material());
- aFillAspect->SetInteriorColor (myAspect->Material().Color());
+ aFillAspect->SetFrontMaterial (myGraphicAspect->Material());
+ aFillAspect->SetInteriorColor (myGraphicAspect->Material().Color());
}
- if (myAspect->ToUseObjectTexture() && theObjectAspect != NULL)
+ if (myGraphicAspect->ToUseObjectTexture() && theObjectAspect != NULL)
{
if (theObjectAspect->Aspect()->ToMapTexture())
{
}
else
{
- aFillAspect->SetTextureMap (myAspect->Texture());
- if (!myAspect->Texture().IsNull())
+ aFillAspect->SetTextureMap (myGraphicAspect->Texture());
+ if (!myGraphicAspect->Texture().IsNull())
{
aFillAspect->SetTextureMapOn();
}
}
}
- if (myAspect->ToUseObjectShader() && theObjectAspect != NULL)
+ if (myGraphicAspect->ToUseObjectShader() && theObjectAspect != NULL)
{
aFillAspect->SetShaderProgram (theObjectAspect->Aspect()->ShaderProgram());
}
else
{
- aFillAspect->SetShaderProgram (myAspect->Shader());
+ aFillAspect->SetShaderProgram (myGraphicAspect->Shader());
}
myCappingAspect.SetAspect (aFillAspect);
// =======================================================================
const OpenGl_Aspects* OpenGl_CappingPlaneResource::HatchingFaceAspect() const
{
- if (myAspect.IsNull())
+ if (myGraphicAspect.IsNull())
{
return NULL;
}
- const Standard_Size aHatchingState = myAspect->HatchingState();
+ const Standard_Size aHatchingState = myGraphicAspect->HatchingState();
if (myHatchingState != aHatchingState)
{
- if (myAspect->ToDrawHatch())
+ if (myGraphicAspect->ToDrawHatch())
{
Handle(Graphic3d_Aspects) aFillAspect = myHatchingAspect.Aspect();
- aFillAspect->SetInteriorStyle (myAspect->IsStippleHatch() ? Aspect_IS_HATCH : Aspect_IS_SOLID);
- aFillAspect->SetHatchStyle (myAspect->IsStippleHatch() ? myAspect->StippleHatch() : Handle(Graphic3d_HatchStyle)());
- aFillAspect->SetTextureMap (myAspect->IsTextureHatch() ? myAspect->TextureHatch() : Handle(Graphic3d_TextureMap)());
- aFillAspect->SetFrontMaterial (myAspect->HatchMaterial());
- aFillAspect->SetInteriorColor (myAspect->HatchMaterial().Color());
- if (myAspect->IsTextureHatch())
+ aFillAspect->SetInteriorStyle (myGraphicAspect->IsStippleHatch() ? Aspect_IS_HATCH : Aspect_IS_SOLID);
+ aFillAspect->SetHatchStyle (myGraphicAspect->IsStippleHatch() ? myGraphicAspect->StippleHatch() : Handle(Graphic3d_HatchStyle)());
+ aFillAspect->SetTextureMap (myGraphicAspect->IsTextureHatch() ? myGraphicAspect->TextureHatch() : Handle(Graphic3d_TextureMap)());
+ aFillAspect->SetFrontMaterial (myGraphicAspect->HatchMaterial());
+ aFillAspect->SetInteriorColor (myGraphicAspect->HatchMaterial().Color());
+ if (myGraphicAspect->IsTextureHatch())
{
aFillAspect->SetTextureMapOn();
}
return &myHatchingAspect;
}
+
+// =======================================================================
+// function : updateAspect
+// purpose :
+// =======================================================================
+void OpenGl_CappingPlaneResource::updateAspect (const Handle(Graphic3d_Aspects)& theObjAspect)
+{
+ if (myPlaneRoot.IsNull())
+ return;
+
+ if (myAspect == NULL)
+ {
+ myAspect = new OpenGl_Aspects();
+ myAspectMod = myPlaneRoot->MCountAspect() - 1; // mark out of sync
+ }
+
+ if (theObjAspect.IsNull())
+ {
+ if (myAspectMod != myPlaneRoot->MCountAspect())
+ {
+ myAspect->SetAspect (myPlaneRoot->CappingAspect());
+ myAspectMod = myPlaneRoot->MCountAspect();
+ }
+ return;
+ }
+
+ if (myFillAreaAspect.IsNull())
+ {
+ myFillAreaAspect = new Graphic3d_AspectFillArea3d();
+ }
+ if (myAspectMod != myPlaneRoot->MCountAspect())
+ {
+ *myFillAreaAspect = *myPlaneRoot->CappingAspect();
+ }
+
+ if (myPlaneRoot->ToUseObjectMaterial())
+ {
+ // only front material currently supported by capping rendering
+ myFillAreaAspect->SetFrontMaterial (theObjAspect->FrontMaterial());
+ myFillAreaAspect->SetInteriorColor (theObjAspect->InteriorColor());
+ }
+ if (myPlaneRoot->ToUseObjectTexture())
+ {
+ myFillAreaAspect->SetTextureSet (theObjAspect->TextureSet());
+ if (theObjAspect->ToMapTexture())
+ {
+ myFillAreaAspect->SetTextureMapOn();
+ }
+ else
+ {
+ myFillAreaAspect->SetTextureMapOff();
+ }
+ }
+ if (myPlaneRoot->ToUseObjectShader())
+ {
+ myFillAreaAspect->SetShaderProgram (theObjAspect->ShaderProgram());
+ }
+
+ myAspect->SetAspect (myFillAreaAspect);
+}
+
+// =======================================================================
+// function : updateTransform
+// purpose :
+// =======================================================================
+void OpenGl_CappingPlaneResource::updateTransform (const Handle(OpenGl_Context)& theCtx)
+{
+ if (myPlaneRoot.IsNull())
+ return;
+
+ if (myEquationMod == myPlaneRoot->MCountEquation()
+ && myLocalOrigin.IsEqual (theCtx->ShaderManager()->LocalOrigin(), gp::Resolution()))
+ {
+ return; // nothing to update
+ }
+
+ myEquationMod = myPlaneRoot->MCountEquation();
+ myLocalOrigin = theCtx->ShaderManager()->LocalOrigin();
+
+ const Graphic3d_ClipPlane::Equation& anEq = myPlaneRoot->GetEquation();
+ const Standard_Real anEqW = theCtx->ShaderManager()->LocalClippingPlaneW (*myPlaneRoot);
+
+ // re-evaluate infinite plane transformation matrix
+ const Graphic3d_Vec3 aNorm (anEq.xyz());
+ const Graphic3d_Vec3 T (anEq.xyz() * -anEqW);
+
+ // project plane normal onto OX to find left vector
+ const Standard_ShortReal aProjLen = sqrt ((Standard_ShortReal)anEq.xz().SquareModulus());
+ Graphic3d_Vec3 aLeft;
+ if (aProjLen < ShortRealSmall())
+ {
+ aLeft[0] = 1.0f;
+ }
+ else
+ {
+ aLeft[0] = aNorm[2] / aProjLen;
+ aLeft[2] = -aNorm[0] / aProjLen;
+ }
+
+ const Graphic3d_Vec3 F = Graphic3d_Vec3::Cross (-aLeft, aNorm);
+
+ myOrientation.mat[0][0] = aLeft[0];
+ myOrientation.mat[0][1] = aLeft[1];
+ myOrientation.mat[0][2] = aLeft[2];
+ myOrientation.mat[0][3] = 0.0f;
+
+ myOrientation.mat[1][0] = aNorm[0];
+ myOrientation.mat[1][1] = aNorm[1];
+ myOrientation.mat[1][2] = aNorm[2];
+ myOrientation.mat[1][3] = 0.0f;
+
+ myOrientation.mat[2][0] = F[0];
+ myOrientation.mat[2][1] = F[1];
+ myOrientation.mat[2][2] = F[2];
+ myOrientation.mat[2][3] = 0.0f;
+
+ myOrientation.mat[3][0] = T[0];
+ myOrientation.mat[3][1] = T[1];
+ myOrientation.mat[3][2] = T[2];
+ myOrientation.mat[3][3] = 1.0f;
+}
#include <OpenGl_Aspects.hxx>
#include <OpenGl_Matrix.hxx>
#include <Graphic3d_AspectFillCapping.hxx>
+#include <Graphic3d_ClipPlane.hxx>
class OpenGl_CappingPlaneResource;
DEFINE_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource)
public:
//! Create and assign style.
- Standard_EXPORT OpenGl_CappingPlaneResource (const Handle(Graphic3d_AspectFillCapping)& theAspect);
+ Standard_EXPORT OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane,
+ const Handle(Graphic3d_AspectFillCapping)& theAspect);
//! Destroy object.
Standard_EXPORT virtual ~OpenGl_CappingPlaneResource();
- //! Assign section style.
+ //! Update resource data in the passed context.
+ //! @param theContext [in] the context
+ //! @param theObjAspect [in] object aspect
+ Standard_EXPORT void Update (const Handle(OpenGl_Context)& theContext,
+ const Handle(Graphic3d_Aspects)& theObjAspect);
+
+//! Assign section style.
Standard_EXPORT void SetAspect (const Handle(Graphic3d_AspectFillCapping)& theAspect);
//! Returns section style parameters.
- const Handle(Graphic3d_AspectFillCapping)& Aspect() const { return myAspect; }
+ const Handle(Graphic3d_AspectFillCapping)& Aspect() const { return myGraphicAspect; }
//! Release associated OpenGl resources.
//! @param theContext [in] the resource context.
//! Returns estimated GPU memory usage - not implemented.
virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE { return 0; }
+ //! Return parent clipping plane structure.
+ const Handle(Graphic3d_ClipPlane)& Plane() const { return myPlaneRoot; }
+
//! @return primitive array of vertices to render infinite plane.
static OpenGl_PrimitiveArray* BuildInfinitPlaneVertices();
- //! Returns true if capping should draw hatch layer.
+ //! @return aspect face for rendering capping surface.
+ inline const OpenGl_Aspects* AspectFace() const { return myAspect; }
+
+//! Returns true if capping should draw hatch layer.
Standard_Boolean ToDrawHatch() const
{
- return myAspect->ToDrawHatch()
- && (myAspect->IsStippleHatch()
- || myAspect->IsTextureHatch());
+ return Aspect()->ToDrawHatch()
+ && (Aspect()->IsStippleHatch()
+ || Aspect()->IsTextureHatch());
}
+ //! @return evaluated orientation matrix to transform infinite plane.
+ inline const OpenGl_Matrix* Orientation() const { return &myOrientation; }
+
//! Returns the shading aspect for drawing face of a clipping section itself.
//! @param theObjectAspect [in] the aspect of an object if it requires combining.
Standard_EXPORT const OpenGl_Aspects* CappingFaceAspect (const OpenGl_Aspects* theObjectAspect) const;
+ //! @return primitive array of vertices to render infinite plane.
+ inline const OpenGl_PrimitiveArray& Primitives() const { return myPrimitives; }
+
//! Returns the shading aspect for drawing hatch layer of a section.
Standard_EXPORT const OpenGl_Aspects* HatchingFaceAspect() const;
private:
- Handle(Graphic3d_AspectFillCapping) myAspect; //!< Section style settings from application's level.
+ OpenGl_PrimitiveArray myPrimitives; //!< vertices and texture coordinates for rendering
+ Standard_Boolean myPrimitivesUsed; //!< boolean flag if primitives are used
+ OpenGl_Matrix myOrientation; //!< plane transformation matrix.
+ OpenGl_Aspects* myAspect; //!< capping face aspect.
+ Handle(Graphic3d_ClipPlane) myPlaneRoot; //!< parent clipping plane structure.
+ Handle(Graphic3d_Aspects) myFillAreaAspect;//!< own capping aspect
+ gp_XYZ myLocalOrigin; //!< layer origin
+ unsigned int myEquationMod; //!< modification counter for plane equation.
+ unsigned int myAspectMod; //!< modification counter for aspect.
+
+ Handle(Graphic3d_AspectFillCapping) myGraphicAspect; //!< Section style settings from application's level.
mutable OpenGl_Aspects myCappingAspect; //!< GL aspect for shading base layer of a capping section.
mutable OpenGl_Aspects myHatchingAspect; //!< GL aspect for shading hatching layer (additional to base) of a capping section.
mutable Standard_Size myHatchingState;
- gp_XYZ myLocalOrigin; //!< layer origin
public:
Handle(Graphic3d_AspectFillCapping) aFillCappingAspect = Handle(Graphic3d_AspectFillCapping)::DownCast (theAspect);
if (myAspectFillCapping == NULL)
{
- myAspectFillCapping = new OpenGl_CappingPlaneResource (aFillCappingAspect);
+ myAspectFillCapping = new OpenGl_CappingPlaneResource (NULL, aFillCappingAspect);
}
else
{