#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_CUserDraw.hxx>
#include <Graphic3d_GroupDefinitionError.hxx>
-IMPLEMENT_STANDARD_HANDLE (OpenGl_Group, Graphic3d_Group)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group, Graphic3d_Group)
+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,
+ OpenGl_Element* theElement)
+ {
+ if (!theWorkspace->ShouldRender (theElement))
+ {
+ return false;
+ }
+
+ theElement->Render (theWorkspace);
+ return true;
+ }
+}
// =======================================================================
// function : OpenGl_Group
// =======================================================================
OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct)
: Graphic3d_Group (theStruct),
- myAspectLine(NULL),
- myAspectFace(NULL),
- myAspectMarker(NULL),
- myAspectText(NULL),
+ myAspects(NULL),
myFirst(NULL),
myLast(NULL),
- myIsRaytracable (Standard_False),
- myModificationState (0)
+ myIsRaytracable (Standard_False)
{
Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
- if (aStruct == NULL)
+ if (aStruct.IsNull())
{
- Graphic3d_GroupDefinitionError::Raise ("OpenGl_Group should be created by OpenGl_Structure!");
+ throw Graphic3d_GroupDefinitionError("OpenGl_Group should be created by OpenGl_Structure!");
}
}
}
// =======================================================================
-// function : UpdateAspectLine
+// function : SetGroupPrimitivesAspect
// purpose :
// =======================================================================
-void OpenGl_Group::UpdateAspectLine (const Standard_Boolean theIsGlobal)
+void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect)
{
- if (!ContextLine.IsDef)
+ if (IsDeleted())
{
return;
}
- if (theIsGlobal || myFirst == NULL)
+ if (myAspects == NULL)
{
- if (myAspectLine == NULL)
- {
- myAspectLine = new OpenGl_AspectLine();
- }
- myAspectLine->SetAspect (ContextLine);
+ myAspects = new OpenGl_Aspects (theAspect);
}
else
{
- OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
- anAspectLine->SetAspect (ContextLine);
- AddElement (anAspectLine);
+ myAspects->SetAspect (theAspect);
+ }
+
+ if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
+ {
+ aStruct->UpdateStateIfRaytracable (Standard_False);
}
+
+ Update();
}
// =======================================================================
-// function : UpdateAspectFace
+// function : SetPrimitivesAspect
// purpose :
// =======================================================================
-void OpenGl_Group::UpdateAspectFace (const Standard_Boolean theIsGlobal)
+void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect)
{
- if (!ContextFillArea.IsDef)
+ if (myAspects == NULL)
{
+ SetGroupPrimitivesAspect (theAspect);
return;
}
-
- if (theIsGlobal || myFirst == NULL)
- {
- if (myAspectFace == NULL)
- {
- myAspectFace = new OpenGl_AspectFace();
- }
- myAspectFace->SetAspect (ContextFillArea);
- }
- else
+ else if (IsDeleted())
{
- OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
- anAspectFace->SetAspect (ContextFillArea);
- AddElement (anAspectFace);
+ return;
}
- if (myIsRaytracable)
- {
- ++myModificationState;
- OpenGl_Structure* aStruct = GlStruct();
- if (aStruct != NULL)
- {
- aStruct->UpdateStateWithAncestorStructures();
- }
- }
+ OpenGl_Aspects* anAspects = new OpenGl_Aspects (theAspect);
+ AddElement (anAspects);
+ Update();
}
// =======================================================================
-// function : UpdateAspectMarker
+// function : SynchronizeAspects
// purpose :
// =======================================================================
-void OpenGl_Group::UpdateAspectMarker (const Standard_Boolean theIsGlobal)
+void OpenGl_Group::SynchronizeAspects()
{
- if (!ContextMarker.IsDef)
+ if (myAspects != NULL)
{
- return;
- }
-
- if (theIsGlobal || myFirst == NULL)
- {
- if (myAspectMarker == NULL)
+ myAspects->SynchronizeAspects();
+ if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
{
- myAspectMarker = new OpenGl_AspectMarker();
+ aStruct->UpdateStateIfRaytracable (Standard_False);
}
- myAspectMarker->SetAspect (ContextMarker);
}
- else
+ for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
{
- OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
- anAspectMarker->SetAspect (ContextMarker);
- AddElement (anAspectMarker);
+ aNode->elem->SynchronizeAspects();
}
}
// =======================================================================
-// function : UpdateAspectText
+// function : ReplaceAspects
// purpose :
// =======================================================================
-void OpenGl_Group::UpdateAspectText (const Standard_Boolean theIsGlobal)
+void OpenGl_Group::ReplaceAspects (const Graphic3d_MapOfAspectsToAspects& theMap)
{
- if (!ContextText.IsDef)
+ if (theMap.IsEmpty())
{
return;
}
- if (theIsGlobal || myFirst == NULL)
+ Handle(Graphic3d_Aspects) anAspect;
+ if (myAspects != NULL
+ && theMap.Find (myAspects->Aspect(), anAspect))
{
- if (myAspectText == NULL)
+ myAspects->SetAspect (anAspect);
+ if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
{
- myAspectText = new OpenGl_AspectText();
+ aStruct->UpdateStateIfRaytracable (Standard_False);
}
- myAspectText->SetAspect (ContextText);
}
- else
+ for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
{
- OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
- anAspectText->SetAspect (ContextText);
- AddElement (anAspectText);
+ OpenGl_Aspects* aGlAspect = dynamic_cast<OpenGl_Aspects*> (aNode->elem);
+ if (aGlAspect != NULL
+ && theMap.Find (aGlAspect->Aspect(), anAspect))
+ {
+ aGlAspect->SetAspect (anAspect);
+ }
}
}
void OpenGl_Group::Text (const Standard_CString theTextUtf,
const Graphic3d_Vertex& thePoint,
const Standard_Real theHeight,
- const Quantity_PlaneAngle theAngle,
+ const Standard_Real theAngle,
const Graphic3d_TextPath theTp,
const Graphic3d_HorizontalTextAlignment theHta,
const Graphic3d_VerticalTextAlignment theVta,
}
// =======================================================================
-// function : UserDraw
+// function : Text
// purpose :
// =======================================================================
-void OpenGl_Group::UserDraw (const Standard_Address theObject,
- const Standard_Boolean theToEvalMinMax,
- const Standard_Boolean theContainsFacet)
+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();
- if (aStruct->GlDriver()->UserDrawCallback() == NULL)
- {
- return;
- }
- Graphic3d_CUserDraw aUserDraw;
- aUserDraw.Data = theObject;
- aUserDraw.Bounds = theToEvalMinMax ? &myBounds : NULL;
- OpenGl_Element* aUserDrawElem = aStruct->GlDriver()->UserDrawCallback()(&aUserDraw);
- if (aUserDrawElem != NULL)
- {
- AddElement (aUserDrawElem);
- }
- Graphic3d_Group::UserDraw (theObject, theToEvalMinMax, theContainsFacet);
+ aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
+ aParams.HAlign = theHTA;
+ aParams.VAlign = theVTA;
+
+ 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);
+
}
// =======================================================================
if (OpenGl_Raytrace::IsRaytracedElement (aNode))
{
- myModificationState++;
myIsRaytracable = Standard_True;
OpenGl_Structure* aStruct = GlStruct();
if (aStruct != NULL)
{
- aStruct->UpdateStateWithAncestorStructures();
- aStruct->SetRaytracableWithAncestorStructures();
+ aStruct->UpdateStateIfRaytracable (Standard_False);
}
}
}
// =======================================================================
void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
{
- // Is rendering in ADD or IMMEDIATE mode?
- const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
-
// Setup aspects
- const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine (Standard_False);
- const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace (Standard_False);
- const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
- const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText (Standard_False);
- Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter);
- Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter);
- Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
- Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter);
+ theWorkspace->SetAllowFaceCulling (myIsClosed
+ && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn());
+ const OpenGl_Aspects* aBackAspects = theWorkspace->Aspects();
+ const bool isAspectSet = myAspects != NULL && renderFiltered (theWorkspace, myAspects);
// Render group elements
for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
{
- aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
+ renderFiltered (theWorkspace, aNodeIter->elem);
}
// Restore aspects
- if (isLineSet)
- theWorkspace->SetAspectLine (aBackAspectLine);
- if (isFaceSet)
- theWorkspace->SetAspectFace (aBackAspectFace);
- if (isMarkerSet)
- theWorkspace->SetAspectMarker (aBackAspectMarker);
- if (isTextSet)
- theWorkspace->SetAspectText (aBackAspectText);
+ if (isAspectSet)
+ theWorkspace->SetAspects (aBackAspects);
}
// =======================================================================
Release (aCtx);
Graphic3d_Group::Clear (theToUpdateStructureMgr);
+
+ myIsRaytracable = Standard_False;
}
// =======================================================================
while (myFirst != NULL)
{
OpenGl_ElementNode* aNext = myFirst->next;
- OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
+ OpenGl_Element::Destroy (theGlCtx.get(), myFirst->elem);
delete myFirst;
myFirst = aNext;
}
myLast = NULL;
- OpenGl_Element::Destroy (theGlCtx, myAspectLine);
- OpenGl_Element::Destroy (theGlCtx, myAspectFace);
- OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
- OpenGl_Element::Destroy (theGlCtx, myAspectText);
+ OpenGl_Element::Destroy (theGlCtx.get(), myAspects);
}