From 4552cb8552d15fc7097b7c6d6d4d5b5ea4248562 Mon Sep 17 00:00:00 2001 From: mzernova Date: Thu, 9 Jul 2020 11:32:40 +0300 Subject: [PATCH] 0027130: Visualization, Ray tracing - skip structures with transformation persistence flag Objects with transform persistence are detected as non ray-tracable and redered using the rasterization approach. The renderFiltered() method moved to the OpenGl_Group class. v3d/raytrace/bug27130: test case added --- src/OpenGl/OpenGl_CappingAlgo.cxx | 2 +- src/OpenGl/OpenGl_Group.cxx | 41 ++++++++++++----------------- src/OpenGl/OpenGl_Group.hxx | 15 +++++++++++ src/OpenGl/OpenGl_SceneGeometry.cxx | 5 ++++ src/OpenGl/OpenGl_Structure.cxx | 7 ++++- src/OpenGl/OpenGl_Workspace.cxx | 5 ++-- src/OpenGl/OpenGl_Workspace.hxx | 3 ++- tests/v3d/raytrace/bug27130 | 18 +++++++++++++ 8 files changed, 67 insertions(+), 29 deletions(-) create mode 100644 tests/v3d/raytrace/bug27130 diff --git a/src/OpenGl/OpenGl_CappingAlgo.cxx b/src/OpenGl/OpenGl_CappingAlgo.cxx index 0e22c66d2c..743a809992 100755 --- a/src/OpenGl/OpenGl_CappingAlgo.cxx +++ b/src/OpenGl/OpenGl_CappingAlgo.cxx @@ -108,7 +108,7 @@ namespace thePlane->Update (aContext, anObjAspectFace != NULL ? anObjAspectFace->Aspect() : Handle(Graphic3d_Aspects)()); theWorkspace->SetAspects (thePlane->AspectFace()); theWorkspace->SetRenderFilter (aPrevFilter); - if (!theWorkspace->ShouldRender (&thePlane->Primitives())) + if (!theWorkspace->ShouldRender (&thePlane->Primitives(), aGroupIter.Value())) { continue; } diff --git a/src/OpenGl/OpenGl_Group.cxx b/src/OpenGl/OpenGl_Group.cxx index 9cdd80ac11..b3601bd3f1 100644 --- a/src/OpenGl/OpenGl_Group.cxx +++ b/src/OpenGl/OpenGl_Group.cxx @@ -29,29 +29,6 @@ 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 // purpose : @@ -265,7 +242,7 @@ void OpenGl_Group::AddElement (OpenGl_Element* theElem) (myLast? myLast->next : myFirst) = aNode; myLast = aNode; - if (OpenGl_Raytrace::IsRaytracedElement (aNode)) + if (OpenGl_Raytrace::IsRaytracedElement (aNode) && !HasPersistence()) { myIsRaytracable = Standard_True; @@ -277,6 +254,22 @@ void OpenGl_Group::AddElement (OpenGl_Element* theElem) } } +// ======================================================================= +// function : renderFiltered +// purpose : +// ======================================================================= +bool OpenGl_Group::renderFiltered (const Handle(OpenGl_Workspace)& theWorkspace, + OpenGl_Element* theElement) const +{ + if (!theWorkspace->ShouldRender (theElement, this)) + { + return false; + } + + theElement->Render (theWorkspace); + return true; +} + // ======================================================================= // function : Render // purpose : diff --git a/src/OpenGl/OpenGl_Group.hxx b/src/OpenGl/OpenGl_Group.hxx index cd76dd2399..905567165d 100644 --- a/src/OpenGl/OpenGl_Group.hxx +++ b/src/OpenGl/OpenGl_Group.hxx @@ -52,6 +52,9 @@ public: : Handle(Graphic3d_Aspects)(); } + //! Return TRUE if group contains primitives with transform persistence. + bool HasPersistence() const { return myStructure != NULL && !myStructure->TransformPersistence().IsNull(); } + //! Update aspect. Standard_EXPORT virtual void SetGroupPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect) Standard_OVERRIDE; @@ -106,6 +109,18 @@ protected: Standard_EXPORT virtual ~OpenGl_Group(); +private: + + //! 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 + Standard_EXPORT bool renderFiltered (const Handle(OpenGl_Workspace)& theWorkspace, + OpenGl_Element* theElement) const; + protected: OpenGl_Aspects* myAspects; diff --git a/src/OpenGl/OpenGl_SceneGeometry.cxx b/src/OpenGl/OpenGl_SceneGeometry.cxx index b13e16727c..5b3113b255 100644 --- a/src/OpenGl/OpenGl_SceneGeometry.cxx +++ b/src/OpenGl/OpenGl_SceneGeometry.cxx @@ -557,6 +557,11 @@ namespace OpenGl_Raytrace // ======================================================================= Standard_Boolean IsRaytracedGroup (const OpenGl_Group* theGroup) { + if (theGroup->HasPersistence()) + { + return Standard_False; + } + for (const OpenGl_ElementNode* aNode = theGroup->FirstNode(); aNode != NULL; aNode = aNode->next) { if (IsRaytracedElement (aNode)) diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index b7533c16ff..b49bced5ba 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -162,6 +162,10 @@ void OpenGl_Structure::SetTransformation (const Handle(TopLoc_Datum3D)& theTrsf) // ======================================================================= void OpenGl_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) { + if ((myTrsfPers.IsNull() || theTrsfPers.IsNull()) && myTrsfPers != theTrsfPers) + { + ++myModificationState; + } myTrsfPers = theTrsfPers; updateLayerTransformation(); } @@ -226,7 +230,8 @@ void OpenGl_Structure::OnVisibilityChanged() Standard_Boolean OpenGl_Structure::IsRaytracable() const { if (!myGroups.IsEmpty() - && myIsRaytracable) + && myIsRaytracable + && myTrsfPers.IsNull()) { return Standard_True; } diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index 56170b4fc5..d720ec2451 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -398,12 +398,13 @@ Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& // function : ShouldRender // purpose : // ======================================================================= -bool OpenGl_Workspace::ShouldRender (const OpenGl_Element* theElement) +bool OpenGl_Workspace::ShouldRender (const OpenGl_Element* theElement, + const OpenGl_Group* theGroup) { // render only non-raytracable elements when RayTracing is enabled if ((myRenderFilter & OpenGl_RenderFilter_NonRaytraceableOnly) != 0) { - if (OpenGl_Raytrace::IsRaytracedElement (theElement)) + if (!theGroup->HasPersistence() && OpenGl_Raytrace::IsRaytracedElement (theElement)) { return false; } diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index 5b1b8ada13..98a79692e5 100644 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -176,8 +176,9 @@ public: //! Checks whether the element can be rendered or not. //! @param theElement [in] the element to check + //! @param theGroup [in] the group containing the element //! @return True if element can be rendered - bool ShouldRender (const OpenGl_Element* theElement); + bool ShouldRender (const OpenGl_Element* theElement, const OpenGl_Group* theGroup); //! Return the number of skipped transparent elements within active OpenGl_RenderFilter_OpaqueOnly filter. //! @sa OpenGl_LayerList::Render() diff --git a/tests/v3d/raytrace/bug27130 b/tests/v3d/raytrace/bug27130 new file mode 100644 index 0000000000..56fd98dcbe --- /dev/null +++ b/tests/v3d/raytrace/bug27130 @@ -0,0 +1,18 @@ +puts "============" +puts "0027130: Visualization, Ray tracing - skip structures with transformation persistence flag" +puts "============" +puts "" + +pload VISUALIZATION MODELING + +vinit View1 +vsetdispmode 1 + +restore [locate_data_file face1.brep] f +vdisplay f +box b1 25 25 25 +vdisplay b1 -trsfPers zoom -trsfPersPos 0 0 0 + +vraytrace 1 +vfit +vdump ${imagedir}/${casename}.png