// =======================================================================
OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
: Graphic3d_CStructure (theManager),
- myHighlightColor (NULL),
myInstancedStructure (NULL),
myIsRaytracable (Standard_False),
myModificationState (0),
}
// =======================================================================
-// function : UpdateTransformation
+// function : SetTransformation
// purpose :
// =======================================================================
-void OpenGl_Structure::UpdateTransformation()
+void OpenGl_Structure::SetTransformation (const Handle(Geom_Transformation)& theTrsf)
{
- const OpenGl_Mat4& aMat = Graphic3d_CStructure::Transformation;
- Standard_ShortReal aDet =
- aMat.GetValue(0, 0) * (aMat.GetValue(1, 1) * aMat.GetValue(2, 2) - aMat.GetValue(2, 1) * aMat.GetValue(1, 2)) -
- aMat.GetValue(0, 1) * (aMat.GetValue(1, 0) * aMat.GetValue(2, 2) - aMat.GetValue(2, 0) * aMat.GetValue(1, 2)) +
- aMat.GetValue(0, 2) * (aMat.GetValue(1, 0) * aMat.GetValue(2, 1) - aMat.GetValue(2, 0) * aMat.GetValue(1, 1));
-
- // Determinant of transform matrix less then 0 means that mirror transform applied.
- myIsMirrored = aDet < 0.0f;
+ myTrsf = theTrsf;
+ myIsMirrored = Standard_False;
+ if (!myTrsf.IsNull())
+ {
+ // Determinant of transform matrix less then 0 means that mirror transform applied.
+ const Standard_Real aDet = myTrsf->Value(1, 1) * (myTrsf->Value (2, 2) * myTrsf->Value (3, 3) - myTrsf->Value (3, 2) * myTrsf->Value (2, 3))
+ - myTrsf->Value(1, 2) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 3) - myTrsf->Value (3, 1) * myTrsf->Value (2, 3))
+ + myTrsf->Value(1, 3) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 2) - myTrsf->Value (3, 1) * myTrsf->Value (2, 2));
+ myIsMirrored = aDet < 0.0;
+ }
if (IsRaytracable())
{
}
}
-// =======================================================================
-// function : HighlightWithColor
-// purpose :
-// =======================================================================
-void OpenGl_Structure::HighlightWithColor (const Graphic3d_Vec3& theColor,
- const Standard_Boolean theToCreate)
-{
- const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
- if (theToCreate)
- setHighlightColor (aContext, theColor);
- else
- clearHighlightColor (aContext);
-}
-
// =======================================================================
// function : HighlightWithBndBox
// purpose :
// =======================================================================
-void OpenGl_Structure::HighlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct,
- const Standard_Boolean theToCreate)
+void OpenGl_Structure::highlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct)
{
const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
- if (!theToCreate)
- {
- clearHighlightBox (aContext);
- return;
- }
if (!myHighlightBox.IsNull())
{
myHighlightBox = new OpenGl_Group (theStruct);
}
- myHighlightBox->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (HighlightColor, Aspect_TOL_SOLID, 1.0));
+ myHighlightBox->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (myHighlightStyle->Color(), Aspect_TOL_SOLID, 1.0));
OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox);
myHighlightBox->AddElement (aBndBoxPrs);
}
// =======================================================================
-// function : setHighlightColor
+// function : GraphicHighlight
// purpose :
// =======================================================================
-void OpenGl_Structure::setHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
- const Graphic3d_Vec3& theColor)
+void OpenGl_Structure::GraphicHighlight (const Handle(Graphic3d_HighlightStyle)& theStyle,
+ const Handle(Graphic3d_Structure)& theStruct)
{
- clearHighlightBox (theGlCtx);
- if (myHighlightColor == NULL)
- {
- myHighlightColor = new OpenGl_Vec4 (theColor, 1.0f);
- }
- else
+ myHighlightStyle = theStyle;
+
+ highlight = 1;
+ if (myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX)
{
- myHighlightColor->xyz() = theColor;
+ highlightWithBndBox (theStruct);
}
}
// =======================================================================
-// function : clearHighlightColor
+// function : GraphicUnhighlight
// purpose :
// =======================================================================
-void OpenGl_Structure::clearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
+void OpenGl_Structure::GraphicUnhighlight()
{
- clearHighlightBox(theGlCtx);
- delete myHighlightColor;
- myHighlightColor = NULL;
+ highlight = 0;
+
+ if (myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX)
+ {
+ const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
+ clearHighlightBox (aContext);
+ }
+
+ myHighlightStyle.Nullify();
}
// =======================================================================
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
// Render named status
- if (highlight)
+ if (highlight && myHighlightBox.IsNull())
{
theWorkspace->SetHighlight (true);
}
// Apply local transformation
aCtx->ModelWorldState.Push();
- aCtx->ModelWorldState.SetCurrent (Transformation);
+ OpenGl_Mat4& aModelWorld = aCtx->ModelWorldState.ChangeCurrent();
+ if (!myTrsf.IsNull())
+ {
+ myTrsf->Trsf().GetMat4 (aModelWorld);
+ }
+ else
+ {
+ aModelWorld.InitIdentity();
+ }
const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
#if !defined(GL_ES_VERSION_2_0)
// detect scale transform
- if (aCtx->core11 != NULL)
+ if (aCtx->core11 != NULL
+ && !myTrsf.IsNull())
{
- const Standard_ShortReal aScaleX = Transformation.GetRow (0).xyz().SquareModulus();
- if (Abs (aScaleX - 1.f) > Precision::Confusion())
+ const Standard_Real aScale = myTrsf->ScaleFactor();
+ if (Abs (aScale - 1.0) > Precision::Confusion())
{
aCtx->SetGlNormalizeEnabled (Standard_True);
}
}
#endif
- if (TransformPersistence.Flags)
+ if (!myTrsfPers.IsNull())
{
- OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
- OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current();
- TransformPersistence.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView, theWorkspace->Width(), theWorkspace->Height());
+ OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current();
+ myTrsfPers->Apply (theWorkspace->View()->Camera(), aCtx->ProjectionState.Current(), aWorldView,
+ aCtx->Viewport()[2], aCtx->Viewport()[3]);
- aCtx->ProjectionState.Push();
aCtx->WorldViewState.Push();
- aCtx->ProjectionState.SetCurrent (aProjection);
aCtx->WorldViewState.SetCurrent (aWorldView);
- aCtx->ApplyProjectionMatrix();
#if !defined(GL_ES_VERSION_2_0)
if (!aCtx->IsGlNormalizeEnabled()
// Apply highlight color
const OpenGl_Vec4* aHighlightColor = theWorkspace->HighlightColor;
- if (myHighlightColor)
- theWorkspace->HighlightColor = myHighlightColor;
-
- // Set up plane equations for non-structure transformed global model-view matrix
- // List of planes to be applied to context state
- Handle(NCollection_Shared<Graphic3d_SequenceOfHClipPlane>) aUserPlanes, aDisabledPlanes;
+ if (!myHighlightStyle.IsNull())
+ theWorkspace->HighlightColor = myHighlightStyle->ColorFltPtr();
// Collect clipping planes of structure scope
- if (!myClipPlanes.IsEmpty())
+ aCtx->ChangeClipping().SetLocalPlanes (aCtx, myClipPlanes);
+
+ // True if structure is fully clipped
+ bool isClipped = false;
+ bool hasDisabled = false;
+ if (aCtx->Clipping().IsClippingOrCappingOn())
{
- for (Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes); aClippingIter.More(); aClippingIter.Next())
+ const Graphic3d_BndBox4f& aBBox = BoundingBox();
+ if (!myClipPlanes.IsNull()
+ && myClipPlanes->ToOverrideGlobal())
+ {
+ aCtx->ChangeClipping().DisableGlobal (aCtx);
+ hasDisabled = aCtx->Clipping().HasDisabled();
+ }
+ else if (!myTrsfPers.IsNull())
{
- const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value();
- if (!aClipPlane->IsOn())
+ if (myTrsfPers->IsZoomOrRotate())
{
- continue;
- }
+ // Zoom/rotate persistence object lives in two worlds at the same time.
+ // Global clipping planes can not be trivially applied without being converted
+ // into local space of transformation persistence object.
+ // As more simple alternative - just clip entire object by its anchor point defined in the world space.
+ const gp_Pnt anAnchor = myTrsfPers->AnchorPoint();
+ for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More() && aPlaneIt.IsGlobal(); aPlaneIt.Next())
+ {
+ const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+ if (!aPlane->IsOn())
+ {
+ continue;
+ }
- if (aUserPlanes.IsNull())
- {
- aUserPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>();
+ // check for clipping
+ const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
+ const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+ if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space
+ {
+ isClipped = true;
+ break;
+ }
+ }
}
- aUserPlanes->Append (aClipPlane);
- }
- }
- if (!aUserPlanes.IsNull())
- {
- // add planes at loaded view matrix state
- aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes);
- // Set OCCT state uniform variables
- aCtx->ShaderManager()->UpdateClippingState();
- }
-
- // True if structure is fully clipped
- bool isClipped = false;
+ aCtx->ChangeClipping().DisableGlobal (aCtx);
+ hasDisabled = aCtx->Clipping().HasDisabled();
+ }
- // Set of clipping planes that do not intersect the structure,
- // and thus can be disabled to improve rendering performance
- const Graphic3d_BndBox4f& aBBox = BoundingBox();
- if (!aCtx->Clipping().Planes().IsEmpty() && aBBox.IsValid() && TransformPersistence.Flags == Graphic3d_TMF_None)
- {
- for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aCtx->Clipping().Planes()); aPlaneIt.More(); aPlaneIt.Next())
+ // Set of clipping planes that do not intersect the structure,
+ // and thus can be disabled to improve rendering performance
+ if (aBBox.IsValid()
+ && myTrsfPers.IsNull())
{
- const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
- if (!aPlane->IsOn())
+ for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More(); aPlaneIt.Next())
{
- continue;
- }
+ const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+ if (!aPlane->IsOn())
+ {
+ continue;
+ }
- // check for clipping
- const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
- const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(),
- aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(),
- aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(),
- 1.0);
- if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space
- {
- isClipped = true;
- break;
- }
+ // check for clipping
+ const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
+ const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(),
+ aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(),
+ aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(),
+ 1.0);
+ if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space
+ {
+ isClipped = true;
+ break;
+ }
- // check for no intersection (e.g. object is "entirely not clipped")
- const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(),
- aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(),
- aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(),
- 1.0);
- if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space
- {
- aCtx->ChangeClipping().SetEnabled (aCtx, aPlane, Standard_False);
- if (aDisabledPlanes.IsNull())
+ // check for no intersection (e.g. object is "entirely not clipped")
+ const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(),
+ aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(),
+ aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(),
+ 1.0);
+ if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space
{
- aDisabledPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>();
- if (aUserPlanes.IsNull())
- {
- aCtx->ShaderManager()->UpdateClippingState();
- }
+ aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt, Standard_False);
+ hasDisabled = true;
}
- aDisabledPlanes->Append (aPlane);
}
}
+
+ if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
+ || hasDisabled)
+ {
+ // Set OCCT state uniform variables
+ aCtx->ShaderManager()->UpdateClippingState();
+ }
}
// Render groups
}
// Revert structure clippings
- if (!aDisabledPlanes.IsNull())
+ if (hasDisabled)
{
// enable planes that were previously disabled
- for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aDisabledPlanes); aPlaneIt.More(); aPlaneIt.Next())
- {
- aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt.Value(), Standard_True);
- }
- if (aUserPlanes.IsNull())
- {
- aCtx->ShaderManager()->RevertClippingState();
- }
+ aCtx->ChangeClipping().RestoreDisabled (aCtx);
}
- if (!aUserPlanes.IsNull())
+ aCtx->ChangeClipping().SetLocalPlanes (aCtx, Handle(Graphic3d_SequenceOfHClipPlane)());
+ if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
+ || hasDisabled)
{
- aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes);
-
// Set OCCT state uniform variables
aCtx->ShaderManager()->RevertClippingState();
}
// Restore local transformation
aCtx->ModelWorldState.Pop();
aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
- if (TransformPersistence.Flags)
+ if (!myTrsfPers.IsNull())
{
- aCtx->ProjectionState.Pop();
aCtx->WorldViewState.Pop();
- aCtx->ApplyProjectionMatrix();
}
// Restore highlight color
{
// Release groups
Clear (theGlCtx);
- clearHighlightColor (theGlCtx);
+ clearHighlightBox (theGlCtx);
+ myHighlightStyle.Nullify();
}
// =======================================================================