// Created on: 2011-08-01
// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+#include <OpenGl_CappingAlgo.hxx>
+#include <OpenGl_Context.hxx>
#include <OpenGl_GlCore11.hxx>
-
-#include <OpenGl_Structure.hxx>
-
-#include <OpenGl_Polyline.hxx>
-#include <OpenGl_Workspace.hxx>
+#include <OpenGl_ClippingIterator.hxx>
+#include <OpenGl_GraphicDriver.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
+#include <OpenGl_StructureShadow.hxx>
+#include <OpenGl_Vec.hxx>
#include <OpenGl_View.hxx>
+#include <OpenGl_Workspace.hxx>
-#include <OpenGl_telem_util.hxx>
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Structure,Graphic3d_CStructure)
+// =======================================================================
+// function : renderBoundingBox
+// purpose :
+// =======================================================================
+void OpenGl_Structure::renderBoundingBox (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+ if (!myBndBox.IsValid())
+ {
+ return;
+ }
-/*----------------------------------------------------------------------*/
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+ const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
+ const Graphic3d_ZLayerSettings& aLayer = myGraphicDriver->ZLayerSettings (myZLayer);
+ const Graphic3d_Vec3d aMoveVec = myTrsfPers.IsNull()
+ && !aLayer.OriginTransformation().IsNull()
+ ? -Graphic3d_Vec3d (aLayer.Origin().X(), aLayer.Origin().Y(), aLayer.Origin().Z())
+ : Graphic3d_Vec3d (0.0, 0.0, 0.0);
+ if (aCtx->core20fwd != NULL
+ && aCtx->ShaderManager()->BindBoundBoxProgram())
+ {
+ const Graphic3d_Vec3d aCenter = myBndBox.Center() + aMoveVec;
+ const Graphic3d_Vec3d aSize = myBndBox.Size();
+ aCtx->ActiveProgram()->SetUniform (aCtx, "occBBoxCenter", Graphic3d_Vec3 ((float )aCenter.x(), (float )aCenter.y(), (float )aCenter.z()));
+ aCtx->ActiveProgram()->SetUniform (aCtx, "occBBoxSize", Graphic3d_Vec3 ((float )aSize.x(), (float )aSize.y(), (float )aSize.z()));
+ aCtx->SetColor4fv (theWorkspace->InteriorColor());
+
+ const Handle(OpenGl_VertexBuffer)& aBoundBoxVertBuffer = aCtx->ShaderManager()->BoundBoxVertBuffer();
+ aBoundBoxVertBuffer->BindAttribute (aCtx, Graphic3d_TOA_POS);
+ aCtx->core20fwd->glDrawArrays (GL_LINES, 0, aBoundBoxVertBuffer->GetElemsNb());
+ aBoundBoxVertBuffer->UnbindAttribute(aCtx, Graphic3d_TOA_POS);
+ }
+#if !defined(GL_ES_VERSION_2_0)
+ else if (aCtx->core11 != NULL)
+ {
+ const Graphic3d_Vec3d aMind = myBndBox.CornerMin() + aMoveVec;
+ const Graphic3d_Vec3d aMaxd = myBndBox.CornerMax() + aMoveVec;
+ const Graphic3d_Vec3 aMin ((float )aMind.x(), (float )aMind.y(), (float )aMind.z());
+ const Graphic3d_Vec3 aMax ((float )aMaxd.x(), (float )aMaxd.y(), (float )aMaxd.z());
+ const OpenGl_Vec3 aVerts[16] =
+ {
+ OpenGl_Vec3 (aMin.x(), aMin.y(), aMin.z()),
+ OpenGl_Vec3 (aMin.x(), aMin.y(), aMax.z()),
+ OpenGl_Vec3 (aMin.x(), aMax.y(), aMax.z()),
+ OpenGl_Vec3 (aMin.x(), aMax.y(), aMin.z()),
+ OpenGl_Vec3 (aMin.x(), aMin.y(), aMin.z()),
+ OpenGl_Vec3 (aMax.x(), aMin.y(), aMin.z()),
+ OpenGl_Vec3 (aMax.x(), aMin.y(), aMax.z()),
+ OpenGl_Vec3 (aMax.x(), aMax.y(), aMax.z()),
+ OpenGl_Vec3 (aMax.x(), aMax.y(), aMin.z()),
+ OpenGl_Vec3 (aMax.x(), aMin.y(), aMin.z()),
+ OpenGl_Vec3 (aMax.x(), aMax.y(), aMin.z()),
+ OpenGl_Vec3 (aMin.x(), aMax.y(), aMin.z()),
+ OpenGl_Vec3 (aMin.x(), aMax.y(), aMax.z()),
+ OpenGl_Vec3 (aMax.x(), aMax.y(), aMax.z()),
+ OpenGl_Vec3 (aMax.x(), aMin.y(), aMax.z()),
+ OpenGl_Vec3 (aMin.x(), aMin.y(), aMax.z())
+ };
+
+ aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID, Graphic3d_TOSM_UNLIT, Graphic3d_AlphaMode_Opaque, false, Handle(OpenGl_ShaderProgram)());
+ aCtx->SetColor4fv (theWorkspace->InteriorColor());
+ aCtx->core11fwd->glDisable (GL_LIGHTING);
+ aCtx->core11->glEnableClientState (GL_VERTEX_ARRAY);
+ aCtx->core11->glVertexPointer (3, GL_FLOAT, 0, aVerts[0].GetData());
+ aCtx->core11fwd->glDrawArrays (GL_LINE_STRIP, 0, 16);
+ aCtx->core11->glDisableClientState (GL_VERTEX_ARRAY);
+ }
+#endif
+ aCtx->BindTextures (aPrevTexture);
+}
-static void call_util_transpose_mat (float tmat[16], float mat[4][4])
+// =======================================================================
+// function : OpenGl_Structure
+// purpose :
+// =======================================================================
+OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
+: Graphic3d_CStructure (theManager),
+ myInstancedStructure (NULL),
+ myIsRaytracable (Standard_False),
+ myModificationState (0),
+ myIsMirrored (Standard_False)
{
- int i, j;
-
- for (i=0; i<4; i++)
- for (j=0; j<4; j++)
- tmat[j*4+i] = mat[i][j];
+ updateLayerTransformation();
}
-/*----------------------------------------------------------------------*/
-
-OpenGl_Structure::OpenGl_Structure ()
-: myTransformation(NULL),
- myTransPers(NULL),
- myDegenerateModel(NULL),
- myAspectLine(NULL),
- myAspectFace(NULL),
- myAspectMarker(NULL),
- myAspectText(NULL),
- myHighlightBox(NULL),
- myHighlightColor(NULL),
- myNamedStatus(0),
- myZLayer(0)
+// =======================================================================
+// function : ~OpenGl_Structure
+// purpose :
+// =======================================================================
+OpenGl_Structure::~OpenGl_Structure()
{
+ Release (Handle(OpenGl_Context)());
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : SetZLayer
+// purpose :
+// =======================================================================
+void OpenGl_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerIndex)
+{
+ Graphic3d_CStructure::SetZLayer (theLayerIndex);
+ updateLayerTransformation();
+}
-OpenGl_Structure::~OpenGl_Structure ()
+// =======================================================================
+// function : SetTransformation
+// purpose :
+// =======================================================================
+void OpenGl_Structure::SetTransformation (const Handle(Geom_Transformation)& theTrsf)
{
- if (myTransformation)
+ myTrsf = theTrsf;
+ myIsMirrored = Standard_False;
+ if (!myTrsf.IsNull())
{
- delete myTransformation;
- myTransformation = NULL;
+ // 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 (myTransPers)
- {
- delete myTransPers;
- myTransPers = NULL;
- }
- if (myDegenerateModel)
- {
- delete myDegenerateModel;
- myDegenerateModel = NULL;
- }
- if (myAspectLine)
- {
- delete myAspectLine;
- myAspectLine = NULL;
- }
- if (myAspectFace)
- {
- delete myAspectFace;
- myAspectFace = NULL;
- }
- if (myAspectMarker)
- {
- delete myAspectMarker;
- myAspectMarker = NULL;
- }
- if (myAspectText)
+
+ updateLayerTransformation();
+ if (IsRaytracable())
{
- delete myAspectText;
- myAspectText = NULL;
+ ++myModificationState;
}
- ClearHighlightColor();
- // Delete groups
- Clear();
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetTransformation(const float *AMatrix)
+// =======================================================================
+// function : SetTransformPersistence
+// purpose :
+// =======================================================================
+void OpenGl_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
{
- if (!myTransformation)
- myTransformation = new OpenGl_Matrix;
-
- matcpy( myTransformation->mat, AMatrix );
+ myTrsfPers = theTrsfPers;
+ updateLayerTransformation();
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
+// =======================================================================
+// function : updateLayerTransformation
+// purpose :
+// =======================================================================
+void OpenGl_Structure::updateLayerTransformation()
{
- if (!myTransPers)
- myTransPers = new TEL_TRANSFORM_PERSISTENCE;
+ gp_Trsf aRenderTrsf;
+ if (!myTrsf.IsNull())
+ {
+ aRenderTrsf = myTrsf->Trsf();
+ }
- myTransPers->mode = ATransPers.Flag;
- myTransPers->pointX = ATransPers.Point.x;
- myTransPers->pointY = ATransPers.Point.y;
- myTransPers->pointZ = ATransPers.Point.z;
+ const Graphic3d_ZLayerSettings& aLayer = myGraphicDriver->ZLayerSettings (myZLayer);
+ if (!aLayer.OriginTransformation().IsNull()
+ && myTrsfPers.IsNull())
+ {
+ aRenderTrsf.SetTranslationPart (aRenderTrsf.TranslationPart() - aLayer.Origin());
+ }
+ aRenderTrsf.GetMat4 (myRenderTrsf);
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetDegenerateModel (const Standard_Integer AMode, const float ASkipRatio)
+// =======================================================================
+// function : GraphicHighlight
+// purpose :
+// =======================================================================
+void OpenGl_Structure::GraphicHighlight (const Handle(Graphic3d_PresentationAttributes)& theStyle)
{
- if (!myDegenerateModel)
- myDegenerateModel = new DEGENERATION;
-
- myDegenerateModel->mode = AMode;
- myDegenerateModel->skipRatio = ASkipRatio;
+ myHighlightStyle = theStyle;
+ highlight = 1;
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
+// =======================================================================
+// function : GraphicUnhighlight
+// purpose :
+// =======================================================================
+void OpenGl_Structure::GraphicUnhighlight()
{
- if (!myAspectLine)
- myAspectLine = new OpenGl_AspectLine;
- myAspectLine->SetContext( AContext );
+ highlight = 0;
+ myHighlightStyle.Nullify();
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA &AContext)
+// =======================================================================
+// function : OnVisibilityChanged
+// purpose :
+// =======================================================================
+void OpenGl_Structure::OnVisibilityChanged()
{
- if (!myAspectFace)
- myAspectFace = new OpenGl_AspectFace;
- myAspectFace->SetContext( AContext );
+ if (IsRaytracable())
+ {
+ ++myModificationState;
+ }
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER &AContext)
+// =======================================================================
+// function : IsRaytracable
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_Structure::IsRaytracable() const
{
- if (!myAspectMarker)
- myAspectMarker = new OpenGl_AspectMarker;
- myAspectMarker->SetContext( AContext );
-}
-
-/*----------------------------------------------------------------------*/
+ if (!myGroups.IsEmpty()
+ && myIsRaytracable)
+ {
+ return Standard_True;
+ }
-void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
-{
- if (!myAspectText)
- myAspectText = new OpenGl_AspectText;
- myAspectText->SetContext( AContext );
+ return myInstancedStructure != NULL
+ && myInstancedStructure->IsRaytracable();
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetHighlightBox (const CALL_DEF_BOUNDBOX &ABoundBox)
+// =======================================================================
+// function : UpdateRaytracableState
+// purpose :
+// =======================================================================
+void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const
{
- if (!myHighlightBox)
- myHighlightBox = new OpenGl_Group;
- else
- myHighlightBox->Clear();
-
- CALL_DEF_CONTEXTLINE context_line;
- context_line.Color = ABoundBox.Color;
- context_line.LineType = Aspect_TOL_SOLID;
- context_line.Width = 1.0f;
- myHighlightBox->SetAspectLine( context_line );
-
-#define CALL_MAX_BOUNDBOXSIZE 16
-
- Graphic3d_Array1OfVertex points(1,CALL_MAX_BOUNDBOXSIZE);
- const float Xm = ABoundBox.Pmin.x;
- const float Ym = ABoundBox.Pmin.y;
- const float Zm = ABoundBox.Pmin.z;
- const float XM = ABoundBox.Pmax.x;
- const float YM = ABoundBox.Pmax.y;
- const float ZM = ABoundBox.Pmax.z;
- points( 1).SetCoord(Xm,Ym,Zm);
- points( 2).SetCoord(Xm,Ym,ZM);
- points( 3).SetCoord(Xm,YM,ZM);
- points( 4).SetCoord(Xm,YM,Zm);
- points( 5).SetCoord(Xm,Ym,Zm);
- points( 6).SetCoord(XM,Ym,Zm);
- points( 7).SetCoord(XM,Ym,ZM);
- points( 8).SetCoord(XM,YM,ZM);
- points( 9).SetCoord(XM,YM,Zm);
- points(10).SetCoord(XM,Ym,Zm);
- points(11).SetCoord(XM,YM,Zm);
- points(12).SetCoord(Xm,YM,Zm);
- points(13).SetCoord(Xm,YM,ZM);
- points(14).SetCoord(XM,YM,ZM);
- points(15).SetCoord(XM,Ym,ZM);
- points(16).SetCoord(Xm,Ym,ZM);
-
- OpenGl_Polyline *apolyline = new OpenGl_Polyline(points);
- myHighlightBox->AddElement( TelPolyline, apolyline );
-}
-
-/*----------------------------------------------------------------------*/
+ myIsRaytracable = !toCheck;
+ if (!myIsRaytracable)
+ {
+ for (OpenGl_Structure::GroupIterator anIter (myGroups); anIter.More(); anIter.Next())
+ {
+ if (anIter.Value()->IsRaytracable())
+ {
+ myIsRaytracable = Standard_True;
+ break;
+ }
+ }
+ }
-void OpenGl_Structure::ClearHighlightBox ()
-{
- if (myHighlightBox)
+ if (IsRaytracable())
{
- delete myHighlightBox;
- myHighlightBox = NULL;
+ ++myModificationState;
}
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetHighlightColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
+// =======================================================================
+// function : Connect
+// purpose :
+// =======================================================================
+void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
{
- ClearHighlightBox();
- if (!myHighlightColor)
- myHighlightColor = new TEL_COLOUR;
-
- myHighlightColor->rgb[0] = R;
- myHighlightColor->rgb[1] = G;
- myHighlightColor->rgb[2] = B;
- myHighlightColor->rgb[3] = 1.F;
-}
+ OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
-/*----------------------------------------------------------------------*/
+ Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct,
+ "Error! Instanced structure is already defined");
-void OpenGl_Structure::ClearHighlightColor ()
-{
- ClearHighlightBox();
- if (myHighlightColor)
+ myInstancedStructure = aStruct;
+
+ if (aStruct->IsRaytracable())
{
- delete myHighlightColor;
- myHighlightColor = NULL;
+ UpdateStateIfRaytracable (Standard_False);
}
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
+// =======================================================================
+// function : Disconnect
+// purpose :
+// =======================================================================
+void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
{
- Disconnect (AStructure);
- myConnected.Append(AStructure);
-}
-
-/*----------------------------------------------------------------------*/
+ OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
-void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
-{
- OpenGl_ListOfStructure::Iterator its(myConnected);
- while (its.More())
+ if (myInstancedStructure == aStruct)
{
- // Check for the given structure
- if (its.Value() == AStructure)
+ myInstancedStructure = NULL;
+
+ if (aStruct->IsRaytracable())
{
- myConnected.Remove(its);
- return;
+ UpdateStateIfRaytracable();
}
- its.Next();
}
}
-/*----------------------------------------------------------------------*/
-
-OpenGl_Group * OpenGl_Structure::AddGroup ()
+// =======================================================================
+// function : NewGroup
+// purpose :
+// =======================================================================
+Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct)
{
- // Create new group
- OpenGl_Group *g = new OpenGl_Group;
- myGroups.Append(g);
- return g;
+ Handle(OpenGl_Group) aGroup = new OpenGl_Group (theStruct);
+ myGroups.Append (aGroup);
+ return aGroup;
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::RemoveGroup (const OpenGl_Group *AGroup)
+// =======================================================================
+// function : RemoveGroup
+// purpose :
+// =======================================================================
+void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
{
- OpenGl_ListOfGroup::Iterator itg(myGroups);
- while (itg.More())
+ if (theGroup.IsNull())
+ {
+ return;
+ }
+
+ for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
{
// Check for the given group
- if (itg.Value() == AGroup)
+ if (aGroupIter.Value() == theGroup)
{
- // Delete object
- delete AGroup;
- myGroups.Remove(itg);
+ const Standard_Boolean wasRaytracable =
+ static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable();
+
+ theGroup->Clear (Standard_False);
+
+ if (wasRaytracable)
+ {
+ UpdateStateIfRaytracable();
+ }
+
+ myGroups.Remove (aGroupIter);
return;
}
- itg.Next();
}
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : Clear
+// purpose :
+// =======================================================================
+void OpenGl_Structure::Clear()
+{
+ Clear (GlDriver()->GetSharedContext());
+}
-void OpenGl_Structure::Clear ()
+// =======================================================================
+// function : Clear
+// purpose :
+// =======================================================================
+void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
{
- OpenGl_ListOfGroup::Iterator itg(myGroups);
- while (itg.More())
+ Standard_Boolean aRaytracableGroupDeleted (Standard_False);
+
+ // Release groups
+ for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
{
+ aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable();
+
// Delete objects
- delete itg.Value();
- itg.Next();
+ aGroupIter.ChangeValue()->Release (theGlCtx);
}
myGroups.Clear();
+
+ if (aRaytracableGroupDeleted)
+ {
+ myIsRaytracable = Standard_False;
+ }
+
+ Is2dText = Standard_False;
+ IsForHighlight = Standard_False;
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : renderGeometry
+// purpose :
+// =======================================================================
+void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace,
+ bool& theHasClosed) const
+{
+ if (myInstancedStructure != NULL)
+ {
+ myInstancedStructure->renderGeometry (theWorkspace, theHasClosed);
+ }
+
+ for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
+ {
+ theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
+ aGroupIter.Value()->Render (theWorkspace);
+ }
+}
-void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+// =======================================================================
+// function : Render
+// purpose :
+// =======================================================================
+void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
{
// Process the structure only if visible
- if ( myNamedStatus & OPENGL_NS_HIDE )
+ if (!visible)
+ {
return;
+ }
- // Render named status
- const Standard_Integer named_status = AWorkspace->NamedStatus;
- AWorkspace->NamedStatus |= myNamedStatus;
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- // Is rendering in ADD or IMMEDIATE mode?
- const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
+ // Render named status
+ if (highlight && !myHighlightStyle.IsNull() && myHighlightStyle->Method() != Aspect_TOHM_BOUNDBOX)
+ {
+ theWorkspace->SetHighlightStyle (myHighlightStyle);
+ }
// Apply local transformation
- GLint matrix_mode = 0;
- const OpenGl_Matrix *local_trsf = NULL;
- if (myTransformation)
+ aCtx->ModelWorldState.Push();
+ OpenGl_Mat4& aModelWorld = aCtx->ModelWorldState.ChangeCurrent();
+ aModelWorld = myRenderTrsf;
+
+ const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
+#if !defined(GL_ES_VERSION_2_0)
+ // detect scale transform
+ if (aCtx->core11 != NULL
+ && !myTrsf.IsNull())
{
- if (isImmediate)
+ const Standard_Real aScale = myTrsf->ScaleFactor();
+ if (Abs (aScale - 1.0) > Precision::Confusion())
{
- float mat16[16];
- call_util_transpose_mat (mat16, myTransformation->mat);
- glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
- glMatrixMode (GL_MODELVIEW);
- glPushMatrix ();
- glScalef (1.F, 1.F, 1.F);
- glMultMatrixf (mat16);
+ aCtx->SetGlNormalizeEnabled (Standard_True);
}
- else
- {
- glMatrixMode (GL_MODELVIEW);
- glPushMatrix();
+ }
+#endif
- local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
+ if (!myTrsfPers.IsNull())
+ {
+ aCtx->WorldViewState.Push();
+ OpenGl_Mat4& aWorldView = aCtx->WorldViewState.ChangeCurrent();
+ myTrsfPers->Apply (theWorkspace->View()->Camera(),
+ aCtx->ProjectionState.Current(), aWorldView,
+ aCtx->VirtualViewport()[2], aCtx->VirtualViewport()[3]);
+
+ #if !defined(GL_ES_VERSION_2_0)
+ if (!aCtx->IsGlNormalizeEnabled()
+ && aCtx->core11 != NULL)
+ {
+ const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView);
+ if (Abs (aScale - 1.0) > Precision::Confusion())
+ {
+ aCtx->SetGlNormalizeEnabled (Standard_True);
+ }
}
+ #endif
}
- // Apply transform persistence
- const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
- if ( myTransPers && myTransPers->mode != 0 )
+ // Take into account transform persistence
+ aCtx->ApplyModelViewMatrix();
+
+ // remember aspects
+ const OpenGl_Aspects* aPrevAspectFace = theWorkspace->Aspects();
+
+ // Apply correction for mirror transform
+ if (myIsMirrored)
{
- trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
+ aCtx->core11fwd->glFrontFace (GL_CW);
}
- // Apply degeneration
- if (myDegenerateModel)
+ // Collect clipping planes of structure scope
+ aCtx->ChangeClipping().SetLocalPlanes (myClipPlanes);
+
+ // True if structure is fully clipped
+ bool isClipped = false;
+ bool hasDisabled = false;
+ if (aCtx->Clipping().IsClippingOrCappingOn())
{
- if ( AWorkspace->NamedStatus & OPENGL_NS_DEGENERATION )
+ const Graphic3d_BndBox3d& aBBox = BoundingBox();
+ if (!myClipPlanes.IsNull()
+ && myClipPlanes->ToOverrideGlobal())
+ {
+ aCtx->ChangeClipping().DisableGlobal();
+ hasDisabled = aCtx->Clipping().HasDisabled();
+ }
+ else if (!myTrsfPers.IsNull())
{
- AWorkspace->DegenerateModel = myDegenerateModel->mode;
- switch ( AWorkspace->DegenerateModel )
+ if (myTrsfPers->IsZoomOrRotate())
{
- case 0: break;
+ // 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;
+ }
+
+ // check for clipping
+ const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+ if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
+ {
+ isClipped = true;
+ break;
+ }
+ }
+ }
- default:
- glLineWidth ( 1.0 );
- glDisable ( GL_LINE_STIPPLE );
+ aCtx->ChangeClipping().DisableGlobal();
+ hasDisabled = aCtx->Clipping().HasDisabled();
+ }
- case 1:
- AWorkspace->SkipRatio = myDegenerateModel->skipRatio;
+ // Set of clipping planes that do not intersect the structure,
+ // and thus can be disabled to improve rendering performance
+ if (aBBox.IsValid()
+ && myTrsfPers.IsNull())
+ {
+ for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More(); aPlaneIt.Next())
+ {
+ const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+ if (aPlaneIt.IsDisabled())
+ {
+ continue;
+ }
+
+ const Graphic3d_ClipState aBoxState = aPlane->ProbeBox (aBBox);
+ if (aBoxState == Graphic3d_ClipState_In)
+ {
+ aCtx->ChangeClipping().SetEnabled (aPlaneIt, false);
+ hasDisabled = true;
+ }
+ else if (aBoxState == Graphic3d_ClipState_Out && myBndBoxClipCheck)
+ {
+ isClipped = true;
+ break;
+ }
}
}
- }
- // Apply aspects
- const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
- const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
- const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
- const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
- if (myAspectLine)
- AWorkspace->SetAspectLine(myAspectLine);
- if (myAspectFace)
- AWorkspace->SetAspectFace(myAspectFace);
- if (myAspectMarker)
- AWorkspace->SetAspectMarker(myAspectMarker);
- if (myAspectText)
- AWorkspace->SetAspectText(myAspectText);
+ if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
+ || hasDisabled)
+ {
+ // Set OCCT state uniform variables
+ aCtx->ShaderManager()->UpdateClippingState();
+ }
+ }
- // Apply highlight box
- if (myHighlightBox)
- myHighlightBox->Render( AWorkspace );
+ // Render groups
+ bool hasClosedPrims = false;
+ if (!isClipped)
+ {
+ renderGeometry (theWorkspace, hasClosedPrims);
+ }
- // Apply highlight color
- const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
- if (myHighlightColor)
- AWorkspace->HighlightColor = myHighlightColor;
+ // Reset correction for mirror transform
+ if (myIsMirrored)
+ {
+ aCtx->core11fwd->glFrontFace (GL_CCW);
+ }
- // Render connected structures
- OpenGl_ListOfStructure::Iterator its(myConnected);
- while (its.More())
+ // Render capping for structure groups
+ if (hasClosedPrims
+ && aCtx->Clipping().IsCappingOn())
{
- its.Value()->Render(AWorkspace);
- its.Next();
+ OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this);
}
- // Render groups
- OpenGl_ListOfGroup::Iterator itg(myGroups);
- while (itg.More())
+ // Revert structure clippings
+ if (hasDisabled)
{
- itg.Value()->Render(AWorkspace);
- itg.Next();
+ // enable planes that were previously disabled
+ aCtx->ChangeClipping().RestoreDisabled();
+ }
+ aCtx->ChangeClipping().SetLocalPlanes (Handle(Graphic3d_SequenceOfHClipPlane)());
+ if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
+ || hasDisabled)
+ {
+ // Set OCCT state uniform variables
+ aCtx->ShaderManager()->RevertClippingState();
}
- // Restore highlight color
- AWorkspace->HighlightColor = highlight_color;
+ // Restore local transformation
+ aCtx->ModelWorldState.Pop();
+ aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
// Restore aspects
- AWorkspace->SetAspectLine(aspect_line);
- AWorkspace->SetAspectFace(aspect_face);
- AWorkspace->SetAspectMarker(aspect_marker);
- AWorkspace->SetAspectText(aspect_text);
+ theWorkspace->SetAspects (aPrevAspectFace);
- // Restore transform persistence
- if ( myTransPers && myTransPers->mode != 0 )
+ // Apply highlight box
+ if (!isClipped
+ && !myHighlightStyle.IsNull()
+ && myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX)
{
- AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
+ aCtx->ApplyModelViewMatrix();
+ theWorkspace->SetHighlightStyle (myHighlightStyle);
+ renderBoundingBox (theWorkspace);
}
- // Restore local transformation
- if (myTransformation)
+ if (!myTrsfPers.IsNull())
{
- if (isImmediate)
- {
- glPopMatrix ();
- glMatrixMode (matrix_mode);
- }
- else
- {
- AWorkspace->SetStructureMatrix(local_trsf);
-
- glMatrixMode (GL_MODELVIEW);
- glPopMatrix();
- }
+ aCtx->WorldViewState.Pop();
}
// Restore named status
- AWorkspace->NamedStatus = named_status;
+ theWorkspace->SetHighlightStyle (Handle(Graphic3d_PresentationAttributes)());
}
-//=======================================================================
-//function : SetZLayer
-//purpose :
-//=======================================================================
+// =======================================================================
+// function : Release
+// purpose :
+// =======================================================================
+void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
+{
+ // Release groups
+ Clear (theGlCtx);
+ myHighlightStyle.Nullify();
+}
-void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
+// =======================================================================
+// function : ReleaseGlResources
+// purpose :
+// =======================================================================
+void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
{
- myZLayer = theLayerIndex;
+ for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
+ {
+ aGroupIter.ChangeValue()->Release (theGlCtx);
+ }
}
//=======================================================================
-//function : GetZLayer
-//purpose :
+//function : ShadowLink
+//purpose :
//=======================================================================
-
-Standard_Integer OpenGl_Structure::GetZLayer () const
+Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const
{
- return myZLayer;
+ return new OpenGl_StructureShadow (theManager, this);
}