// 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_GraphicDriver.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
+#include <OpenGl_StructureShadow.hxx>
+#include <OpenGl_telem_util.hxx>
+#include <OpenGl_Vec.hxx>
+#include <OpenGl_View.hxx>
+#include <OpenGl_Workspace.hxx>
-#include <OpenGl_Structure.hxx>
+#include <Graphic3d_SequenceOfHClipPlane.hxx>
-#include <OpenGl_Polyline.hxx>
-#include <OpenGl_Workspace.hxx>
-#include <OpenGl_View.hxx>
-#include <OpenGl_telem_util.hxx>
+//! Auxiliary class for bounding box presentation
+class OpenGl_BndBoxPrs : public OpenGl_Element
+{
+public:
-/*----------------------------------------------------------------------*/
+ //! Main constructor
+ OpenGl_BndBoxPrs (const Graphic3d_BndBox4f& theBndBox)
+ {
+ const float Xm = theBndBox.CornerMin().x();
+ const float Ym = theBndBox.CornerMin().y();
+ const float Zm = theBndBox.CornerMin().z();
+ const float XM = theBndBox.CornerMax().x();
+ const float YM = theBndBox.CornerMax().y();
+ const float ZM = theBndBox.CornerMax().z();
+
+ myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm);
+ myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM);
+ myVerts[2] = OpenGl_Vec3 (Xm, YM, ZM);
+ myVerts[3] = OpenGl_Vec3 (Xm, YM, Zm);
+ myVerts[4] = OpenGl_Vec3 (Xm, Ym, Zm);
+ myVerts[5] = OpenGl_Vec3 (XM, Ym, Zm);
+ myVerts[6] = OpenGl_Vec3 (XM, Ym, ZM);
+ myVerts[7] = OpenGl_Vec3 (XM, YM, ZM);
+ myVerts[8] = OpenGl_Vec3 (XM, YM, Zm);
+ myVerts[9] = OpenGl_Vec3 (XM, Ym, Zm);
+ myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
+ myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
+ myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
+ myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
+ myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
+ myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
+ }
-static void call_util_transpose_mat (float tmat[16], float mat[4][4])
-{
- int i, j;
+ //! Render presentation
+ virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
+ {
+ #if !defined(GL_ES_VERSION_2_0)
+ // Apply line aspect
+ const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
+ const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
- for (i=0; i<4; i++)
- for (j=0; j<4; j++)
- tmat[j*4+i] = mat[i][j];
-}
+ glDisable (GL_LIGHTING);
+
+ // Use highlight colors
+ theWorkspace->GetGlContext()->core11->glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
+
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
+ glDrawArrays (GL_LINE_STRIP, 0, 16);
+ glDisableClientState (GL_VERTEX_ARRAY);
+
+ // restore aspects
+ if (!aPrevTexture.IsNull())
+ {
+ theWorkspace->EnableTexture (aPrevTexture);
+ }
+ #endif
+ }
+
+ //! Release graphical resources
+ virtual void Release (OpenGl_Context*)
+ {
+ //
+ }
+
+protected:
+
+ //! Protected destructor
+ virtual ~OpenGl_BndBoxPrs() {}
+
+private:
+
+ OpenGl_Vec3 myVerts[16]; //!< vertices array
+
+public:
+
+ DEFINE_STANDARD_ALLOC
+
+};
/*----------------------------------------------------------------------*/
-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 (const Handle(Graphic3d_StructureManager)& theManager)
+: Graphic3d_CStructure (theManager),
+ myTransformation (NULL),
+ myAspectLine (NULL),
+ myAspectFace (NULL),
+ myAspectMarker (NULL),
+ myAspectText (NULL),
+ myHighlightColor (NULL),
+ myInstancedStructure (NULL),
+ myIsRaytracable (Standard_False),
+ myModificationState (0),
+ myIsCulled (Standard_True),
+ myIsMirrored (Standard_False)
{
+ //
}
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : ~OpenGl_Structure
+// purpose :
+// =======================================================================
OpenGl_Structure::~OpenGl_Structure()
{
Release (Handle(OpenGl_Context)());
delete myTransformation; myTransformation = NULL;
- delete myTransPers; myTransPers = NULL;
- delete myDegenerateModel; myDegenerateModel = NULL;
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetTransformation(const float *AMatrix)
+// =======================================================================
+// function : UpdateAspects
+// purpose :
+// =======================================================================
+void OpenGl_Structure::UpdateAspects()
{
- if (!myTransformation)
- myTransformation = new OpenGl_Matrix();
+ if (ContextLine.IsDef)
+ SetAspectLine (ContextLine);
- matcpy( myTransformation->mat, AMatrix );
-}
+ if (ContextFillArea.IsDef)
+ SetAspectFace (ContextFillArea);
-/*----------------------------------------------------------------------*/
+ if (ContextMarker.IsDef)
+ SetAspectMarker (ContextMarker);
+
+ if (ContextText.IsDef)
+ SetAspectText (ContextText);
+}
-void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
+// =======================================================================
+// function : UpdateTransformation
+// purpose :
+// =======================================================================
+void OpenGl_Structure::UpdateTransformation()
{
- if (!myTransPers)
- myTransPers = new TEL_TRANSFORM_PERSISTENCE;
+ if (myTransformation == NULL)
+ {
+ myTransformation = new OpenGl_Matrix();
+ }
- myTransPers->mode = ATransPers.Flag;
- myTransPers->pointX = ATransPers.Point.x;
- myTransPers->pointY = ATransPers.Point.y;
- myTransPers->pointZ = ATransPers.Point.z;
-}
+ Standard_ShortReal (*aMat)[4] = Graphic3d_CStructure::Transformation;
-/*----------------------------------------------------------------------*/
+ Standard_ShortReal aDet =
+ aMat[0][0] * (aMat[1][1] * aMat[2][2] - aMat[2][1] * aMat[1][2]) -
+ aMat[0][1] * (aMat[1][0] * aMat[2][2] - aMat[2][0] * aMat[1][2]) +
+ aMat[0][2] * (aMat[1][0] * aMat[2][1] - aMat[2][0] * aMat[1][1]);
-void OpenGl_Structure::SetDegenerateModel (const Standard_Integer AMode, const float ASkipRatio)
-{
- if (!myDegenerateModel)
- myDegenerateModel = new DEGENERATION;
+ // Determinant of transform matrix less then 0 means that mirror transform applied.
+ myIsMirrored = aDet < 0.0f;
- myDegenerateModel->mode = AMode;
- myDegenerateModel->skipRatio = ASkipRatio;
-}
+ matcpy (myTransformation->mat, &Graphic3d_CStructure::Transformation[0][0]);
-/*----------------------------------------------------------------------*/
+ if (IsRaytracable())
+ {
+ ++myModificationState;
+ }
+}
-void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
+// =======================================================================
+// function : SetAspectLine
+// purpose :
+// =======================================================================
+void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &theAspect)
{
if (!myAspectLine)
+ {
myAspectLine = new OpenGl_AspectLine();
- myAspectLine->SetContext( AContext );
+ }
+ myAspectLine->SetAspect (theAspect);
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA &AContext)
+// =======================================================================
+// function : SetAspectFace
+// purpose :
+// =======================================================================
+void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect)
{
if (!myAspectFace)
+ {
myAspectFace = new OpenGl_AspectFace();
- myAspectFace->SetContext( AContext );
-}
+ }
+ myAspectFace->SetAspect (theAspect);
-/*----------------------------------------------------------------------*/
+ if (IsRaytracable())
+ {
+ ++myModificationState;
+ }
+}
-void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER &AContext)
+// =======================================================================
+// function : SetAspectMarker
+// purpose :
+// =======================================================================
+void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect)
{
if (!myAspectMarker)
+ {
myAspectMarker = new OpenGl_AspectMarker();
- myAspectMarker->SetContext( AContext );
+ }
+ myAspectMarker->SetAspect (theAspect);
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
+// =======================================================================
+// function : SetAspectText
+// purpose :
+// =======================================================================
+void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &theAspect)
{
if (!myAspectText)
+ {
myAspectText = new OpenGl_AspectText();
- myAspectText->SetContext( AContext );
+ }
+ myAspectText->SetAspect (theAspect);
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
- const CALL_DEF_BOUNDBOX& theBoundBox)
+// =======================================================================
+// function : clearHighlightBox
+// purpose :
+// =======================================================================
+void OpenGl_Structure::clearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
{
- if (myHighlightBox != NULL)
+ if (!myHighlightBox.IsNull())
{
myHighlightBox->Release (theGlCtx);
+ myHighlightBox.Nullify();
+ }
+}
+
+// =======================================================================
+// 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)
+{
+ const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
+ if (!theToCreate)
+ {
+ clearHighlightBox (aContext);
+ return;
+ }
+
+ if (!myHighlightBox.IsNull())
+ {
+ myHighlightBox->Release (aContext);
}
else
{
- myHighlightBox = new OpenGl_Group();
+ myHighlightBox = new OpenGl_Group (theStruct);
}
- CALL_DEF_CONTEXTLINE aContextLine;
- aContextLine.Color = theBoundBox.Color;
+ CALL_DEF_CONTEXTLINE& aContextLine = myHighlightBox->ChangeContextLine();
+ aContextLine.IsDef = 1;
+ aContextLine.Color = HighlightColor;
aContextLine.LineType = Aspect_TOL_SOLID;
aContextLine.Width = 1.0f;
- myHighlightBox->SetAspectLine (aContextLine);
-
-#define CALL_MAX_BOUNDBOXSIZE 16
-
- Graphic3d_Array1OfVertex aPoints (1, CALL_MAX_BOUNDBOXSIZE);
- const float Xm = theBoundBox.Pmin.x;
- const float Ym = theBoundBox.Pmin.y;
- const float Zm = theBoundBox.Pmin.z;
- const float XM = theBoundBox.Pmax.x;
- const float YM = theBoundBox.Pmax.y;
- const float ZM = theBoundBox.Pmax.z;
- aPoints( 1).SetCoord (Xm, Ym, Zm);
- aPoints( 2).SetCoord (Xm, Ym, ZM);
- aPoints( 3).SetCoord (Xm, YM, ZM);
- aPoints( 4).SetCoord (Xm, YM, Zm);
- aPoints( 5).SetCoord (Xm, Ym, Zm);
- aPoints( 6).SetCoord (XM, Ym, Zm);
- aPoints( 7).SetCoord (XM, Ym, ZM);
- aPoints( 8).SetCoord (XM, YM, ZM);
- aPoints( 9).SetCoord (XM, YM, Zm);
- aPoints(10).SetCoord (XM, Ym, Zm);
- aPoints(11).SetCoord (XM, YM, Zm);
- aPoints(12).SetCoord (Xm, YM, Zm);
- aPoints(13).SetCoord (Xm, YM, ZM);
- aPoints(14).SetCoord (XM, YM, ZM);
- aPoints(15).SetCoord (XM, Ym, ZM);
- aPoints(16).SetCoord (Xm, Ym, ZM);
-
- OpenGl_Polyline* aPolyline = new OpenGl_Polyline (aPoints);
- myHighlightBox->AddElement (TelPolyline, aPolyline);
-}
-
-/*----------------------------------------------------------------------*/
+ myHighlightBox->UpdateAspectLine (Standard_True);
-void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
-{
- if (myHighlightBox != NULL)
- {
- OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
- }
+ OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox);
+ myHighlightBox->AddElement (aBndBoxPrs);
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
- const Standard_ShortReal R,
- const Standard_ShortReal G,
- const Standard_ShortReal B)
+// =======================================================================
+// function : setHighlightColor
+// purpose :
+// =======================================================================
+void OpenGl_Structure::setHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
+ const Graphic3d_Vec3& theColor)
{
- ClearHighlightBox (theGlCtx);
+ clearHighlightBox (theGlCtx);
if (myHighlightColor == NULL)
{
myHighlightColor = new TEL_COLOUR();
}
- myHighlightColor->rgb[0] = R;
- myHighlightColor->rgb[1] = G;
- myHighlightColor->rgb[2] = B;
+ myHighlightColor->rgb[0] = theColor.r();
+ myHighlightColor->rgb[1] = theColor.g();
+ myHighlightColor->rgb[2] = theColor.b();
myHighlightColor->rgb[3] = 1.F;
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
+// =======================================================================
+// function : clearHighlightColor
+// purpose :
+// =======================================================================
+void OpenGl_Structure::clearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
{
- ClearHighlightBox(theGlCtx);
+ clearHighlightBox(theGlCtx);
delete myHighlightColor;
myHighlightColor = NULL;
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : OnVisibilityChanged
+// purpose :
+// =======================================================================
+void OpenGl_Structure::OnVisibilityChanged()
+{
+ if (IsRaytracable())
+ {
+ ++myModificationState;
+ }
+}
-void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
+// =======================================================================
+// function : IsRaytracable
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_Structure::IsRaytracable() const
{
- Disconnect (AStructure);
- myConnected.Append(AStructure);
+ if (!myGroups.IsEmpty())
+ {
+ return myIsRaytracable; // geometry structure
+ }
+ else if (myInstancedStructure != NULL)
+ {
+ return myInstancedStructure->IsRaytracable(); // instance structure
+ }
+
+ return Standard_False; // has no any groups or structures
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : UpdateRaytracableState
+// purpose :
+// =======================================================================
+void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const
+{
+ myIsRaytracable = !toCheck || OpenGl_Raytrace::IsRaytracedStructure (this);
+
+ if (IsRaytracable())
+ {
+ ++myModificationState;
+ }
+}
-void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
+// =======================================================================
+// function : Connect
+// purpose :
+// =======================================================================
+void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
{
- OpenGl_ListOfStructure::Iterator its(myConnected);
- while (its.More())
+ OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
+
+ Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct,
+ "Error! Instanced structure is already defined");
+
+ myInstancedStructure = aStruct;
+
+ if (aStruct->IsRaytracable())
{
- // Check for the given structure
- if (its.Value() == AStructure)
+ UpdateStateIfRaytracable (Standard_False);
+ }
+}
+
+// =======================================================================
+// function : Disconnect
+// purpose :
+// =======================================================================
+void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
+{
+ OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
+
+ if (myInstancedStructure == aStruct)
+ {
+ 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 Handle(OpenGl_Context)& theGlCtx,
- const OpenGl_Group* theGroup)
+// =======================================================================
+// function : RemoveGroup
+// purpose :
+// =======================================================================
+void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
{
- for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
+ if (theGroup.IsNull())
+ {
+ return;
+ }
+
+ for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
{
// Check for the given group
- if (anIter.Value() == theGroup)
+ if (aGroupIter.Value() == theGroup)
{
- // Delete object
- OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
- myGroups.Remove (anIter);
+ const Standard_Boolean wasRaytracable =
+ static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable();
+
+ theGroup->Clear (Standard_False);
+
+ if (wasRaytracable)
+ {
+ UpdateStateIfRaytracable();
+ }
+
+ myGroups.Remove (aGroupIter);
return;
}
}
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : Clear
+// purpose :
+// =======================================================================
+void OpenGl_Structure::Clear()
+{
+ Clear (GlDriver()->GetSharedContext());
+}
+// =======================================================================
+// function : Clear
+// purpose :
+// =======================================================================
void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
{
+ Standard_Boolean aRaytracableGroupDeleted (Standard_False);
+
// Release groups
- for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
+ for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
{
+ aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable();
+
// Delete objects
- OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
+ 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) const
+{
+ // Render groups
+ const Graphic3d_SequenceOfGroup& aGroups = DrawGroups();
+ for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
+ {
+ 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;
+ }
+
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
// Render named status
- const Standard_Integer named_status = AWorkspace->NamedStatus;
- AWorkspace->NamedStatus |= myNamedStatus;
+ const Standard_Integer aNamedStatus = theWorkspace->NamedStatus;
+ if (highlight)
+ {
+ theWorkspace->NamedStatus |= OPENGL_NS_HIGHLIGHT;
+ }
- // Is rendering in ADD or IMMEDIATE mode?
- const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
+ // Do we need to restore GL_NORMALIZE?
+ const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
// Apply local transformation
- GLint matrix_mode = 0;
- const OpenGl_Matrix *local_trsf = NULL;
if (myTransformation)
{
- if (isImmediate)
+ OpenGl_Matrix aModelWorld;
+ OpenGl_Transposemat3 (&aModelWorld, myTransformation);
+ aCtx->ModelWorldState.Push();
+ aCtx->ModelWorldState.SetCurrent (OpenGl_Mat4::Map ((Standard_ShortReal* )aModelWorld.mat));
+
+ Standard_ShortReal aScaleX = OpenGl_Vec3 (myTransformation->mat[0][0],
+ myTransformation->mat[0][1],
+ myTransformation->mat[0][2]).SquareModulus();
+ // Scale transform detected.
+ if (Abs (aScaleX - 1.f) > 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);
- }
- else
- {
- glMatrixMode (GL_MODELVIEW);
- glPushMatrix();
-
- local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
+ aCtx->SetGlNormalizeEnabled (Standard_True);
}
}
-
- // Apply transform persistence
- const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
- if ( myTransPers && myTransPers->mode != 0 )
+ if (TransformPersistence.Flags)
{
- trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
+ OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
+ OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current();
+ TransformPersistence.Apply (aProjection, aWorldView, theWorkspace->Width(), theWorkspace->Height());
+
+ aCtx->ProjectionState.Push();
+ aCtx->WorldViewState.Push();
+ aCtx->ProjectionState.SetCurrent (aProjection);
+ aCtx->WorldViewState.SetCurrent (aWorldView);
+ aCtx->ApplyProjectionMatrix();
}
- // Apply degeneration
- if (myDegenerateModel)
- {
- if ( AWorkspace->NamedStatus & OPENGL_NS_DEGENERATION )
- {
- AWorkspace->DegenerateModel = myDegenerateModel->mode;
- switch ( AWorkspace->DegenerateModel )
- {
- case 0: break;
-
- default:
- glLineWidth ( 1.0 );
- glDisable ( GL_LINE_STIPPLE );
-
- case 1:
- AWorkspace->SkipRatio = myDegenerateModel->skipRatio;
- }
- }
- }
+ // Take into account transform persistence
+ aCtx->ApplyModelViewMatrix();
// 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);
+ const OpenGl_AspectLine *anAspectLine = theWorkspace->AspectLine (Standard_False);
+ const OpenGl_AspectFace *anAspectFace = theWorkspace->AspectFace (Standard_False);
+ const OpenGl_AspectMarker *anAspectMarker = theWorkspace->AspectMarker (Standard_False);
+ const OpenGl_AspectText *anAspectText = theWorkspace->AspectText (Standard_False);
if (myAspectLine)
- AWorkspace->SetAspectLine(myAspectLine);
+ {
+ theWorkspace->SetAspectLine (myAspectLine);
+ }
if (myAspectFace)
- AWorkspace->SetAspectFace(myAspectFace);
+ {
+ theWorkspace->SetAspectFace (myAspectFace);
+ }
if (myAspectMarker)
- AWorkspace->SetAspectMarker(myAspectMarker);
+ {
+ theWorkspace->SetAspectMarker (myAspectMarker);
+ }
if (myAspectText)
- AWorkspace->SetAspectText(myAspectText);
+ {
+ theWorkspace->SetAspectText (myAspectText);
+ }
- // Apply highlight box
- if (myHighlightBox)
- myHighlightBox->Render( AWorkspace );
+ // Apply correction for mirror transform
+ if (myIsMirrored)
+ {
+ aCtx->core11fwd->glFrontFace (GL_CW);
+ }
// Apply highlight color
- const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
+ const TEL_COLOUR *aHighlightColor = theWorkspace->HighlightColor;
if (myHighlightColor)
- AWorkspace->HighlightColor = myHighlightColor;
+ theWorkspace->HighlightColor = myHighlightColor;
+
+ // Render instanced structure (if exists)
+ if (myInstancedStructure != NULL)
+ {
+ myInstancedStructure->RenderGeometry (theWorkspace);
+ }
+
+ // Set up plane equations for non-structure transformed global model-view matrix
+ // List of planes to be applied to context state
+ NCollection_Handle<Graphic3d_SequenceOfHClipPlane> aUserPlanes;
+
+ // Collect clipping planes of structure scope
+ if (!myClipPlanes.IsEmpty())
+ {
+ Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes);
+ for (; aClippingIter.More(); aClippingIter.Next())
+ {
+ const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value();
+ if (!aClipPlane->IsOn())
+ {
+ continue;
+ }
+
+ if (aUserPlanes.IsNull())
+ {
+ aUserPlanes = new Graphic3d_SequenceOfHClipPlane();
+ }
+
+ aUserPlanes->Append (aClipPlane);
+ }
+ }
- // Render connected structures
- OpenGl_ListOfStructure::Iterator its(myConnected);
- while (its.More())
+ if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
{
- its.Value()->Render(AWorkspace);
- its.Next();
+ // add planes at loaded view matrix state
+ aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes);
+
+ // Set OCCT state uniform variables
+ if (!aCtx->ShaderManager()->IsEmpty())
+ {
+ aCtx->ShaderManager()->UpdateClippingState();
+ }
}
// Render groups
- OpenGl_ListOfGroup::Iterator itg(myGroups);
- while (itg.More())
+ const Graphic3d_SequenceOfGroup& aGroups = DrawGroups();
+ for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
{
- itg.Value()->Render(AWorkspace);
- itg.Next();
+ aGroupIter.Value()->Render (theWorkspace);
}
- // Restore highlight color
- AWorkspace->HighlightColor = highlight_color;
+ // Reset correction for mirror transform
+ if (myIsMirrored)
+ {
+ aCtx->core11fwd->glFrontFace (GL_CCW);
+ }
- // Restore aspects
- AWorkspace->SetAspectLine(aspect_line);
- AWorkspace->SetAspectFace(aspect_face);
- AWorkspace->SetAspectMarker(aspect_marker);
- AWorkspace->SetAspectText(aspect_text);
+ // Render capping for structure groups
+ if (!aCtx->Clipping().Planes().IsEmpty())
+ {
+ OpenGl_CappingAlgo::RenderCapping (theWorkspace, aGroups);
+ }
- // Restore transform persistence
- if ( myTransPers && myTransPers->mode != 0 )
+ // Revert structure clippings
+ if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
{
- AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
+ aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes);
+
+ // Set OCCT state uniform variables
+ if (!aCtx->ShaderManager()->IsEmpty())
+ {
+ aCtx->ShaderManager()->RevertClippingState();
+ }
}
// Restore local transformation
if (myTransformation)
{
- if (isImmediate)
- {
- glPopMatrix ();
- glMatrixMode (matrix_mode);
- }
- else
- {
- AWorkspace->SetStructureMatrix(local_trsf);
+ aCtx->ModelWorldState.Pop();
+ aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
+ }
+ if (TransformPersistence.Flags)
+ {
+ aCtx->ProjectionState.Pop();
+ aCtx->WorldViewState.Pop();
+ aCtx->ApplyProjectionMatrix();
+ }
- glMatrixMode (GL_MODELVIEW);
- glPopMatrix();
- }
+ // Restore highlight color
+ theWorkspace->HighlightColor = aHighlightColor;
+
+ // Restore aspects
+ theWorkspace->SetAspectLine (anAspectLine);
+ theWorkspace->SetAspectFace (anAspectFace);
+ theWorkspace->SetAspectMarker (anAspectMarker);
+ theWorkspace->SetAspectText (anAspectText);
+
+ // Apply highlight box
+ if (!myHighlightBox.IsNull())
+ {
+ myHighlightBox->Render (theWorkspace);
}
// Restore named status
- AWorkspace->NamedStatus = named_status;
+ theWorkspace->NamedStatus = aNamedStatus;
}
// =======================================================================
{
// Release groups
Clear (theGlCtx);
- OpenGl_Element::Destroy (theGlCtx, myAspectLine);
- OpenGl_Element::Destroy (theGlCtx, myAspectFace);
- OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
- OpenGl_Element::Destroy (theGlCtx, myAspectText);
- ClearHighlightColor (theGlCtx);
+ OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine);
+ OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace);
+ OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
+ OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);
+ clearHighlightColor (theGlCtx);
}
// =======================================================================
// =======================================================================
void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
{
- for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
+ for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
{
- OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
- if (aGroup != NULL)
- {
- aGroup->Release (theGlCtx);
- }
+ aGroupIter.ChangeValue()->Release (theGlCtx);
}
if (myAspectLine != NULL)
{
- myAspectLine->Release (theGlCtx);
+ myAspectLine->Release (theGlCtx.operator->());
}
if (myAspectFace != NULL)
{
- myAspectFace->Release (theGlCtx);
+ myAspectFace->Release (theGlCtx.operator->());
}
if (myAspectMarker != NULL)
{
- myAspectMarker->Release (theGlCtx);
+ myAspectMarker->Release (theGlCtx.operator->());
}
if (myAspectText != NULL)
{
- myAspectText->Release (theGlCtx);
+ myAspectText->Release (theGlCtx.operator->());
}
- if (myHighlightBox != NULL)
+ if (!myHighlightBox.IsNull())
{
- myHighlightBox->Release (theGlCtx);
+ myHighlightBox->Release (theGlCtx.operator->());
}
}
//=======================================================================
-//function : SetZLayer
-//purpose :
+//function : ShadowLink
+//purpose :
//=======================================================================
-
-void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
-{
- myZLayer = theLayerIndex;
-}
-
-//=======================================================================
-//function : GetZLayer
-//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);
}