diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index 5bc030e7bd..13c448d4c2 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -37,6 +37,7 @@ Graphic3d_Buffer.hxx Graphic3d_BufferType.hxx Graphic3d_Camera.cxx Graphic3d_Camera.hxx +Graphic3d_CappingFlags.hxx Graphic3d_CLight.hxx Graphic3d_ClipPlane.cxx Graphic3d_ClipPlane.hxx diff --git a/src/Graphic3d/Graphic3d_CappingFlags.hxx b/src/Graphic3d/Graphic3d_CappingFlags.hxx new file mode 100644 index 0000000000..f247b49846 --- /dev/null +++ b/src/Graphic3d/Graphic3d_CappingFlags.hxx @@ -0,0 +1,29 @@ +// Created on: 2016-08-04 +// Copyright (c) 2016 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. + +#ifndef _Graphic3d_CappingFlags_HeaderFile +#define _Graphic3d_CappingFlags_HeaderFile + +//! Enumeration of capping flags. +enum Graphic3d_CappingFlags +{ + Graphic3d_CappingFlags_None = 0x0000, //!< no flags + Graphic3d_CappingFlags_ObjectMaterial = 0x0001, //!< use object material + Graphic3d_CappingFlags_ObjectTexture = 0x0002, //!< use object texture + Graphic3d_CappingFlags_ObjectShader = 0x0008, //!< use object GLSL program + Graphic3d_CappingFlags_ObjectAspect = + Graphic3d_CappingFlags_ObjectMaterial | Graphic3d_CappingFlags_ObjectTexture | Graphic3d_CappingFlags_ObjectShader //!< use entire fill area aspect from object +}; + +#endif // _Graphic3d_CappingFlags_HeaderFile diff --git a/src/Graphic3d/Graphic3d_ClipPlane.cxx b/src/Graphic3d/Graphic3d_ClipPlane.cxx index ffd4ed5d14..72f7788769 100755 --- a/src/Graphic3d/Graphic3d_ClipPlane.cxx +++ b/src/Graphic3d/Graphic3d_ClipPlane.cxx @@ -14,16 +14,29 @@ // commercial license or contractual agreement. #include + #include #include #include - IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ClipPlane,Standard_Transient) namespace { static volatile Standard_Integer THE_CLIP_PLANE_COUNTER = 0; + + static Handle(Graphic3d_AspectFillArea3d) defaultAspect() + { + const Graphic3d_MaterialAspect aMaterial (Graphic3d_NOM_DEFAULT); + Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); + anAspect->SetDistinguishOff(); + anAspect->SetFrontMaterial (aMaterial); + anAspect->SetHatchStyle (Aspect_HS_HORIZONTAL); + anAspect->SetInteriorStyle (Aspect_IS_SOLID); + anAspect->SetInteriorColor (aMaterial.Color()); + anAspect->SetSuppressBackFaces (false); + return anAspect; + } } // ======================================================================= @@ -31,17 +44,15 @@ namespace // purpose : // ======================================================================= Graphic3d_ClipPlane::Graphic3d_ClipPlane() -: myEquation (0.0, 0.0, 1.0, 0.0), +: myAspect (defaultAspect()), + myEquation (0.0, 0.0, 1.0, 0.0), + myFlags (Graphic3d_CappingFlags_None), myIsOn (Standard_True), myIsCapping (Standard_False), - myMaterial (Graphic3d_NOM_DEFAULT), - myHatch (Aspect_HS_HORIZONTAL), - myHatchOn (Standard_False), - myId(), myEquationMod(0), myAspectMod(0) { - MakeId(); + makeId(); } // ======================================================================= @@ -49,17 +60,15 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane() // purpose : // ======================================================================= Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation) -: myEquation (theEquation), +: myAspect (defaultAspect()), + myEquation (theEquation), + myFlags (Graphic3d_CappingFlags_None), myIsOn (Standard_True), myIsCapping (Standard_False), - myMaterial (Graphic3d_NOM_DEFAULT), - myHatch (Aspect_HS_HORIZONTAL), - myHatchOn (Standard_False), - myId(), myEquationMod(0), myAspectMod(0) { - MakeId(); + makeId(); } // ======================================================================= @@ -68,18 +77,16 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation) // ======================================================================= Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther) : Standard_Transient(theOther), + myAspect (defaultAspect()), myEquation (theOther.myEquation), + myFlags (theOther.myFlags), myIsOn (theOther.myIsOn), myIsCapping (theOther.myIsCapping), - myMaterial (theOther.myMaterial), - myTexture (theOther.myTexture), - myHatch (theOther.myHatch), - myHatchOn (theOther.myHatchOn), - myId(), myEquationMod (0), myAspectMod (0) { - MakeId(); + makeId(); + *myAspect = *theOther.CappingAspect(); } // ======================================================================= @@ -87,17 +94,15 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther) // purpose : // ======================================================================= Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane) -: myEquation (), +: myAspect (defaultAspect()), + myEquation (), + myFlags (Graphic3d_CappingFlags_None), myIsOn (Standard_True), myIsCapping (Standard_False), - myMaterial (Graphic3d_NOM_DEFAULT), - myHatch (Aspect_HS_HORIZONTAL), - myHatchOn (Standard_False), - myId(), myEquationMod(0), myAspectMod(0) { - MakeId(); + makeId(); SetEquation (thePlane); } @@ -169,8 +174,9 @@ Handle(Graphic3d_ClipPlane) Graphic3d_ClipPlane::Clone() const // ======================================================================= void Graphic3d_ClipPlane::SetCappingMaterial (const Graphic3d_MaterialAspect& theMat) { - myMaterial = theMat; - myAspectMod++; + myAspect->SetFrontMaterial (theMat); + myAspect->SetInteriorColor (theMat.Color()); + ++myAspectMod; } // ======================================================================= @@ -179,8 +185,16 @@ void Graphic3d_ClipPlane::SetCappingMaterial (const Graphic3d_MaterialAspect& th // ======================================================================= void Graphic3d_ClipPlane::SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture) { - myTexture = theTexture; - myAspectMod++; + myAspect->SetTextureMap (theTexture); + if (!theTexture.IsNull()) + { + myAspect->SetTextureMapOn(); + } + else + { + myAspect->SetTextureMapOff(); + } + ++myAspectMod; } // ======================================================================= @@ -189,8 +203,8 @@ void Graphic3d_ClipPlane::SetCappingTexture (const Handle(Graphic3d_TextureMap)& // ======================================================================= void Graphic3d_ClipPlane::SetCappingHatch (const Aspect_HatchStyle theStyle) { - myHatch = theStyle; - myAspectMod++; + myAspect->SetHatchStyle (theStyle); + ++myAspectMod; } // ======================================================================= @@ -199,8 +213,8 @@ void Graphic3d_ClipPlane::SetCappingHatch (const Aspect_HatchStyle theStyle) // ======================================================================= void Graphic3d_ClipPlane::SetCappingHatchOn() { - myHatchOn = Standard_True; - myAspectMod++; + myAspect->SetInteriorStyle (Aspect_IS_HATCH); + ++myAspectMod; } // ======================================================================= @@ -209,41 +223,43 @@ void Graphic3d_ClipPlane::SetCappingHatchOn() // ======================================================================= void Graphic3d_ClipPlane::SetCappingHatchOff() { - myHatchOn = Standard_False; - myAspectMod++; + myAspect->SetInteriorStyle (Aspect_IS_SOLID); + ++myAspectMod; } // ======================================================================= -// function : MakeId +// function : SetCappingAspect // purpose : // ======================================================================= -void Graphic3d_ClipPlane::MakeId() +void Graphic3d_ClipPlane::SetCappingAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect) +{ + myAspect = theAspect; + ++myAspectMod; +} + +// ======================================================================= +// function : setCappingFlag +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::setCappingFlag (bool theToUse, int theFlag) +{ + if (theToUse) + { + myFlags |= theFlag; + } + else + { + myFlags &= ~(theFlag); + } + ++myAspectMod; +} + +// ======================================================================= +// function : makeId +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::makeId() { myId = TCollection_AsciiString ("Graphic3d_ClipPlane_") //DynamicType()->Name() + TCollection_AsciiString (Standard_Atomic_Increment (&THE_CLIP_PLANE_COUNTER)); } - -// ======================================================================= -// function : CappingAspect -// purpose : -// ======================================================================= -Handle(Graphic3d_AspectFillArea3d) Graphic3d_ClipPlane::CappingAspect() const -{ - Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); - anAspect->SetDistinguishOff(); - anAspect->SetFrontMaterial (myMaterial); - anAspect->SetTextureMap (myTexture); - anAspect->SetHatchStyle (myHatch); - anAspect->SetInteriorStyle (myHatchOn ? Aspect_IS_HATCH : Aspect_IS_SOLID); - anAspect->SetInteriorColor (myMaterial.Color()); - anAspect->SetSuppressBackFaces (false); - if (!myTexture.IsNull()) - { - anAspect->SetTextureMapOn(); - } - else - { - anAspect->SetTextureMapOff(); - } - return anAspect; -} diff --git a/src/Graphic3d/Graphic3d_ClipPlane.hxx b/src/Graphic3d/Graphic3d_ClipPlane.hxx index c402ff8a0f..d4141a0fba 100755 --- a/src/Graphic3d/Graphic3d_ClipPlane.hxx +++ b/src/Graphic3d/Graphic3d_ClipPlane.hxx @@ -20,12 +20,12 @@ #include #include #include -#include +#include +#include #include #include class gp_Pln; -class Graphic3d_AspectFillArea3d; //! Container for properties describing graphic driver clipping planes. //! It is up to application to create instances of this class and specify its @@ -132,30 +132,21 @@ public: // @name user-defined graphical attributes Standard_EXPORT void SetCappingMaterial (const Graphic3d_MaterialAspect& theMat); //! @return capping material. - const Graphic3d_MaterialAspect& CappingMaterial() const - { - return myMaterial; - } + const Graphic3d_MaterialAspect& CappingMaterial() const { return myAspect->FrontMaterial(); } //! Set texture to be applied on capping surface. //! @param theTexture [in] the texture. Standard_EXPORT void SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture); //! @return capping texture map. - const Handle(Graphic3d_TextureMap)& CappingTexture() const - { - return myTexture; - } + const Handle(Graphic3d_TextureMap)& CappingTexture() const { return myAspect->TextureMap(); } //! Set hatch style (stipple) and turn hatching on. //! @param theStyle [in] the hatch style. Standard_EXPORT void SetCappingHatch (const Aspect_HatchStyle theStyle); //! @return hatching style. - Aspect_HatchStyle CappingHatch() const - { - return myHatch; - } + Aspect_HatchStyle CappingHatch() const { return myAspect->HatchStyle(); } //! Turn on hatching. Standard_EXPORT void SetCappingHatchOn(); @@ -164,10 +155,7 @@ public: // @name user-defined graphical attributes Standard_EXPORT void SetCappingHatchOff(); //! @return True if hatching mask is turned on. - Standard_Boolean IsHatchOn() const - { - return myHatchOn; - } + Standard_Boolean IsHatchOn() const { return myAspect->InteriorStyle() == Aspect_IS_HATCH; } //! This ID is used for managing associated resources in graphical driver. //! The clip plane can be assigned within a range of IO which can be @@ -181,9 +169,38 @@ public: // @name user-defined graphical attributes return myId; } - //! Compute and return capping aspect from the graphical attributes. +public: + + //! Return capping aspect. //! @return capping surface rendering aspect. - Standard_EXPORT Handle(Graphic3d_AspectFillArea3d) CappingAspect() const; + const Handle(Graphic3d_AspectFillArea3d)& CappingAspect() const { return myAspect; } + + //! Assign capping aspect. + Standard_EXPORT void SetCappingAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect); + + //! Flag indicating whether material for capping plane should be taken from object. + //! Default value: FALSE (use dedicated capping plane material). + bool ToUseObjectMaterial() const { return (myFlags & Graphic3d_CappingFlags_ObjectMaterial) != 0; } + + //! Set flag for controlling the source of capping plane material. + void SetUseObjectMaterial (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectMaterial); } + + //! Flag indicating whether texture for capping plane should be taken from object. + //! Default value: FALSE. + bool ToUseObjectTexture() const { return (myFlags & Graphic3d_CappingFlags_ObjectTexture) != 0; } + + //! Set flag for controlling the source of capping plane texture. + void SetUseObjectTexture (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectTexture); } + + //! Flag indicating whether shader program for capping plane should be taken from object. + //! Default value: FALSE. + bool ToUseObjectShader() const { return (myFlags & Graphic3d_CappingFlags_ObjectShader) != 0; } + + //! Set flag for controlling the source of capping plane shader program. + void SetUseObjectShader(bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectShader); } + + //! Return true if some fill area aspect properties should be taken from object. + bool ToUseObjectProperties() const { return myFlags != Graphic3d_CappingFlags_None; } public: // @name modification counters @@ -201,20 +218,22 @@ public: // @name modification counters private: - void MakeId(); + //! Generate unique object id for OpenGL graphic resource manager. + void makeId(); + + //! Set capping flag. + Standard_EXPORT void setCappingFlag (bool theToUse, int theFlag); private: - Equation myEquation; //!< Plane equation vector. - Standard_Boolean myIsOn; //!< State of the clipping plane. - Standard_Boolean myIsCapping; //!< State of graphic driver capping. - Graphic3d_MaterialAspect myMaterial; //!< Capping surface material. - Handle(Graphic3d_TextureMap) myTexture; //!< Capping surface texture. - Aspect_HatchStyle myHatch; //!< Capping surface hatch mask. - Standard_Boolean myHatchOn; //!< Capping surface hatching flag. - TCollection_AsciiString myId; //!< Resource id. - unsigned int myEquationMod; //!< Modification counter for equation. - unsigned int myAspectMod; //!< Modification counter of aspect. + Handle(Graphic3d_AspectFillArea3d) myAspect; //!< fill area aspect + TCollection_AsciiString myId; //!< resource id + Equation myEquation; //!< plane equation vector + unsigned int myFlags; //!< capping flags + Standard_Boolean myIsOn; //!< state of the clipping plane + Standard_Boolean myIsCapping; //!< state of graphic driver capping + unsigned int myEquationMod; //!< modification counter for equation + unsigned int myAspectMod; //!< modification counter of aspect public: diff --git a/src/MeshVS/MeshVS_ElementalColorPrsBuilder.cxx b/src/MeshVS/MeshVS_ElementalColorPrsBuilder.cxx index ec08c90d56..75880888e4 100644 --- a/src/MeshVS/MeshVS_ElementalColorPrsBuilder.cxx +++ b/src/MeshVS/MeshVS_ElementalColorPrsBuilder.cxx @@ -249,19 +249,38 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& } // Draw elements with one color - for ( MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger aColIter ( aColorsOfElements ); aColIter.More(); - aColIter.Next() ) + Handle(Graphic3d_Group) aGGroup, aGroup2, aLGroup, aSGroup; + if (!aTwoColorsOfElements.IsEmpty()) { - Standard_Integer aSize = aColIter.Value().Extent(); - if ( aSize<=0 ) + aGroup2 = Prs3d_Root::NewGroup (Prs); + } + if (!aColorsOfElements.IsEmpty()) + { + Handle(Graphic3d_AspectFillArea3d) aGroupFillAspect = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, anInteriorColor, anEdgeColor, + anEdgeType, anEdgeWidth, aMaterial[0], aMaterial[1]); + aGGroup = Prs3d_Root::NewGroup (Prs); + aLGroup = Prs3d_Root::NewGroup (Prs); + aGGroup->SetClosed (toSupressBackFaces == Standard_True); + aGGroup->SetGroupPrimitivesAspect (aGroupFillAspect); + } + + if (anEdgeOn) + { + Handle(Graphic3d_AspectLine3d) anEdgeAspect = new Graphic3d_AspectLine3d (anEdgeColor, anEdgeType, anEdgeWidth); + aSGroup = Prs3d_Root::NewGroup (Prs); + aSGroup->SetGroupPrimitivesAspect (anEdgeAspect); + } + + for (MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger aColIter (aColorsOfElements); + aColIter.More(); aColIter.Next()) + { + if (aColIter.Value().IsEmpty()) + { continue; + } TColStd_PackedMapOfInteger aCustomElements; - Handle(Graphic3d_Group) aGGroup = Prs3d_Root::NewGroup (Prs); - Handle(Graphic3d_Group) aLGroup = Prs3d_Root::NewGroup (Prs); - Handle(Graphic3d_Group) aSGroup = Prs3d_Root::NewGroup (Prs); - Standard_Integer aNbFacePrimitives = 0; Standard_Integer aNbVolmPrimitives = 0; Standard_Integer aNbEdgePrimitives = 0; @@ -334,9 +353,6 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& Handle(Graphic3d_AspectLine3d) aLinkAspect = new Graphic3d_AspectLine3d ( aColIter.Key(), aLineType, aLineWidth ); - Handle(Graphic3d_AspectLine3d) anEdgeAspect = - new Graphic3d_AspectLine3d ( anEdgeColor, anEdgeType, anEdgeWidth ); - aFillAspect->SetDistinguishOff (); aFillAspect->SetInteriorColor ( aColIter.Key() ); aFillAspect->SetEdgeOff(); @@ -452,7 +468,6 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& if (anEdgeOn) { aSGroup->AddPrimitiveArray (anEdgeSegments); - aSGroup->SetGroupPrimitivesAspect (anEdgeAspect); } } if (IsPolyL) @@ -505,15 +520,20 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& } // Draw faces with two color + if (!aTwoColorsOfElements.IsEmpty()) + { + Handle(Graphic3d_AspectFillArea3d) aGroupFillAspect2 = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, anInteriorColor, anEdgeColor, + anEdgeType, anEdgeWidth, aMaterial2[0], aMaterial2[1]); + aGroup2->SetClosed (Standard_False); // ignore toSupressBackFaces + aGroup2->SetGroupPrimitivesAspect (aGroupFillAspect2); + } for ( MeshVS_DataMapIteratorOfDataMapOfTwoColorsMapOfInteger aColIter2 ( aTwoColorsOfElements ); aColIter2.More(); aColIter2.Next() ) { - Handle(Graphic3d_Group) aGroup2 = Prs3d_Root::NewGroup (Prs); - Handle(Graphic3d_Group) aGroup3 = Prs3d_Root::NewGroup (Prs); - - Standard_Integer aSize = aColIter2.Value().Extent(); - if ( aSize<=0 ) + if (aColIter2.Value().IsEmpty()) + { continue; + } Standard_Integer aNbFacePrimitives = 0; Standard_Integer aNbEdgePrimitives = 0; @@ -561,9 +581,7 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& anAsp->SetEdgeOn(); else anAsp->SetEdgeOff();*/ - - Handle(Graphic3d_AspectLine3d) anEdgeAspect = - new Graphic3d_AspectLine3d (anEdgeColor, anEdgeType, anEdgeWidth); + aGroup2->SetPrimitivesAspect (anAsp); for( it.Reset(); it.More(); it.Next() ) { @@ -626,11 +644,8 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)& } } - aGroup2->SetClosed (toSupressBackFaces == Standard_True); aGroup2->AddPrimitiveArray (aFaceTriangles); - aGroup2->SetGroupPrimitivesAspect (anAsp); - aGroup3->AddPrimitiveArray (anEdgeSegments); - aGroup3->SetGroupPrimitivesAspect (anEdgeAspect); + aSGroup->AddPrimitiveArray (anEdgeSegments); } } diff --git a/src/OpenGl/OpenGl_CappingAlgo.cxx b/src/OpenGl/OpenGl_CappingAlgo.cxx index e2ce3c0ac6..36862c1359 100755 --- a/src/OpenGl/OpenGl_CappingAlgo.cxx +++ b/src/OpenGl/OpenGl_CappingAlgo.cxx @@ -34,6 +34,117 @@ namespace static const GLint THE_FILLPRIM_FROM = GL_TRIANGLES; static const GLint THE_FILLPRIM_TO = GL_TRIANGLE_FAN; #endif + + //! Render infinite capping plane. + //! @param theWorkspace [in] the GL workspace, context state. + //! @param thePlane [in] the graphical plane, for which the capping surface is rendered. + static void renderPlane (const Handle(OpenGl_Workspace)& theWorkspace, + const Handle(OpenGl_CappingPlaneResource)& thePlane, + const OpenGl_AspectFace* theAspectFace) + { + const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); + thePlane->Update (aContext, theAspectFace != NULL ? theAspectFace->Aspect() : Handle(Graphic3d_AspectFillArea3d)()); + + const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace(); + theWorkspace->SetAspectFace (thePlane->AspectFace()); + + // set identity model matrix + aContext->ModelWorldState.Push(); + aContext->ModelWorldState.SetCurrent (OpenGl_Mat4::Map (*thePlane->Orientation()->mat)); + aContext->ApplyModelViewMatrix(); + + thePlane->Primitives().Render (theWorkspace); + + aContext->ModelWorldState.Pop(); + aContext->ApplyModelViewMatrix(); + + theWorkspace->SetAspectFace (aFaceAspect); + } + + //! Render capping for specific structure. + static void renderCappingForStructure (const Handle(OpenGl_Workspace)& theWorkspace, + const OpenGl_Structure& theStructure, + const Handle(OpenGl_CappingPlaneResource)& thePlane) + { + const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); + const Graphic3d_SequenceOfHClipPlane& aContextPlanes = aContext->Clipping().Planes(); + const Handle(Graphic3d_ClipPlane)& aRenderPlane = thePlane->Plane(); + for (OpenGl_Structure::GroupIterator aGroupIter (theStructure.Groups()); aGroupIter.More(); aGroupIter.Next()) + { + if (!aGroupIter.Value()->IsClosed()) + { + continue; + } + + // enable only the rendering plane to generate stencil mask + for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next()) + { + const Standard_Boolean isOn = (aPlaneIt.Value() == aRenderPlane); + aContext->ChangeClipping().SetEnabled (aContext, aPlaneIt.Value(), isOn); + } + aContext->ShaderManager()->UpdateClippingState(); + + glClear (GL_STENCIL_BUFFER_BIT); + glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + // override aspects, disable culling + theWorkspace->SetAspectFace (&theWorkspace->NoneCulling()); + theWorkspace->ApplyAspectFace(); + + // evaluate number of pair faces + glDisable (GL_DEPTH_TEST); + glDepthMask (GL_FALSE); + glStencilFunc (GL_ALWAYS, 1, 0x01); + glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT); + + // render closed primitives + if (aRenderPlane->ToUseObjectProperties()) + { + aGroupIter.Value()->Render (theWorkspace); + } + else + { + for (; aGroupIter.More(); aGroupIter.Next()) + { + if (aGroupIter.Value()->IsClosed()) + { + aGroupIter.Value()->Render (theWorkspace); + } + } + } + + // override material, cull back faces + theWorkspace->SetAspectFace (&theWorkspace->FrontCulling()); + theWorkspace->ApplyAspectFace(); + + // enable all clip plane except the rendered one + for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next()) + { + const Standard_Boolean isOn = (aPlaneIt.Value() != aRenderPlane); + aContext->ChangeClipping().SetEnabled (aContext, aPlaneIt.Value(), isOn); + } + aContext->ShaderManager()->UpdateClippingState(); + + // render capping plane using the generated stencil mask + glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthMask (GL_TRUE); + glStencilFunc (GL_EQUAL, 1, 0x01); + glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); + glEnable (GL_DEPTH_TEST); + + renderPlane (theWorkspace, thePlane, aRenderPlane->ToUseObjectProperties() + ? aGroupIter.Value()->AspectFace() + : NULL); + + aContext->ShaderManager()->RevertClippingState(); + aContext->ShaderManager()->RevertClippingState(); + } + + if (theStructure.InstancedStructure() != NULL) + { + renderCappingForStructure (theWorkspace, *theStructure.InstancedStructure(), thePlane); + } + } } // ======================================================================= @@ -48,8 +159,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks // check whether algorithm need to be performed Standard_Boolean isCapping = Standard_False; const Graphic3d_SequenceOfHClipPlane& aContextPlanes = aContext->Clipping().Planes(); - Graphic3d_SequenceOfHClipPlane::Iterator aCappingIt (aContextPlanes); - for (; aCappingIt.More(); aCappingIt.Next()) + for (Graphic3d_SequenceOfHClipPlane::Iterator aCappingIt (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) { const Handle(Graphic3d_ClipPlane)& aPlane = aCappingIt.Value(); if (aPlane->IsCapping()) @@ -82,7 +192,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks glDepthFunc (GL_LESS); // generate capping for every clip plane - for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) + for (Graphic3d_SequenceOfHClipPlane::Iterator aCappingIt (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) { // get plane being rendered const Handle(Graphic3d_ClipPlane)& aRenderPlane = aCappingIt.Value(); @@ -91,56 +201,21 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks continue; } - // enable only the rendering plane to generate stencil mask - Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aContextPlanes); - for (; aPlaneIt.More(); aPlaneIt.Next()) + // get resource for the plane + const TCollection_AsciiString& aResId = aRenderPlane->GetId(); + Handle(OpenGl_CappingPlaneResource) aPlaneRes; + if (!aContext->GetResource (aResId, aPlaneRes)) { - const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); - const Standard_Boolean isOn = (aPlane == aRenderPlane); - aContext->ChangeClipping().SetEnabled (aContext, aPlane, isOn); + // share and register for release once the resource is no longer used + aPlaneRes = new OpenGl_CappingPlaneResource (aRenderPlane); + aContext->ShareResource (aResId, aPlaneRes); } - aContext->ShaderManager()->UpdateClippingState(); - glClear (GL_STENCIL_BUFFER_BIT); - glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + renderCappingForStructure (theWorkspace, theStructure, aPlaneRes); - // override aspects, disable culling - theWorkspace->SetAspectFace (&theWorkspace->NoneCulling()); - theWorkspace->ApplyAspectFace(); - - // evaluate number of pair faces - glDisable (GL_DEPTH_TEST); - glDepthMask (GL_FALSE); - glStencilFunc (GL_ALWAYS, 1, 0x01); - glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT); - - // render closed primitives - theStructure.renderClosedGeometry (theWorkspace); - - // override material, cull back faces - theWorkspace->SetAspectFace (&theWorkspace->FrontCulling()); - theWorkspace->ApplyAspectFace(); - - // enable all clip plane except the rendered one - for (aPlaneIt.Init (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next()) - { - const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); - const Standard_Boolean isOn = (aPlane != aRenderPlane); - aContext->ChangeClipping().SetEnabled (aContext, aPlane, isOn); - } - aContext->ShaderManager()->UpdateClippingState(); - - // render capping plane using the generated stencil mask - glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glDepthMask (GL_TRUE); - glStencilFunc (GL_EQUAL, 1, 0x01); - glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); - glEnable (GL_DEPTH_TEST); - - RenderPlane (theWorkspace, aRenderPlane); - - aContext->ShaderManager()->RevertClippingState(); - aContext->ShaderManager()->RevertClippingState(); + // set delayed resource release + aPlaneRes.Nullify(); + aContext->ReleaseResource (aResId, Standard_True); } // restore previous application state @@ -150,7 +225,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks glDisable (GL_STENCIL_TEST); // enable clipping - for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) + for (Graphic3d_SequenceOfHClipPlane::Iterator aCappingIt (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) { aContext->ChangeClipping().SetEnabled (aContext, aCappingIt.Value(), Standard_True); } @@ -160,52 +235,6 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks theWorkspace->SetRenderFilter (aRenderFilter); } -// ======================================================================= -// function : RenderPlane -// purpose : -// ======================================================================= -void OpenGl_CappingAlgo::RenderPlane (const Handle(OpenGl_Workspace)& theWorkspace, - const Handle(Graphic3d_ClipPlane)& thePlane) -{ - const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); - - // get resource for the plane - TCollection_AsciiString aResId = thePlane->GetId(); - - Handle(OpenGl_CappingPlaneResource) aPlaneRes; - if (!aContext->GetResource (aResId, aPlaneRes)) - { - // share and register for release once the resource is no longer used - aPlaneRes = new OpenGl_CappingPlaneResource (thePlane); - aContext->ShareResource (aResId, aPlaneRes); - } - - aPlaneRes->Update (aContext); - - const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace(); - const OpenGl_AspectFace* aPlaneAspect = aPlaneRes->AspectFace(); - if (aPlaneAspect != NULL) - { - theWorkspace->SetAspectFace (aPlaneAspect); - } - - // set identity model matrix - aContext->ModelWorldState.Push(); - aContext->ModelWorldState.SetCurrent (OpenGl_Mat4::Map (*aPlaneRes->Orientation()->mat)); - aContext->ApplyModelViewMatrix(); - - aPlaneRes->Primitives().Render (theWorkspace); - - aContext->ModelWorldState.Pop(); - aContext->ApplyModelViewMatrix(); - - theWorkspace->SetAspectFace (aFaceAspect); - - // set delayed resource release - aPlaneRes.Nullify(); - aContext->ReleaseResource (aResId, Standard_True); -} - // ======================================================================= // function : CanRender // purpose : diff --git a/src/OpenGl/OpenGl_CappingAlgo.hxx b/src/OpenGl/OpenGl_CappingAlgo.hxx index a2497b17ad..7fc7881448 100755 --- a/src/OpenGl/OpenGl_CappingAlgo.hxx +++ b/src/OpenGl/OpenGl_CappingAlgo.hxx @@ -21,7 +21,9 @@ // Forward declaration class OpenGl_CappingAlgoFilter; +class OpenGl_CappingPlaneResource; class OpenGl_Structure; + DEFINE_STANDARD_HANDLE (OpenGl_CappingAlgoFilter, OpenGl_RenderFilter) //! Capping surface rendering algorithm. @@ -36,11 +38,6 @@ public: Standard_EXPORT static void RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace, const OpenGl_Structure& theStructure); - //! Render infinite capping plane. - //! @param theWorkspace [in] the GL workspace, context state. - //! @param thePlane [in] the graphical plane, for which the capping surface is rendered. - Standard_EXPORT static void RenderPlane (const Handle(OpenGl_Workspace)& theWorkspace, - const Handle(Graphic3d_ClipPlane)& thePlane); }; //! Graphical capping rendering algorithm filter. diff --git a/src/OpenGl/OpenGl_CappingPlaneResource.cxx b/src/OpenGl/OpenGl_CappingPlaneResource.cxx index 8cb48cfcbf..dd032d9d9b 100755 --- a/src/OpenGl/OpenGl_CappingPlaneResource.cxx +++ b/src/OpenGl/OpenGl_CappingPlaneResource.cxx @@ -99,10 +99,11 @@ OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource() // function : Update // purpose : // ======================================================================= -void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theContext) +void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& , + const Handle(Graphic3d_AspectFillArea3d)& theObjAspect) { - UpdateTransform(); - UpdateAspect (theContext); + updateTransform(); + updateAspect (theObjAspect); } // ======================================================================= @@ -118,44 +119,67 @@ void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext) } // ======================================================================= -// function : UpdateAspect +// function : updateAspect // purpose : // ======================================================================= -void OpenGl_CappingPlaneResource::UpdateAspect (const Handle(OpenGl_Context)& theContext) +void OpenGl_CappingPlaneResource::updateAspect (const Handle(Graphic3d_AspectFillArea3d)& theObjAspect) { - Handle(Graphic3d_AspectFillArea3d) aCappingAsp = myPlaneRoot->CappingAspect(); - if (myAspect != NULL && !aCappingAsp.IsNull()) - { - if (myAspectMod == myPlaneRoot->MCountAspect()) - return; // noting to update - - myAspect->SetAspect (aCappingAsp); - myAspectMod = myPlaneRoot->MCountAspect(); - return; - } - - // no more used - if (myAspect != NULL && aCappingAsp.IsNull()) - { - OpenGl_Element::Destroy (theContext.operator->(), myAspect); - myAspectMod = myPlaneRoot->MCountAspect(); - return; - } - - // first created - if (myAspect == NULL && !aCappingAsp.IsNull()) + if (myAspect == NULL) { myAspect = new OpenGl_AspectFace(); - myAspect->SetAspect (aCappingAsp); - myAspectMod = myPlaneRoot->MCountAspect(); + myAspectMod = myPlaneRoot->MCountAspect() - 1; // mark out of sync } + + if (theObjAspect.IsNull()) + { + if (myAspectMod != myPlaneRoot->MCountAspect()) + { + myAspect->SetAspect (myPlaneRoot->CappingAspect()); + myAspectMod = myPlaneRoot->MCountAspect(); + } + return; + } + + if (myFillAreaAspect.IsNull()) + { + myFillAreaAspect = new Graphic3d_AspectFillArea3d(); + } + if (myAspectMod != myPlaneRoot->MCountAspect()) + { + *myFillAreaAspect = *myPlaneRoot->CappingAspect(); + } + + if (myPlaneRoot->ToUseObjectMaterial()) + { + // only front material currently supported by capping rendering + myFillAreaAspect->SetFrontMaterial (theObjAspect->FrontMaterial()); + myFillAreaAspect->SetInteriorColor (theObjAspect->InteriorColor()); + } + if (myPlaneRoot->ToUseObjectTexture()) + { + if (theObjAspect->ToMapTexture()) + { + myFillAreaAspect->SetTextureMap (theObjAspect->TextureMap()); + myFillAreaAspect->SetTextureMapOn(); + } + else + { + myFillAreaAspect->SetTextureMapOff(); + } + } + if (myPlaneRoot->ToUseObjectShader()) + { + myFillAreaAspect->SetShaderProgram (theObjAspect->ShaderProgram()); + } + + myAspect->SetAspect (myFillAreaAspect); } // ======================================================================= -// function : UpdateTransform +// function : updateTransform // purpose : // ======================================================================= -void OpenGl_CappingPlaneResource::UpdateTransform() +void OpenGl_CappingPlaneResource::updateTransform() { const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation(); if (myEquationMod == myPlaneRoot->MCountEquation()) diff --git a/src/OpenGl/OpenGl_CappingPlaneResource.hxx b/src/OpenGl/OpenGl_CappingPlaneResource.hxx index b3f66b1343..43b4c115b8 100755 --- a/src/OpenGl/OpenGl_CappingPlaneResource.hxx +++ b/src/OpenGl/OpenGl_CappingPlaneResource.hxx @@ -45,13 +45,18 @@ public: Standard_EXPORT virtual ~OpenGl_CappingPlaneResource(); //! Update resource data in the passed context. - //! @param theContext [in] the context. - Standard_EXPORT void Update (const Handle(OpenGl_Context)& theContext); + //! @param theContext [in] the context + //! @param theObjAspect [in] object aspect + Standard_EXPORT void Update (const Handle(OpenGl_Context)& theContext, + const Handle(Graphic3d_AspectFillArea3d)& theObjAspect); //! Release associated OpenGl resources. //! @param theContext [in] the resource context. Standard_EXPORT virtual void Release (OpenGl_Context* theContext) Standard_OVERRIDE; + //! Return parent clipping plane structure. + const Handle(Graphic3d_ClipPlane)& Plane() const { return myPlaneRoot; } + //! @return aspect face for rendering capping surface. inline const OpenGl_AspectFace* AspectFace() const { return myAspect; } @@ -64,11 +69,10 @@ public: private: //! Update precomputed plane orientation matrix. - void UpdateTransform(); + void updateTransform(); //! Update resources. - //! @param theContext [in] the context. - void UpdateAspect (const Handle(OpenGl_Context)& theContext); + void updateAspect (const Handle(Graphic3d_AspectFillArea3d)& theObjAspect); private: @@ -76,6 +80,7 @@ private: OpenGl_Matrix myOrientation; //!< plane transformation matrix. OpenGl_AspectFace* myAspect; //!< capping face aspect. Handle(Graphic3d_ClipPlane) myPlaneRoot; //!< parent clipping plane structure. + Handle(Graphic3d_AspectFillArea3d) myFillAreaAspect; //!< own capping aspect unsigned int myEquationMod; //!< modification counter for plane equation. unsigned int myAspectMod; //!< modification counter for aspect. diff --git a/src/OpenGl/OpenGl_SceneGeometry.cxx b/src/OpenGl/OpenGl_SceneGeometry.cxx index b3d7de271f..d363629004 100755 --- a/src/OpenGl/OpenGl_SceneGeometry.cxx +++ b/src/OpenGl/OpenGl_SceneGeometry.cxx @@ -601,20 +601,4 @@ namespace OpenGl_Raytrace } return Standard_False; } - - // ======================================================================= - // function : IsRaytracedStructure - // purpose : Checks to see if the structure contains ray-trace geometry - // ======================================================================= - Standard_Boolean IsRaytracedStructure (const OpenGl_Structure* theStructure) - { - for (OpenGl_Structure::GroupIterator anIter (theStructure->DrawGroups()); anIter.More(); anIter.Next()) - { - if (anIter.Value()->IsRaytracable()) - { - return Standard_True; - } - } - return Standard_False; - } } diff --git a/src/OpenGl/OpenGl_SceneGeometry.hxx b/src/OpenGl/OpenGl_SceneGeometry.hxx index 9cde62964a..237e6f4ce2 100755 --- a/src/OpenGl/OpenGl_SceneGeometry.hxx +++ b/src/OpenGl/OpenGl_SceneGeometry.hxx @@ -40,9 +40,6 @@ namespace OpenGl_Raytrace //! Checks to see if the element contains ray-trace geometry. Standard_Boolean IsRaytracedElement (const OpenGl_Element* theElement); - - //! Checks to see if the structure contains ray-trace geometry. - Standard_Boolean IsRaytracedStructure (const OpenGl_Structure* theStructure); } //! Stores properties of surface material. diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index a0eca72694..767288cdc8 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -262,16 +262,14 @@ void OpenGl_Structure::OnVisibilityChanged() // ======================================================================= Standard_Boolean OpenGl_Structure::IsRaytracable() const { - if (!myGroups.IsEmpty()) + if (!myGroups.IsEmpty() + && myIsRaytracable) { - return myIsRaytracable; // geometry structure - } - else if (myInstancedStructure != NULL) - { - return myInstancedStructure->IsRaytracable(); // instance structure + return Standard_True; } - return Standard_False; // has no any groups or structures + return myInstancedStructure != NULL + && myInstancedStructure->IsRaytracable(); } // ======================================================================= @@ -280,7 +278,18 @@ Standard_Boolean OpenGl_Structure::IsRaytracable() const // ======================================================================= void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const { - myIsRaytracable = !toCheck || OpenGl_Raytrace::IsRaytracedStructure (this); + myIsRaytracable = !toCheck; + if (!myIsRaytracable) + { + for (OpenGl_Structure::GroupIterator anIter (myGroups); anIter.More(); anIter.Next()) + { + if (anIter.Value()->IsRaytracable()) + { + myIsRaytracable = Standard_True; + break; + } + } + } if (IsRaytracable()) { @@ -424,26 +433,6 @@ void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorksp } } -// ======================================================================= -// function : renderClosedGeometry -// purpose : -// ======================================================================= -void OpenGl_Structure::renderClosedGeometry (const Handle(OpenGl_Workspace)& theWorkspace) const -{ - if (myInstancedStructure != NULL) - { - myInstancedStructure->renderClosedGeometry (theWorkspace); - } - - for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) - { - if (aGroupIter.Value()->IsClosed()) - { - aGroupIter.Value()->Render (theWorkspace); - } - } -} - // ======================================================================= // function : Render // purpose : diff --git a/src/OpenGl/OpenGl_Structure.hxx b/src/OpenGl/OpenGl_Structure.hxx index 61560f8fa0..68147108cd 100644 --- a/src/OpenGl/OpenGl_Structure.hxx +++ b/src/OpenGl/OpenGl_Structure.hxx @@ -99,12 +99,6 @@ public: public: - //! @return graphic groups - virtual const Graphic3d_SequenceOfGroup& DrawGroups() const - { - return myGroups; - } - //! Access graphic driver OpenGl_GraphicDriver* GlDriver() const { @@ -120,15 +114,6 @@ public: Standard_EXPORT void Clear (const Handle(OpenGl_Context)& theGlCtx); - //! Renders groups of structure without applying any attributes (i.e. transform, material etc). - //! @param theWorkspace current workspace - //! @param theHasClosed flag will be set to TRUE if structure contains at least one group of closed primitives - virtual void renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace, - bool& theHasClosed) const; - - //! Renders groups of closed primitives without applying any attributes (i.e. transform, material etc). - virtual void renderClosedGeometry (const Handle(OpenGl_Workspace)& theWorkspace) const; - //! Renders the structure. virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const; @@ -192,6 +177,12 @@ protected: //! Updates ray-tracable status for structure and its parents. void UpdateStateIfRaytracable (const Standard_Boolean toCheck = Standard_True) const; + //! Renders groups of structure without applying any attributes (i.e. transform, material etc). + //! @param theWorkspace current workspace + //! @param theHasClosed flag will be set to TRUE if structure contains at least one group of closed primitives + Standard_EXPORT void renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace, + bool& theHasClosed) const; + protected: Handle(OpenGl_Group) myHighlightBox; diff --git a/src/OpenGl/OpenGl_StructureShadow.cxx b/src/OpenGl/OpenGl_StructureShadow.cxx index 3d272abb34..0f7277be66 100644 --- a/src/OpenGl/OpenGl_StructureShadow.cxx +++ b/src/OpenGl/OpenGl_StructureShadow.cxx @@ -16,6 +16,7 @@ #include #include +#include IMPLEMENT_STANDARD_RTTIEXT(OpenGl_StructureShadow,OpenGl_Structure) @@ -38,4 +39,25 @@ OpenGl_StructureShadow::OpenGl_StructureShadow (const Handle(Graphic3d_Structure UpdateTransformation(); myInstancedStructure = const_cast (myParent->InstancedStructure()); TransformPersistence = myParent->TransformPersistence; + + // reuse instanced structure API + myInstancedStructure = myParent.operator->(); +} + +// ======================================================================= +// function : Connect +// purpose : +// ======================================================================= +void OpenGl_StructureShadow::Connect (Graphic3d_CStructure& ) +{ + Standard_ProgramError::Raise ("Error! OpenGl_StructureShadow::Connect() should not be called!"); +} + +// ======================================================================= +// function : Disconnect +// purpose : +// ======================================================================= +void OpenGl_StructureShadow::Disconnect (Graphic3d_CStructure& ) +{ + Standard_ProgramError::Raise ("Error! OpenGl_StructureShadow::Disconnect() should not be called!"); } diff --git a/src/OpenGl/OpenGl_StructureShadow.hxx b/src/OpenGl/OpenGl_StructureShadow.hxx index c5a19ec496..a325f17440 100644 --- a/src/OpenGl/OpenGl_StructureShadow.hxx +++ b/src/OpenGl/OpenGl_StructureShadow.hxx @@ -28,22 +28,13 @@ public: Standard_EXPORT OpenGl_StructureShadow (const Handle(Graphic3d_StructureManager)& theManager, const Handle(OpenGl_Structure)& theStructure); - //! Return groups of parent structure. - virtual const Graphic3d_SequenceOfGroup& DrawGroups() const Standard_OVERRIDE - { return myParent->DrawGroups(); } +public: - //! Renders groups of parent structure. - virtual void renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace, - bool& theHasClosed) const Standard_OVERRIDE - { - myParent->renderGeometry (theWorkspace, theHasClosed); - } + //! Raise exception on API misuse. + virtual void Connect (Graphic3d_CStructure& ) Standard_OVERRIDE; - //! Renders closed groups of parent structure. - virtual void renderClosedGeometry (const Handle(OpenGl_Workspace)& theWorkspace) const Standard_OVERRIDE - { - myParent->renderClosedGeometry (theWorkspace); - } + //! Raise exception on API misuse. + virtual void Disconnect (Graphic3d_CStructure& ) Standard_OVERRIDE; private: diff --git a/src/OpenGl/OpenGl_View_Raytrace.cxx b/src/OpenGl/OpenGl_View_Raytrace.cxx index cc4d91c491..551a0035d7 100644 --- a/src/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/OpenGl/OpenGl_View_Raytrace.cxx @@ -109,7 +109,7 @@ Standard_Boolean OpenGl_View::updateRaytraceGeometry (const RaytraceUpdateMode continue; } - for (OpenGl_Structure::GroupIterator aGroupIter (aStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next()) + for (OpenGl_Structure::GroupIterator aGroupIter (aStructure->Groups()); aGroupIter.More(); aGroupIter.Next()) { // Extract OpenGL elements from the group (primitives arrays) for (const OpenGl_ElementNode* aNode = aGroupIter.Value()->FirstNode(); aNode != NULL; aNode = aNode->next) @@ -457,7 +457,7 @@ Standard_Boolean OpenGl_View::addRaytraceGroups (const OpenGl_Structure* const Graphic3d_Mat4* theTransform, const Handle(OpenGl_Context)& theGlContext) { - for (OpenGl_Structure::GroupIterator aGroupIter (theStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next()) + for (OpenGl_Structure::GroupIterator aGroupIter (theStructure->Groups()); aGroupIter.More(); aGroupIter.Next()) { // Get group material OpenGl_RaytraceMaterial aGroupMaterial; diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index b74cec6187..fc05e2762b 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -2297,6 +2297,11 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, if (aColoredPrs.IsNull()) { aColoredPrs = new AIS_ColoredShape (aShapePrs); + if (aShapePrs->HasDisplayMode()) + { + aColoredPrs->SetDisplayMode (aShapePrs->DisplayMode()); + } + aColoredPrs->SetLocalTransformation (aShapePrs->LocalTransformation()); aCtx->Remove (aShapePrs, Standard_False); GetMapOfAIS().UnBind2 (aName); GetMapOfAIS().Bind (aColoredPrs, aName); diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 9c86583f05..ddbd7ef59c 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -6417,6 +6417,40 @@ static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, return 0; } +namespace +{ + typedef NCollection_DataMap MapOfPlanes; + + //! Remove registered clipping plane from all views and objects. + static void removePlane (MapOfPlanes& theRegPlanes, + const TCollection_AsciiString& theName) + { + Handle(Graphic3d_ClipPlane) aClipPlane; + if (!theRegPlanes.Find (theName, aClipPlane)) + { + std::cout << "Warning: no such plane.\n"; + return; + } + + theRegPlanes.UnBind (theName); + for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS()); + anIObjIt.More(); anIObjIt.Next()) + { + Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anIObjIt.Key1()); + aPrs->RemoveClipPlane (aClipPlane); + } + + for (NCollection_DoubleMap::Iterator aViewIt(ViewerTest_myViews); + aViewIt.More(); aViewIt.Next()) + { + const Handle(V3d_View)& aView = aViewIt.Key2(); + aView->RemoveClipPlane(aClipPlane); + } + + ViewerTest::RedrawAllViews(); + } +} + //=============================================================================================== //function : VClipPlane //purpose : @@ -6424,392 +6458,488 @@ static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec) { // use short-cut for created clip planes map of created (or "registered by name") clip planes - typedef NCollection_DataMap MapOfPlanes; static MapOfPlanes aRegPlanes; if (theArgsNb < 2) { - theDi << theArgVec[0] << ": command argument is required. Type help for more information.\n"; - return 1; + for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next()) + { + theDi << aPlaneIter.Key() << " "; + } + return 0; } TCollection_AsciiString aCommand (theArgVec[1]); + aCommand.LowerCase(); + const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView(); + if (anActiveView.IsNull()) + { + std::cout << "Error: no active view.\n"; + return 1; + } // print maximum number of planes for current viewer - if (aCommand == "maxplanes") + if (aCommand == "-maxplanes" + || aCommand == "maxplanes") { - if (theArgsNb < 3) - { - theDi << theArgVec[0] << ": view name is required. Type help for more information.\n"; - return 1; - } - - TCollection_AsciiString aViewName (theArgVec[2]); - - if (!ViewerTest_myViews.IsBound1 (aViewName)) - { - theDi << theArgVec[0] << ": view is not found.\n"; - return 1; - } - - const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName); - - theDi << theArgVec[0] << ": " - << aView->Viewer()->Driver()->InquirePlaneLimit() - << " plane slots provided by driver." - << " Note that 2 more planes might be used (reserved for z-clipping).\n"; - + theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit() + << " plane slots provided by driver.\n"; return 0; } // create / delete plane instance - if (aCommand == "create" || aCommand == "delete" || aCommand == "clone") + if (aCommand == "-create" + || aCommand == "create" + || aCommand == "-delete" + || aCommand == "delete" + || aCommand == "-clone" + || aCommand == "clone") { if (theArgsNb < 3) { - theDi << theArgVec[0] << ": plane name is required. Type help for more information.\n"; + std::cout << "Syntax error: plane name is required.\n"; return 1; } - Standard_Boolean toCreate = (aCommand == "create"); - Standard_Boolean toClone = (aCommand == "clone"); + Standard_Boolean toCreate = aCommand == "-create" + || aCommand == "create"; + Standard_Boolean toClone = aCommand == "-clone" + || aCommand == "clone"; + Standard_Boolean toDelete = aCommand == "-delete" + || aCommand == "delete"; TCollection_AsciiString aPlane (theArgVec[2]); if (toCreate) { if (aRegPlanes.IsBound (aPlane)) { - theDi << theArgVec[0] << ": plane name is in use.\n"; - return 1; + std::cout << "Warning: existing plane has been overridden.\n"; + toDelete = true; + } + else + { + aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane()); + return 0; } - - aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane()); } else if (toClone) // toClone { if (!aRegPlanes.IsBound (aPlane)) { - theDi << theArgVec[0] << ": no such plane.\n"; + std::cout << "Error: no such plane.\n"; return 1; } - - if (theArgsNb < 4) + else if (theArgsNb < 4) { - theDi << theArgVec[0] << ": enter name for new plane. Type help for more information.\n"; + std::cout << "Syntax error: enter name for new plane.\n"; return 1; } TCollection_AsciiString aClone (theArgVec[3]); if (aRegPlanes.IsBound (aClone)) { - theDi << theArgVec[0] << ": plane name is in use.\n"; + std::cout << "Error: plane name is in use.\n"; return 1; } const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane); aRegPlanes.Bind (aClone, aClipPlane->Clone()); + return 0; } - else// toDelete + + if (toDelete) { - if (!aRegPlanes.IsBound (aPlane)) + if (aPlane == "ALL" + || aPlane == "all" + || aPlane == "*") { - theDi << theArgVec[0] << ": no such plane.\n"; - return 1; + for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();) + { + aPlane = aPlaneIter.Key(); + removePlane (aRegPlanes, aPlane); + aPlaneIter = MapOfPlanes::Iterator (aRegPlanes); + } } - - Handle(Graphic3d_ClipPlane) aClipPlane = aRegPlanes.Find (aPlane); - aRegPlanes.UnBind (aPlane); - - ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS()); - for (; anIObjIt.More(); anIObjIt.Next()) + else { - Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anIObjIt.Key1()); - aPrs->RemoveClipPlane(aClipPlane); + removePlane (aRegPlanes, aPlane); } - - NCollection_DoubleMap::Iterator aViewIt(ViewerTest_myViews); - for (; aViewIt.More(); aViewIt.Next()) - { - const Handle(V3d_View)& aView = aViewIt.Key2(); - aView->RemoveClipPlane(aClipPlane); - } - - ViewerTest::RedrawAllViews(); } + if (toCreate) + { + aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane()); + } return 0; } // set / unset plane command - if (aCommand == "set" || aCommand == "unset") + if (aCommand == "set" + || aCommand == "unset") { - if (theArgsNb < 4) + if (theArgsNb < 5) { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + std::cout << "Syntax error: need more arguments.\n"; return 1; } - Standard_Boolean toSet = (aCommand == "set"); - TCollection_AsciiString aPlane (theArgVec [2]); - if (!aRegPlanes.IsBound (aPlane)) + // redirect to new syntax + NCollection_Array1 anArgVec (1, theArgsNb - 1); + anArgVec.SetValue (1, theArgVec[0]); + anArgVec.SetValue (2, theArgVec[2]); + anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset"); + for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt) { - theDi << theArgVec[0] << ": no such plane.\n"; - return 1; + anArgVec.SetValue (anIt, theArgVec[anIt]); } - const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane); - - TCollection_AsciiString aTarget (theArgVec [3]); - if (aTarget != "object" && aTarget != "view") - { - theDi << theArgVec[0] << ": invalid target.\n"; - return 1; - } - - if (aTarget == "object" || aTarget == "view") - { - if (theArgsNb < 5) - { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; - return 1; - } - - Standard_Boolean isObject = (aTarget == "object"); - - for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt) - { - TCollection_AsciiString anEntityName (theArgVec[anIt]); - if (isObject) // to object - { - if (!GetMapOfAIS().IsBound2 (anEntityName)) - { - theDi << theArgVec[0] << ": can not find IO with name " << anEntityName << ".\n"; - continue; - } - - Handle(AIS_InteractiveObject) aIObj = - Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anEntityName)); - - if (toSet) - aIObj->AddClipPlane (aClipPlane); - else - aIObj->RemoveClipPlane (aClipPlane); - } - else // to view - { - if (!ViewerTest_myViews.IsBound1 (anEntityName)) - { - theDi << theArgVec[0] << ": can not find View with name " << anEntityName << ".\n"; - continue; - } - - Handle(V3d_View) aView = ViewerTest_myViews.Find1(anEntityName); - if (toSet) - aView->AddClipPlane (aClipPlane); - else - aView->RemoveClipPlane (aClipPlane); - } - } - - ViewerTest::RedrawAllViews(); - } - - return 0; + return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst()); } // change plane command - if (aCommand == "change") + TCollection_AsciiString aPlaneName; + Handle(Graphic3d_ClipPlane) aClipPlane; + Standard_Integer anArgIter = 0; + if (aCommand == "-change" + || aCommand == "change") { - if (theArgsNb < 4) + // old syntax support + if (theArgsNb < 3) { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + std::cout << "Syntax error: need more arguments.\n"; return 1; } - TCollection_AsciiString aPlane (theArgVec [2]); - if (!aRegPlanes.IsBound (aPlane)) + anArgIter = 3; + aPlaneName = theArgVec[2]; + if (!aRegPlanes.Find (aPlaneName, aClipPlane)) { - theDi << theArgVec[0] << ": no such plane.\n"; + std::cout << "Error: no such plane '" << aPlaneName << "'.\n"; return 1; } - - const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane); - - TCollection_AsciiString aChangeArg (theArgVec [3]); - if (aChangeArg != "on" && aChangeArg != "off" && aChangeArg != "capping" && aChangeArg != "equation") - { - theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n"; - return 1; - } - - if (aChangeArg == "on" || aChangeArg == "off") // on / off - { - aClipPlane->SetOn (aChangeArg == "on"); - } - else if (aChangeArg == "equation") // change equation - { - if (theArgsNb < 8) - { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; - return 1; - } - - Standard_Real aCoeffA = Draw::Atof (theArgVec [4]); - Standard_Real aCoeffB = Draw::Atof (theArgVec [5]); - Standard_Real aCoeffC = Draw::Atof (theArgVec [6]); - Standard_Real aCoeffD = Draw::Atof (theArgVec [7]); - aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD)); - } - else if (aChangeArg == "capping") // change capping aspects - { - if (theArgsNb < 5) - { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; - return 1; - } - - TCollection_AsciiString aCappingArg (theArgVec [4]); - if (aCappingArg != "on" && aCappingArg != "off" && - aCappingArg != "color" && aCappingArg != "texname" && - aCappingArg != "texscale" && aCappingArg != "texorigin" && - aCappingArg != "texrotate" && aCappingArg != "hatch") - { - theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n"; - return 1; - } - - if (aCappingArg == "on" || aCappingArg == "off") // on / off capping - { - aClipPlane->SetCapping (aCappingArg == "on"); - } - else if (aCappingArg == "color") // color aspect for capping - { - if (theArgsNb < 8) - { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; - return 1; - } - - Standard_Real aRed = Draw::Atof (theArgVec [5]); - Standard_Real aGrn = Draw::Atof (theArgVec [6]); - Standard_Real aBlu = Draw::Atof (theArgVec [7]); - - Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial(); - Quantity_Color aColor (aRed, aGrn, aBlu, Quantity_TOC_RGB); - aMat.SetAmbientColor (aColor); - aMat.SetDiffuseColor (aColor); - aClipPlane->SetCappingMaterial (aMat); - } - else if (aCappingArg == "texname") // texture name - { - if (theArgsNb < 6) - { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; - return 1; - } - - TCollection_AsciiString aTextureName (theArgVec [5]); - - Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName); - if (!aTexture->IsDone ()) - { - aClipPlane->SetCappingTexture (NULL); - } - else - { - aTexture->EnableModulate(); - aTexture->EnableRepeat(); - aClipPlane->SetCappingTexture (aTexture); - } - } - else if (aCappingArg == "texscale") // texture scale - { - if (aClipPlane->CappingTexture().IsNull()) - { - theDi << theArgVec[0] << ": no texture is set.\n"; - return 1; - } - - if (theArgsNb < 7) - { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; - return 1; - } - - Standard_ShortReal aSx = (Standard_ShortReal)atof (theArgVec [5]); - Standard_ShortReal aSy = (Standard_ShortReal)atof (theArgVec [6]); - - aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy)); - } - else if (aCappingArg == "texorigin") // texture origin - { - if (aClipPlane->CappingTexture().IsNull()) - { - theDi << theArgVec[0] << ": no texture is set.\n"; - return 1; - } - - if (theArgsNb < 7) - { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; - return 1; - } - - Standard_ShortReal aTx = (Standard_ShortReal)atof (theArgVec [5]); - Standard_ShortReal aTy = (Standard_ShortReal)atof (theArgVec [6]); - - aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy)); - } - else if (aCappingArg == "texrotate") // texture rotation - { - if (aClipPlane->CappingTexture().IsNull()) - { - theDi << theArgVec[0] << ": no texture is set.\n"; - return 1; - } - - if (theArgsNb < 6) - { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; - return 1; - } - - Standard_ShortReal aRot = (Standard_ShortReal)atof (theArgVec[5]); - - aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot); - } - else if (aCappingArg == "hatch") // hatch style - { - if (theArgsNb < 6) - { - theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; - return 1; - } - - TCollection_AsciiString aHatchStr (theArgVec [5]); - if (aHatchStr == "on") - { - aClipPlane->SetCappingHatchOn(); - } - else if (aHatchStr == "off") - { - aClipPlane->SetCappingHatchOff(); - } - else - { - aClipPlane->SetCappingHatch ((Aspect_HatchStyle)atoi (theArgVec[5])); - } - } - } - - ViewerTest::RedrawAllViews(); - - return 0; + } + else if (aRegPlanes.Find (theArgVec[1], aClipPlane)) + { + anArgIter = 2; + aPlaneName = theArgVec[1]; + } + else + { + anArgIter = 2; + aPlaneName = theArgVec[1]; + aClipPlane = new Graphic3d_ClipPlane(); + aRegPlanes.Bind (aPlaneName, aClipPlane); + theDi << "Created new plane " << aPlaneName << ".\n"; } - theDi << theArgVec[0] << ": invalid command. Type help for more information.\n"; - return 1; + if (theArgsNb - anArgIter < 1) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + for (; anArgIter < theArgsNb; ++anArgIter) + { + const char** aChangeArgs = theArgVec + anArgIter; + Standard_Integer aNbChangeArgs = theArgsNb - anArgIter; + TCollection_AsciiString aChangeArg (aChangeArgs[0]); + aChangeArg.LowerCase(); + + Standard_Boolean toEnable = Standard_True; + if (ViewerTest::ParseOnOff (aChangeArgs[0], toEnable)) + { + aClipPlane->SetOn (toEnable); + } + else if (aChangeArg == "-equation" + || aChangeArg == "equation") + { + if (aNbChangeArgs < 5) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + Standard_Real aCoeffA = Draw::Atof (aChangeArgs [1]); + Standard_Real aCoeffB = Draw::Atof (aChangeArgs [2]); + Standard_Real aCoeffC = Draw::Atof (aChangeArgs [3]); + Standard_Real aCoeffD = Draw::Atof (aChangeArgs [4]); + aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD)); + anArgIter += 4; + } + else if (aChangeArg == "-capping" + || aChangeArg == "capping") + { + if (aNbChangeArgs < 2) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable)) + { + aClipPlane->SetCapping (toEnable); + anArgIter += 1; + } + else + { + // just skip otherwise (old syntax) + } + } + else if (aChangeArg == "-useobjectmaterial" + || aChangeArg == "-useobjectmat" + || aChangeArg == "-useobjmat" + || aChangeArg == "-useobjmaterial") + { + if (aNbChangeArgs < 2) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable)) + { + aClipPlane->SetUseObjectMaterial (toEnable == Standard_True); + anArgIter += 1; + } + } + else if (aChangeArg == "-useobjecttexture" + || aChangeArg == "-useobjecttex" + || aChangeArg == "-useobjtexture" + || aChangeArg == "-useobjtex") + { + if (aNbChangeArgs < 2) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable)) + { + aClipPlane->SetUseObjectTexture (toEnable == Standard_True); + anArgIter += 1; + } + } + else if (aChangeArg == "-useobjectshader" + || aChangeArg == "-useobjshader") + { + if (aNbChangeArgs < 2) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable)) + { + aClipPlane->SetUseObjectShader (toEnable == Standard_True); + anArgIter += 1; + } + } + else if (aChangeArg == "-color" + || aChangeArg == "color") + { + Quantity_Color aColor; + Standard_Integer aNbParsed = ViewerTest::ParseColor (aNbChangeArgs - 1, + aChangeArgs + 1, + aColor); + if (aNbParsed == 0) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial(); + aMat.SetAmbientColor (aColor); + aMat.SetDiffuseColor (aColor); + aClipPlane->SetCappingMaterial (aMat); + anArgIter += aNbParsed; + } + else if (aChangeArg == "-texname" + || aChangeArg == "texname") + { + if (aNbChangeArgs < 2) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + TCollection_AsciiString aTextureName (aChangeArgs[1]); + Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName); + if (!aTexture->IsDone()) + { + aClipPlane->SetCappingTexture (NULL); + } + else + { + aTexture->EnableModulate(); + aTexture->EnableRepeat(); + aClipPlane->SetCappingTexture (aTexture); + } + anArgIter += 1; + } + else if (aChangeArg == "-texscale" + || aChangeArg == "texscale") + { + if (aClipPlane->CappingTexture().IsNull()) + { + std::cout << "Error: no texture is set.\n"; + return 1; + } + + if (aNbChangeArgs < 3) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]); + Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]); + aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy)); + anArgIter += 2; + } + else if (aChangeArg == "-texorigin" + || aChangeArg == "texorigin") // texture origin + { + if (aClipPlane->CappingTexture().IsNull()) + { + std::cout << "Error: no texture is set.\n"; + return 1; + } + + if (aNbChangeArgs < 3) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]); + Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]); + + aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy)); + anArgIter += 2; + } + else if (aChangeArg == "-texrotate" + || aChangeArg == "texrotate") // texture rotation + { + if (aClipPlane->CappingTexture().IsNull()) + { + std::cout << "Error: no texture is set.\n"; + return 1; + } + + if (aNbChangeArgs < 2) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]); + aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot); + anArgIter += 1; + } + else if (aChangeArg == "-hatch" + || aChangeArg == "hatch") + { + if (aNbChangeArgs < 2) + { + std::cout << "Syntax error: need more arguments.\n"; + return 1; + } + + TCollection_AsciiString aHatchStr (aChangeArgs[1]); + aHatchStr.LowerCase(); + if (aHatchStr == "on") + { + aClipPlane->SetCappingHatchOn(); + } + else if (aHatchStr == "off") + { + aClipPlane->SetCappingHatchOff(); + } + else + { + aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1])); + } + anArgIter += 1; + } + else if (aChangeArg == "-delete" + || aChangeArg == "delete") + { + removePlane (aRegPlanes, aPlaneName); + return 0; + } + else if (aChangeArg == "-set" + || aChangeArg == "-unset") + { + // set / unset plane command + Standard_Boolean toSet = aChangeArg == "-set"; + Standard_Integer anIt = 1; + for (; anIt < aNbChangeArgs; ++anIt) + { + TCollection_AsciiString anEntityName (aChangeArgs[anIt]); + if (anEntityName.IsEmpty() + || anEntityName.Value (1) == '-') + { + break; + } + else if (ViewerTest_myViews.IsBound1 (anEntityName)) + { + Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName); + if (toSet) + { + aView->AddClipPlane (aClipPlane); + } + else + { + aView->RemoveClipPlane (aClipPlane); + } + continue; + } + else if (GetMapOfAIS().IsBound2 (anEntityName)) + { + Handle(AIS_InteractiveObject) aIObj = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anEntityName)); + if (toSet) + { + aIObj->AddClipPlane (aClipPlane); + } + else + { + aIObj->RemoveClipPlane (aClipPlane); + } + } + else + { + std::cout << "Error: object/view '" << anEntityName << "' is not found!\n"; + return 1; + } + } + + if (anIt == 1) + { + // apply to active view + if (toSet) + { + anActiveView->AddClipPlane (aClipPlane); + } + else + { + anActiveView->RemoveClipPlane (aClipPlane); + } + } + else + { + anArgIter = anArgIter + anIt - 1; + } + } + else + { + std::cout << "Syntax error: unknown argument '" << aChangeArg << "'.\n"; + return 1; + } + } + + ViewerTest::RedrawAllViews(); + return 0; } //=============================================================================================== @@ -9340,24 +9470,37 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) "If shapes are not given HLR algoithm of given type is applied" " to all shapes in the view\n", __FILE__,VHLRType,group); - theCommands.Add("vclipplane", "vclipplane usage: \n" - " maxplanes - get plane limit for view.\n" - " create - create new plane.\n" - " delete - delete plane.\n" - " clone - clone the plane definition.\n" - " set/unset object - set/unset plane for IO.\n" - " set/unset view - set/unset plane for view.\n" - " change on/off - turn clipping on/off.\n" - " change equation - change plane equation.\n" - " change capping on/off - turn capping on/off.\n" - " change capping color - set color.\n" - " change capping texname - set texture.\n" - " change capping texscale - set tex scale.\n" - " change capping texorigin - set tex origin.\n" - " change capping texrotate - set tex rotation.\n" - " change capping hatch on/off/ - set hatching mask.\n" - " please use VSetTextureMode command to enable texture rendering in view.\n" - , __FILE__, VClipPlane, group); + theCommands.Add("vclipplane", + "vclipplane planeName [{0|1}]" + "\n\t\t: [-equation A B C D]" + "\n\t\t: [-set|-unset [objects|views]]" + "\n\t\t: [-maxPlanes]" + "\n\t\t: [-capping {0|1}]" + "\n\t\t: [-color R G B] [-hatch {on|off|ID}]" + "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]" + "\n\t\t: [-texRotate Angle]" + "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]" + "\n\t\t: [-useObjShader {0|1}]" + "\n\t\t: Clipping planes management:" + "\n\t\t: -maxPlanes print plane limit for view" + "\n\t\t: -delete delete plane with given name" + "\n\t\t: {off|on|0|1} turn clipping on/off" + "\n\t\t: -set|-unset set/unset plane for Object or View list;" + "\n\t\t: applied to active View when list is omitted" + "\n\t\t: -equation A B C D change plane equation" + "\n\t\t: -clone SourcePlane NewPlane clone the plane definition." + "\n\t\t: Capping options:" + "\n\t\t: -capping {off|on|0|1} turn capping on/off" + "\n\t\t: -color R G B set capping color" + "\n\t\t: -texName Texture set capping texture" + "\n\t\t: -texScale SX SY set capping tex scale" + "\n\t\t: -texOrigin TX TY set capping tex origin" + "\n\t\t: -texRotate Angle set capping tex rotation" + "\n\t\t: -hatch {on|off|ID} set capping hatching mask" + "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object" + "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object" + "\n\t\t: -useObjShader {off|on|0|1} use shader program of object", + __FILE__, VClipPlane, group); theCommands.Add("vdefaults", "vdefaults [-absDefl value]" "\n\t\t: [-devCoeff value]" diff --git a/tests/bugs/vis/bug26028 b/tests/bugs/vis/bug26028 index dd2f7a30c5..34f880cab8 100644 --- a/tests/bugs/vis/bug26028 +++ b/tests/bugs/vis/bug26028 @@ -48,7 +48,8 @@ set aColor2 [vreadpixel 325 325 rgb name] set aColor3 [vreadpixel 225 150 rgb name] set aColor4 [vreadpixel 325 200 rgb name] -if { "$aColor0" != "GRAY61" || "$aColor1" != "GRAY61" || "$aColor2" != "GRAY61" || "$aColor3" != "GRAY61" || "$aColor4" != "GRAY61" } { +# note that aColor2 is not expected to be capped +if { "$aColor0" != "GRAY61" || "$aColor1" != "GRAY61" || "$aColor2" == "GRAY61" || "$aColor3" != "GRAY61" || "$aColor4" != "GRAY61" } { puts "Error: capping color does not match" } diff --git a/tests/bugs/vis/bug27751_capping b/tests/bugs/vis/bug27751_capping new file mode 100644 index 0000000000..122c566446 --- /dev/null +++ b/tests/bugs/vis/bug27751_capping @@ -0,0 +1,76 @@ +puts "========" +puts "Capping plane perserving material" +puts "========" + +set aHatch [locate_data_file images/hatch_1.png] + +pload MODELING VISUALIZATION + +puts "Create the geometry" +box b0sole 10 10 0 30 30 70 +box b0hole 20 20 -10 10 10 90 +bcut b0 b0sole b0hole +box b1 40 20 0 10 30 70 +box b2 20 40 0 20 10 70 +box b3 0 40 0 20 10 70 +box b4 0 10 0 10 30 70 +box b5 0 0 0 30 10 70 + +set aNbParts 6 +set aColors { RED YELLOW GREEN GRAY MAGENTA1 ORANGE } + +compound b0 b1 b2 b3 b4 b5 cc + +puts "Create the viewer" +vclear +vclose ALL +vinit name=View1 w=512 h=512 + +vpoint p0 0 0 0 +vzbufftrihedron + +puts "Display the geometry as dedicated objects" +for { set aPartIter 0 } { $aPartIter < $aNbParts } { incr aPartIter } { + vdisplay -noupdate -dispMode 1 b${aPartIter} + set aColor [lindex $aColors $aPartIter] + vsetcolor -noupdate b${aPartIter} $aColor +} + +puts "Display the geometry as sole object" +vdisplay -noupdate -dispMode 1 cc +for { set aPartIter 0 } { $aPartIter < $aNbParts } { incr aPartIter } { + set aColor [lindex $aColors $aPartIter] + vaspects -noupdate cc -subShapes b${aPartIter} -setColor $aColor +} +# show also connected interactive object +vconnectto co -70 0 0 cc +vsetdispmode co 1 +vsetlocation cc 70 0 0 +vfit + + +set aPln1Z 40 +set aPln2Y 15 + +vremove -noupdate p1 p2 p3 pp1 pp2 +vpoint p1 0 0 1 +vpoint p2 1 0 1 +vpoint p3 0 1 1 +vplane pp1 p1 p2 p3 +vsetlocation -noupdate pp1 25 0 [expr $aPln1Z - 1] +vremove -noupdate p1 p2 p3 + +vpoint p1 0 1 0 +vpoint p2 1 1 0 +vpoint p3 0 1 1 +vplane pp2 p1 p2 p3 +vsetlocation -noupdate pp2 25 $aPln2Y 35 +vremove -noupdate p1 p2 p3 +verase pp1 pp2 +vfit +vdisplay pp1 pp2 +vzoom 0.8 + +puts "Enable capping planes" +vclipplane pln1 -set -equation 0 0 -1 $aPln1Z -capping 1 -color 0.5 0.5 0.5 -texname $aHatch -texscale 0.02 -0.02 -useObjMaterial 1 +vclipplane pln2 -set -equation 0 1 0 [expr -$aPln2Y] -capping 1 -color 0.8 0.8 0.9 -texname $aHatch -texscale 0.02 -0.02 diff --git a/tests/v3d/materials/begin b/tests/v3d/materials/begin deleted file mode 100644 index 6cabd388d9..0000000000 --- a/tests/v3d/materials/begin +++ /dev/null @@ -1 +0,0 @@ -vinit View1 \ No newline at end of file