mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
502 lines
16 KiB
C++
502 lines
16 KiB
C++
// Created on: 2011-08-01
|
|
// Created by: Sergey ZERCHANINOV
|
|
// Copyright (c) 2011-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// 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.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <OpenGl_Group.hxx>
|
|
|
|
#include <OpenGl_GraphicDriver.hxx>
|
|
#include <OpenGl_Flipper.hxx>
|
|
#include <OpenGl_PrimitiveArray.hxx>
|
|
#include <OpenGl_SceneGeometry.hxx>
|
|
#include <OpenGl_StencilTest.hxx>
|
|
#include <OpenGl_Structure.hxx>
|
|
#include <OpenGl_Text.hxx>
|
|
#include <OpenGl_Workspace.hxx>
|
|
|
|
#include <Graphic3d_ArrayOfPrimitives.hxx>
|
|
#include <Graphic3d_GroupDefinitionError.hxx>
|
|
|
|
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group)
|
|
|
|
namespace
|
|
{
|
|
//! Render element if it passes the filtering procedure. This method should
|
|
//! be used for elements which can be used in scope of rendering algorithms.
|
|
//! E.g. elements of groups during recursive rendering.
|
|
//! If render filter is null, pure rendering is performed.
|
|
//! @param theWorkspace [in] the rendering workspace.
|
|
//! @param theFilter [in] the rendering filter to check whether the element
|
|
//! should be rendered or not.
|
|
//! @return True if element passes the check and renders,
|
|
static bool renderFiltered (const Handle(OpenGl_Workspace)& theWorkspace,
|
|
const Handle(OpenGl_Element)& theElement)
|
|
{
|
|
if (!theWorkspace->ShouldRender (theElement))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
theElement->Render (theWorkspace);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : OpenGl_Group
|
|
// purpose :
|
|
// =======================================================================
|
|
OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct)
|
|
: Graphic3d_Group (theStruct),
|
|
myIsRaytracable (Standard_False)
|
|
{
|
|
Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
|
|
if (aStruct.IsNull())
|
|
{
|
|
throw Graphic3d_GroupDefinitionError("OpenGl_Group should be created by OpenGl_Structure!");
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : ~OpenGl_Group
|
|
// purpose :
|
|
// =======================================================================
|
|
OpenGl_Group::~OpenGl_Group()
|
|
{
|
|
Release (Handle(OpenGl_Context)());
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetGroupPrimitivesAspect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)& theAspect)
|
|
{
|
|
if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (myAspectLine.IsNull())
|
|
{
|
|
myAspectLine = new OpenGl_AspectLine (theAspect);
|
|
}
|
|
else
|
|
{
|
|
myAspectLine->SetAspect (theAspect);
|
|
}
|
|
Update();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetPrimitivesAspect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)& theAspect)
|
|
{
|
|
if (myAspectLine.IsNull())
|
|
{
|
|
SetGroupPrimitivesAspect (theAspect);
|
|
return;
|
|
}
|
|
else if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Handle(OpenGl_AspectLine) anAspectLine = new OpenGl_AspectLine (theAspect);
|
|
AddElement (anAspectLine);
|
|
Update();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetGroupPrimitivesAspect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
|
|
{
|
|
if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (myAspectFace.IsNull())
|
|
{
|
|
myAspectFace = new OpenGl_AspectFace (theAspect);
|
|
}
|
|
else
|
|
{
|
|
myAspectFace->SetAspect (theAspect);
|
|
}
|
|
|
|
if (myIsRaytracable)
|
|
{
|
|
OpenGl_Structure* aStruct = GlStruct();
|
|
if (aStruct != NULL)
|
|
{
|
|
aStruct->UpdateStateIfRaytracable (Standard_False);
|
|
}
|
|
}
|
|
|
|
Update();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetPrimitivesAspect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
|
|
{
|
|
if (myAspectFace.IsNull())
|
|
{
|
|
SetGroupPrimitivesAspect (theAspect);
|
|
return;
|
|
}
|
|
else if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Handle(OpenGl_AspectFace) anAspectFace = new OpenGl_AspectFace (theAspect);
|
|
AddElement (anAspectFace);
|
|
Update();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetGroupPrimitivesAspect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& theAspMarker)
|
|
{
|
|
if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (myAspectMarker.IsNull())
|
|
{
|
|
myAspectMarker = new OpenGl_AspectMarker (theAspMarker);
|
|
}
|
|
else
|
|
{
|
|
myAspectMarker->SetAspect (theAspMarker);
|
|
}
|
|
Update();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetPrimitivesAspect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& theAspMarker)
|
|
{
|
|
if (myAspectMarker.IsNull())
|
|
{
|
|
SetGroupPrimitivesAspect (theAspMarker);
|
|
return;
|
|
}
|
|
else if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Handle(OpenGl_AspectMarker) anAspectMarker = new OpenGl_AspectMarker (theAspMarker);
|
|
AddElement (anAspectMarker);
|
|
Update();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetGroupPrimitivesAspect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectText3d)& theAspText)
|
|
{
|
|
if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (myAspectText.IsNull())
|
|
{
|
|
myAspectText = new OpenGl_AspectText (theAspText);
|
|
}
|
|
else
|
|
{
|
|
myAspectText->SetAspect (theAspText);
|
|
}
|
|
Update();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetPrimitivesAspect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectText3d)& theAspText)
|
|
{
|
|
if (myAspectText.IsNull())
|
|
{
|
|
SetGroupPrimitivesAspect (theAspText);
|
|
return;
|
|
}
|
|
else if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Handle(OpenGl_AspectText) anAspectText = new OpenGl_AspectText (theAspText);
|
|
AddElement (anAspectText);
|
|
Update();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SynchronizeAspects
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SynchronizeAspects()
|
|
{
|
|
if (!myAspectFace.IsNull())
|
|
{
|
|
myAspectFace->SynchronizeAspects();
|
|
}
|
|
if (!myAspectLine.IsNull())
|
|
{
|
|
myAspectLine->SynchronizeAspects();
|
|
}
|
|
if (!myAspectMarker.IsNull())
|
|
{
|
|
myAspectMarker->SynchronizeAspects();
|
|
}
|
|
if (!myAspectText.IsNull())
|
|
{
|
|
myAspectText->SynchronizeAspects();
|
|
}
|
|
for (OpenGl_ElementNodes::Iterator anElemIterator(myElements); anElemIterator.More(); anElemIterator.Next())
|
|
{
|
|
anElemIterator.ChangeValue()->SynchronizeAspects();
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : AddPrimitiveArray
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
|
|
const Handle(Graphic3d_IndexBuffer)& theIndices,
|
|
const Handle(Graphic3d_Buffer)& theAttribs,
|
|
const Handle(Graphic3d_BoundBuffer)& theBounds,
|
|
const Standard_Boolean theToEvalMinMax)
|
|
{
|
|
if (IsDeleted()
|
|
|| theAttribs.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
OpenGl_Structure* aStruct = GlStruct();
|
|
const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver();
|
|
|
|
Handle(OpenGl_PrimitiveArray) anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds);
|
|
AddElement (anArray);
|
|
|
|
Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Text
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::Text (const Standard_CString theTextUtf,
|
|
const Graphic3d_Vertex& thePoint,
|
|
const Standard_Real theHeight,
|
|
const Standard_Real theAngle,
|
|
const Graphic3d_TextPath theTp,
|
|
const Graphic3d_HorizontalTextAlignment theHta,
|
|
const Graphic3d_VerticalTextAlignment theVta,
|
|
const Standard_Boolean theToEvalMinMax)
|
|
{
|
|
if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
OpenGl_TextParam aParams;
|
|
OpenGl_Structure* aStruct = GlStruct();
|
|
aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
|
|
aParams.HAlign = theHta;
|
|
aParams.VAlign = theVta;
|
|
const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
|
|
Handle(OpenGl_Text) aText = new OpenGl_Text (theTextUtf, aPoint, aParams);
|
|
AddElement (aText);
|
|
Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle,
|
|
theTp, theHta, theVta, theToEvalMinMax);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Text
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::Text (const Standard_CString theTextUtf,
|
|
const gp_Ax2& theOrientation,
|
|
const Standard_Real theHeight,
|
|
const Standard_Real theAngle,
|
|
const Graphic3d_TextPath theTp,
|
|
const Graphic3d_HorizontalTextAlignment theHTA,
|
|
const Graphic3d_VerticalTextAlignment theVTA,
|
|
const Standard_Boolean theToEvalMinMax,
|
|
const Standard_Boolean theHasOwnAnchor)
|
|
{
|
|
if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
OpenGl_TextParam aParams;
|
|
OpenGl_Structure* aStruct = GlStruct();
|
|
|
|
aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
|
|
aParams.HAlign = theHTA;
|
|
aParams.VAlign = theVTA;
|
|
|
|
Handle(OpenGl_Text) aText = new OpenGl_Text (theTextUtf, theOrientation, aParams, theHasOwnAnchor != Standard_False);
|
|
|
|
AddElement (aText);
|
|
|
|
Graphic3d_Group::Text (theTextUtf,
|
|
theOrientation,
|
|
theHeight,
|
|
theAngle,
|
|
theTp,
|
|
theHTA,
|
|
theVTA,
|
|
theToEvalMinMax,
|
|
theHasOwnAnchor);
|
|
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetFlippingOptions
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
|
|
const gp_Ax2& theRefPlane)
|
|
{
|
|
Handle(OpenGl_Flipper) aFlipper = new OpenGl_Flipper (theRefPlane);
|
|
aFlipper->SetOptions (theIsEnabled);
|
|
AddElement (aFlipper);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetStencilTestOptions
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled)
|
|
{
|
|
Handle(OpenGl_StencilTest) aStencilTest = new OpenGl_StencilTest();
|
|
aStencilTest->SetOptions (theIsEnabled);
|
|
AddElement (aStencilTest);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : AddElement
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::AddElement (Handle(OpenGl_Element) theElem)
|
|
{
|
|
myElements.Append (theElem);
|
|
|
|
if (OpenGl_Raytrace::IsRaytracedElement (theElem))
|
|
{
|
|
myIsRaytracable = Standard_True;
|
|
|
|
OpenGl_Structure* aStruct = GlStruct();
|
|
if (aStruct != NULL)
|
|
{
|
|
aStruct->UpdateStateIfRaytracable (Standard_False);
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Render
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
|
|
{
|
|
// Setup aspects
|
|
theWorkspace->SetAllowFaceCulling (myIsClosed
|
|
&& !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn());
|
|
const Handle(OpenGl_AspectLine)& aBackAspectLine = theWorkspace->AspectLine();
|
|
const Handle(OpenGl_AspectFace)& aBackAspectFace = theWorkspace->AspectFace();
|
|
const Handle(OpenGl_AspectMarker)& aBackAspectMarker = theWorkspace->AspectMarker();
|
|
const Handle(OpenGl_AspectText)& aBackAspectText = theWorkspace->AspectText();
|
|
const bool isLineSet = !myAspectLine.IsNull() && renderFiltered (theWorkspace, myAspectLine);
|
|
const bool isFaceSet = !myAspectFace.IsNull() && renderFiltered (theWorkspace, myAspectFace);
|
|
const bool isMarkerSet = !myAspectMarker.IsNull() && renderFiltered (theWorkspace, myAspectMarker);
|
|
const bool isTextSet = !myAspectText.IsNull() && renderFiltered (theWorkspace, myAspectText);
|
|
|
|
// Render group elements
|
|
for (OpenGl_ElementNodes::Iterator anElemIterator(myElements); anElemIterator.More(); anElemIterator.Next())
|
|
{
|
|
renderFiltered (theWorkspace, anElemIterator.Value());
|
|
}
|
|
|
|
// Restore aspects
|
|
if (isLineSet)
|
|
theWorkspace->SetAspectLine (aBackAspectLine);
|
|
if (isFaceSet)
|
|
theWorkspace->SetAspectFace (aBackAspectFace);
|
|
if (isMarkerSet)
|
|
theWorkspace->SetAspectMarker (aBackAspectMarker);
|
|
if (isTextSet)
|
|
theWorkspace->SetAspectText (aBackAspectText);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Clear
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
|
|
{
|
|
if (IsDeleted())
|
|
{
|
|
return;
|
|
}
|
|
|
|
OpenGl_Structure* aStruct = GlStruct();
|
|
const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
|
|
|
|
Release (aCtx);
|
|
Graphic3d_Group::Clear (theToUpdateStructureMgr);
|
|
|
|
myIsRaytracable = Standard_False;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Release
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
|
|
{
|
|
// Delete elements
|
|
for (OpenGl_ElementNodes::Iterator anElemIterator(myElements); anElemIterator.More(); anElemIterator.Next())
|
|
{
|
|
OpenGl_Element::Destroy (theGlCtx.operator->(), anElemIterator.ChangeValue());
|
|
}
|
|
myElements.Clear();
|
|
|
|
OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine);
|
|
OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace);
|
|
OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
|
|
OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);
|
|
}
|