// File: OpenGl_Group.cxx // Created: 1 August 2011 // Author: Sergey ZERCHANINOV // Copyright: OPEN CASCADE 2011 #include #include #include /*----------------------------------------------------------------------*/ OpenGl_Group::OpenGl_Group () : myAspectLine(NULL), myAspectFace(NULL), myAspectMarker(NULL), myAspectText(NULL), myFirst(NULL), myLast(NULL) { } OpenGl_Group::~OpenGl_Group() { Clear(); } /*----------------------------------------------------------------------*/ void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theContext, const Standard_Boolean theIsGlobal) { if (theIsGlobal || myFirst == NULL) { if (myAspectLine == NULL) myAspectLine = new OpenGl_AspectLine(); myAspectLine->SetContext (theContext); } else { OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine(); anAspectLine->SetContext (theContext); AddElement (TelNil/*TelAspectLine*/, anAspectLine); } } /*----------------------------------------------------------------------*/ void OpenGl_Group::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theContext, const Standard_Boolean theIsGlobal) { if (theIsGlobal || myFirst == NULL) { if (myAspectFace == NULL) myAspectFace = new OpenGl_AspectFace(); myAspectFace->SetContext (theContext); } else { OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace(); anAspectFace->SetContext (theContext); AddElement (TelNil/*TelAspectFace*/, anAspectFace); } } /*----------------------------------------------------------------------*/ void OpenGl_Group::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theContext, const Standard_Boolean theIsGlobal) { if (theIsGlobal || myFirst == NULL) { if (myAspectMarker == NULL) myAspectMarker = new OpenGl_AspectMarker(); myAspectMarker->SetContext (theContext); } else { OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker(); anAspectMarker->SetContext (theContext); AddElement (TelNil/*TelAspectMarker*/, anAspectMarker); } } /*----------------------------------------------------------------------*/ void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theContext, const Standard_Boolean theIsGlobal) { if (theIsGlobal || myFirst == NULL) { if (myAspectText == NULL) myAspectText = new OpenGl_AspectText(); myAspectText->SetContext (theContext); } else { OpenGl_AspectText* anAspectText = new OpenGl_AspectText(); anAspectText->SetContext (theContext); AddElement ( TelNil/*TelAspectText*/, anAspectText); } } /*----------------------------------------------------------------------*/ void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem ) { OpenGl_ElementNode *node = new OpenGl_ElementNode(); node->type = AType; node->elem = AElem; node->next = NULL; (myLast? myLast->next : myFirst) = node; myLast = node; } /*----------------------------------------------------------------------*/ void OpenGl_Group::Clear () { if (myAspectLine) { // Delete line context delete myAspectLine; myAspectLine = NULL; } if (myAspectFace) { // Delete face context delete myAspectFace; myAspectFace = NULL; } if (myAspectMarker) { // Delete marker context delete myAspectMarker; myAspectMarker = NULL; } if (myAspectText) { // Delete text context delete myAspectText; myAspectText = NULL; } // Delete elements while (myFirst) { OpenGl_ElementNode *next = myFirst->next; delete myFirst->elem; delete myFirst; myFirst = next; } myLast = NULL; } /*----------------------------------------------------------------------*/ void OpenGl_Group::RemovePrimitiveArray (CALL_DEF_PARRAY *APArray) { OpenGl_ElementNode *prevnode = NULL, *node = myFirst; while (node) { if (node->type == TelParray) { CALL_DEF_PARRAY *aCurPArray = ((const OpenGl_PrimitiveArray *)node->elem)->PArray(); // validate for correct pointer if (aCurPArray->num_bounds == APArray->num_bounds && aCurPArray->num_edges == APArray->num_edges && aCurPArray->num_vertexs == APArray->num_vertexs && aCurPArray->type == APArray->type) { (prevnode? prevnode->next : myFirst) = node->next; if (!myFirst) myLast = NULL; delete node->elem; delete node; break; } } prevnode = node; node = node->next; } } /*----------------------------------------------------------------------*/ void OpenGl_Group::Render (const Handle(OpenGl_Workspace) &AWorkspace) const { // Is rendering in ADD or IMMEDIATE mode? const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0; // Setup 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); // Render group elements OpenGl_ElementNode *node = myFirst; while (node) { switch (node->type) { case TelPolyline: case TelMarker: case TelMarkerSet: case TelText: { glDisable(GL_LIGHTING); if (isImmediate) { glDepthMask(GL_FALSE); } else if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 && (AWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 && AWorkspace->DegenerateModel != 0 ) { glDisable( GL_DEPTH_TEST ); if ( AWorkspace->NamedStatus & OPENGL_NS_TEXTURE ) DisableTexture(); AWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME; } node->elem->Render( AWorkspace ); if ( !isImmediate && (AWorkspace->NamedStatus & OPENGL_NS_TEXTURE) != 0 ) EnableTexture(); break; } case TelPolygon: case TelPolygonIndices: case TelQuadrangle: case TelTriangleMesh: { if (isImmediate) { glDepthMask(GL_FALSE); } else if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 && (AWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 && AWorkspace->DegenerateModel < 2 ) { if ( AWorkspace->NamedStatus & OPENGL_NS_TEXTURE ) EnableTexture (); glEnable( GL_DEPTH_TEST ); AWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME; } if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT ) AWorkspace->DisablePolygonOffset(); node->elem->Render( AWorkspace ); if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT ) AWorkspace->EnablePolygonOffset(); break; } default: { node->elem->Render( AWorkspace ); break; } } node = node->next; } // Restore aspects AWorkspace->SetAspectLine(aspect_line); AWorkspace->SetAspectFace(aspect_face); AWorkspace->SetAspectMarker(aspect_marker); AWorkspace->SetAspectText(aspect_text); } /*----------------------------------------------------------------------*/