0027682: Visualization - provide method Prs3d_Drawer::SetShaderProgram() for setting...
authorkgv <kgv@opencascade.com>
Sun, 17 Jul 2016 13:53:43 +0000 (16:53 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 21 Jul 2016 09:47:48 +0000 (12:47 +0300)
AIS_ColoredDrawer has been moved to dedicated file.
AIS_ColoredShape::CustomAspectsMap() - added public method for accessing aspects map.

AIS_InteractiveObject::SynchronizeAspects() - added method for synchronizing
all primitive aspects at low-level (TKOpenGl) after their modification.

src/AIS/AIS_ColoredDrawer.hxx [new file with mode: 0644]
src/AIS/AIS_ColoredShape.cxx
src/AIS/AIS_ColoredShape.hxx
src/AIS/AIS_DataMapOfShapeDrawer.hxx [new file with mode: 0644]
src/AIS/AIS_InteractiveObject.cxx
src/AIS/AIS_InteractiveObject.hxx
src/AIS/FILES
src/Prs3d/Prs3d_Drawer.cxx
src/Prs3d/Prs3d_Drawer.hxx
src/ViewerTest/ViewerTest_OpenGlCommands.cxx

diff --git a/src/AIS/AIS_ColoredDrawer.hxx b/src/AIS/AIS_ColoredDrawer.hxx
new file mode 100644 (file)
index 0000000..b80be3f
--- /dev/null
@@ -0,0 +1,54 @@
+// 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 _AIS_ColoredDrawer_HeaderFile
+#define _AIS_ColoredDrawer_HeaderFile
+
+#include <Prs3d_Drawer.hxx>
+#include <Quantity_Color.hxx>
+
+//! Customizable properties.
+class AIS_ColoredDrawer : public Prs3d_Drawer
+{
+  DEFINE_STANDARD_RTTIEXT(AIS_ColoredDrawer, Prs3d_Drawer)
+public:
+
+  //! Default constructor.
+  AIS_ColoredDrawer (const Handle(Prs3d_Drawer)& theLink)
+  : myIsHidden    (false),
+    myHasOwnColor (false),
+    myHasOwnWidth (false)
+  {
+    Link (theLink);
+  }
+
+  bool IsHidden() const                                 { return myIsHidden;     }
+  void SetHidden (const bool theToHide)                 { myIsHidden = theToHide;}
+  bool HasOwnColor() const                              { return myHasOwnColor;  }
+  void UnsetOwnColor()                                  { myHasOwnColor = false; }
+  void SetOwnColor (const Quantity_Color& /*theColor*/) { myHasOwnColor = true;  }
+  bool HasOwnWidth() const                              { return myHasOwnWidth;  }
+  void UnsetOwnWidth()                                  { myHasOwnWidth = false; }
+  void SetOwnWidth (const Standard_Real /*theWidth*/)   { myHasOwnWidth = true;  }
+
+public:  //! @name list of overridden properties
+
+  bool myIsHidden;
+  bool myHasOwnColor;
+  bool myHasOwnWidth;
+
+};
+
+DEFINE_STANDARD_HANDLE(AIS_ColoredDrawer, Prs3d_Drawer)
+
+#endif // _AIS_ColoredDrawer_HeaderFile
index 6a639f9..e8f20dd 100644 (file)
@@ -195,7 +195,7 @@ void AIS_ColoredShape::SetColor (const Quantity_Color&  theColor)
   hasOwnColor = Standard_True;
   LoadRecomputable (AIS_WireFrame);
   LoadRecomputable (AIS_Shaded);
-  for (DataMapOfShapeColor::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
+  for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
   {
     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
     if (aDrawer->HasOwnColor())
@@ -229,7 +229,7 @@ void AIS_ColoredShape::SetWidth (const Standard_Real    theLineWidth)
   myOwnWidth = theLineWidth;
   LoadRecomputable (AIS_WireFrame);
   LoadRecomputable (AIS_Shaded);
-  for (DataMapOfShapeColor::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
+  for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
   {
     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
     if (aDrawer->HasOwnWidth())
@@ -259,7 +259,7 @@ void AIS_ColoredShape::SetTransparency (const Standard_Real theValue)
   myTransparency = theValue;
   LoadRecomputable (AIS_WireFrame);
   LoadRecomputable (AIS_Shaded);
-  for (DataMapOfShapeColor::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
+  for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
   {
     const Handle(Prs3d_Drawer)& aDrawer = anIter.Value();
     if (aDrawer->HasOwnShadingAspect())
@@ -280,7 +280,7 @@ void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
   //myOwnMaterial = theMaterial;
   hasOwnMaterial = Standard_True;
   LoadRecomputable (AIS_Shaded);
-  for (DataMapOfShapeColor::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
+  for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
   {
     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
     //if (aDrawer->HasOwnMaterial()) continue;
@@ -524,16 +524,16 @@ inline Standard_Boolean isFirstCmpContainSecondOne (const TopoDS_Shape& theFirst
 //function : dispatchColors
 //purpose  :
 //=======================================================================
-void AIS_ColoredShape::dispatchColors (const TopoDS_Shape&        theBaseShape,
-                                       const DataMapOfShapeColor& theKeyshapeColorMap,
-                                       DataMapOfShapeCompd*       theTypeKeyshapeDrawshapeArray)
+void AIS_ColoredShape::dispatchColors (const TopoDS_Shape&  theBaseShape,
+                                       const AIS_DataMapOfShapeDrawer& theKeyshapeColorMap,
+                                       DataMapOfShapeCompd* theTypeKeyshapeDrawshapeArray)
 {
   // Extract <theShapeColors> map (KeyshapeColored -> Color)
   // to subshapes map (Subshape -> KeyshapeColored).
   // This needed when colored shape is not part of <theBaseShape>
   // (but subshapes are) and actually container for subshapes.
   DataMapOfShapeShape aSubshapeKeyshapeMap;
-  for (DataMapOfShapeColor::Iterator aKeyShapeIter (theKeyshapeColorMap);
+  for (AIS_DataMapOfShapeDrawer::Iterator aKeyShapeIter (theKeyshapeColorMap);
        aKeyShapeIter.More(); aKeyShapeIter.Next())
   {
     const TopoDS_Shape& aKeyShape = aKeyShapeIter.Key();
@@ -575,7 +575,7 @@ Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible (DataMapOfShapeCompd*
 //=======================================================================
 Standard_Boolean AIS_ColoredShape::isShapeEntirelyVisible() const
 {
-  for (DataMapOfShapeColor::Iterator aMapIter (myShapeColors); aMapIter.More(); aMapIter.Next())
+  for (AIS_DataMapOfShapeDrawer::Iterator aMapIter (myShapeColors); aMapIter.More(); aMapIter.Next())
   {
     if (aMapIter.Value()->IsHidden())
     {
index af37a86..8ebbc56 100644 (file)
 #ifndef _AIS_ColoredShape_HeaderFile
 #define _AIS_ColoredShape_HeaderFile
 
-#include <Prs3d_Drawer.hxx>
+#include <AIS_DataMapOfShapeDrawer.hxx>
 #include <AIS_Shape.hxx>
-
-#include <NCollection_DataMap.hxx>
 #include <NCollection_IndexedDataMap.hxx>
-#include <TopTools_ShapeMapHasher.hxx>
-#include <TopoDS_Compound.hxx>
 #include <StdPrs_Volume.hxx>
-
-//! Customizable properties.
-class AIS_ColoredDrawer : public Prs3d_Drawer
-{
-public:
-
-  AIS_ColoredDrawer (const Handle(Prs3d_Drawer)& theLink)
-  : myIsHidden    (Standard_False),
-    myHasOwnColor (Standard_False),
-    myHasOwnWidth (Standard_False)
-  {
-    Link (theLink);
-  }
-
-  Standard_Boolean IsHidden()    const                              { return myIsHidden; }
-  void             SetHidden (const Standard_Boolean theToHide)     { myIsHidden = theToHide;  }
-  Standard_Boolean HasOwnColor() const                              { return myHasOwnColor; }
-  void             UnsetOwnColor()                                  { myHasOwnColor = Standard_False; }
-  void             SetOwnColor (const Quantity_Color& /*theColor*/) { myHasOwnColor = Standard_True;  }
-  Standard_Boolean HasOwnWidth() const                              { return myHasOwnWidth; }
-  void             UnsetOwnWidth()                                  { myHasOwnWidth = Standard_False; }
-  void             SetOwnWidth (const Standard_Real /*theWidth*/)   { myHasOwnWidth = Standard_True;  }
-
-public:  //! @name list of overridden properties
-
-  Standard_Boolean myIsHidden;
-  Standard_Boolean myHasOwnColor;
-  Standard_Boolean myHasOwnWidth;
-
-public:
-  DEFINE_STANDARD_RTTIEXT(AIS_ColoredDrawer,Prs3d_Drawer)
-
-};
-
-DEFINE_STANDARD_HANDLE(AIS_ColoredDrawer, Prs3d_Drawer)
+#include <TopoDS_Compound.hxx>
 
 //! Presentation of the shape with customizable sub-shapes properties.
 class AIS_ColoredShape : public AIS_Shape
@@ -94,6 +56,12 @@ public: //! @name sub-shape aspects
   Standard_EXPORT void SetCustomWidth (const TopoDS_Shape& theShape,
                                        const Standard_Real theLineWidth);
 
+  //! Return the map of custom aspects.
+  const AIS_DataMapOfShapeDrawer& CustomAspectsMap() const { return myShapeColors; }
+
+  //! Return the map of custom aspects.
+  AIS_DataMapOfShapeDrawer& ChangeCustomAspectsMap() { return myShapeColors; }
+
 public: //! @name global aspects
 
   //! Setup color of entire shape.
@@ -116,9 +84,8 @@ protected: //! @name override presentation computation
 
 protected:
 
-  typedef NCollection_DataMap<TopoDS_Shape, Handle(AIS_ColoredDrawer), TopTools_ShapeMapHasher> DataMapOfShapeColor;
-  typedef NCollection_DataMap<TopoDS_Shape, TopoDS_Shape,              TopTools_ShapeMapHasher> DataMapOfShapeShape;
-  typedef NCollection_IndexedDataMap<TopoDS_Shape, TopoDS_Compound,    TopTools_ShapeMapHasher> DataMapOfShapeCompd;
+  typedef NCollection_DataMap<TopoDS_Shape, TopoDS_Shape,           TopTools_ShapeMapHasher> DataMapOfShapeShape;
+  typedef NCollection_IndexedDataMap<TopoDS_Shape, TopoDS_Compound, TopTools_ShapeMapHasher> DataMapOfShapeCompd;
 
 protected:
 
@@ -134,9 +101,9 @@ protected:
                                                           const TopAbs_ShapeEnum     theParentType,
                                                           DataMapOfShapeCompd*       theTypeKeyshapeDrawshapeArray);
 
-  Standard_EXPORT static void dispatchColors (const TopoDS_Shape&        theBaseShape,
-                                              const DataMapOfShapeColor& theKeyshapeColorMap,
-                                              DataMapOfShapeCompd*       theTypeKeyshapeDrawshapeArray);
+  Standard_EXPORT static void dispatchColors (const TopoDS_Shape&             theBaseShape,
+                                              const AIS_DataMapOfShapeDrawer& theKeyshapeColorMap,
+                                              DataMapOfShapeCompd*            theTypeKeyshapeDrawshapeArray);
 
 protected:
 
@@ -171,7 +138,7 @@ protected:
 
 protected:
 
-  DataMapOfShapeColor myShapeColors;
+  AIS_DataMapOfShapeDrawer myShapeColors;
 
 public:
 
diff --git a/src/AIS/AIS_DataMapOfShapeDrawer.hxx b/src/AIS/AIS_DataMapOfShapeDrawer.hxx
new file mode 100644 (file)
index 0000000..ffa340e
--- /dev/null
@@ -0,0 +1,24 @@
+// 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 _AIS_DataMapOfShapeDrawer_HeaderFile
+#define _AIS_DataMapOfShapeDrawer_HeaderFile
+
+#include <AIS_ColoredDrawer.hxx>
+#include <NCollection_DataMap.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+
+typedef NCollection_DataMap<TopoDS_Shape, Handle(AIS_ColoredDrawer), TopTools_ShapeMapHasher> AIS_DataMapOfShapeDrawer;
+
+#endif // _AIS_DataMapOfShapeDrawer_HeaderFile
index d58f159..80e93b6 100644 (file)
@@ -671,3 +671,50 @@ void AIS_InteractiveObject::SetIsoOnTriangulation (const Standard_Boolean theIsE
 {
   myDrawer->SetIsoOnTriangulation (theIsEnabled);
 }
+
+//=======================================================================
+//function : SynchronizeAspects
+//purpose  :
+//=======================================================================
+void AIS_InteractiveObject::SynchronizeAspects()
+{
+  for (PrsMgr_Presentations::Iterator aPrsIter (myPresentations); aPrsIter.More(); aPrsIter.Next())
+  {
+    const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue().Presentation();
+    if (aPrs3d.IsNull()
+     || aPrs3d->Presentation().IsNull())
+    {
+      continue;
+    }
+
+    for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPrs3d->Presentation()->Groups()); aGroupIter.More(); aGroupIter.Next())
+    {
+      Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
+      if (aGrp.IsNull())
+      {
+        continue;
+      }
+
+      Handle(Graphic3d_AspectLine3d)     aLineAspect   = aGrp->LineAspect();
+      Handle(Graphic3d_AspectFillArea3d) aFaceAspect   = aGrp->FillAreaAspect();
+      Handle(Graphic3d_AspectMarker3d)   aMarkerAspect = aGrp->MarkerAspect();
+      Handle(Graphic3d_AspectText3d)     aTextAspect   = aGrp->TextAspect();
+      if (!aLineAspect.IsNull())
+      {
+        aGrp->SetGroupPrimitivesAspect (aLineAspect);
+      }
+      if (!aFaceAspect.IsNull())
+      {
+        aGrp->SetGroupPrimitivesAspect (aFaceAspect);
+      }
+      if (!aMarkerAspect.IsNull())
+      {
+        aGrp->SetGroupPrimitivesAspect (aMarkerAspect);
+      }
+      if (!aTextAspect.IsNull())
+      {
+        aGrp->SetGroupPrimitivesAspect (aTextAspect);
+      }
+    }
+  }
+}
index 5c2012c..d7a08e2 100644 (file)
@@ -453,6 +453,12 @@ public:
   //! Enables or disables on-triangulation build of isolines according to the flag given.
   Standard_EXPORT void SetIsoOnTriangulation (const Standard_Boolean theIsEnabled);
 
+  //! Synchronize presentation aspects after their modification.
+  //!
+  //! This method should be called after modifying primitive aspect properties (material, texture, shader)
+  //! so that modifications will take effect on already computed presentation groups (thus avoiding re-displaying the object).
+  Standard_EXPORT void SynchronizeAspects();
+
 friend class AIS_InteractiveContext;
 
 
index 70d284b..9a4bae7 100644 (file)
@@ -22,8 +22,10 @@ AIS_Circle.cxx
 AIS_Circle.hxx
 AIS_Circle.lxx
 AIS_ClearMode.hxx
+AIS_ColoredDrawer.hxx
 AIS_ColoredShape.cxx
 AIS_ColoredShape.hxx
+AIS_DataMapOfShapeDrawer.hxx
 AIS_ColorScale.cxx
 AIS_ColorScale.hxx
 AIS_ConcentricRelation.cxx
index 374e32d..325b226 100644 (file)
 // commercial license or contractual agreement.
 
 #include <Prs3d_Drawer.hxx>
+
+#include <Graphic3d_AspectFillArea3d.hxx>
+#include <Graphic3d_AspectMarker3d.hxx>
+#include <Graphic3d_AspectText3d.hxx>
 #include <Prs3d_ArrowAspect.hxx>
 #include <Prs3d_DatumAspect.hxx>
 #include <Prs3d_DimensionAspect.hxx>
@@ -23,7 +27,6 @@
 #include <Prs3d_ShadingAspect.hxx>
 #include <Prs3d_TextAspect.hxx>
 
-
 IMPLEMENT_STANDARD_RTTIEXT(Prs3d_Drawer,MMgt_TShared)
 
 // =======================================================================
@@ -1069,3 +1072,185 @@ void Prs3d_Drawer::ClearLocalAttributes()
   myVertexDrawMode = Prs3d_VDM_Inherited;
   myTypeOfHLR      = Prs3d_TOH_NotSet;
 }
+
+//! Copy line aspect defaults from the Link.
+inline void copyLineAspect (const Handle(Prs3d_Drawer)&     theLink,
+                            Handle(Prs3d_LineAspect)&       theAspect,
+                            const Handle(Prs3d_LineAspect)& theBaseAspect)
+{
+  Handle(Prs3d_LineAspect) aBaseAspect = theBaseAspect;
+  if (!theLink.IsNull())
+  {
+    theAspect = new Prs3d_LineAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0);
+    *theAspect->Aspect() = *aBaseAspect->Aspect();
+  }
+}
+
+//! Assign the shader program.
+template <typename T>
+inline void setAspectProgram (const Handle(Graphic3d_ShaderProgram)& theProgram,
+                              T thePrsAspect)
+{
+  if (!thePrsAspect.IsNull())
+  {
+    thePrsAspect->Aspect()->SetShaderProgram (theProgram);
+  }
+}
+
+// =======================================================================
+// function : SetShaderProgram
+// purpose  :
+// =======================================================================
+void Prs3d_Drawer::SetShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProgram,
+                                     const Graphic3d_GroupAspect            theAspect,
+                                     const bool                             theToOverrideDefaults)
+{
+  switch (theAspect)
+  {
+    case Graphic3d_ASPECT_LINE:
+    {
+      if (theToOverrideDefaults)
+      {
+        if (myUIsoAspect.IsNull())
+        {
+          Handle(Prs3d_IsoAspect) anAspect = UIsoAspect();
+          if (!myLink.IsNull())
+          {
+            myUIsoAspect = new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 1.0, 1);
+            *myUIsoAspect->Aspect() = *anAspect->Aspect();
+            myUIsoAspect->SetNumber (anAspect->Number());
+          }
+        }
+        if (myVIsoAspect.IsNull())
+        {
+          Handle(Prs3d_IsoAspect) anAspect = VIsoAspect();
+          if (!myLink.IsNull())
+          {
+            myVIsoAspect = new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 1.0, 1);
+            *myVIsoAspect->Aspect() = *anAspect->Aspect();
+            myUIsoAspect->SetNumber (anAspect->Number());
+          }
+        }
+        if (myWireAspect.IsNull())
+        {
+          copyLineAspect (myLink, myWireAspect, WireAspect());
+        }
+        if (myLineAspect.IsNull())
+        {
+          copyLineAspect (myLink, myLineAspect, LineAspect());
+        }
+        if (mySeenLineAspect.IsNull())
+        {
+          copyLineAspect (myLink, mySeenLineAspect, SeenLineAspect());
+        }
+        if (myHiddenLineAspect.IsNull())
+        {
+          copyLineAspect (myLink, myHiddenLineAspect, HiddenLineAspect());
+        }
+        if (myVectorAspect.IsNull())
+        {
+          copyLineAspect (myLink, myVectorAspect, VectorAspect());
+        }
+        if (mySectionAspect.IsNull())
+        {
+          copyLineAspect (myLink, mySectionAspect, SectionAspect());
+        }
+        if (myFreeBoundaryAspect.IsNull())
+        {
+          copyLineAspect (myLink, myFreeBoundaryAspect, FreeBoundaryAspect());
+        }
+        if (myUnFreeBoundaryAspect.IsNull())
+        {
+          copyLineAspect (myLink, myUnFreeBoundaryAspect, UnFreeBoundaryAspect());
+        }
+        if (myFaceBoundaryAspect.IsNull())
+        {
+          copyLineAspect (myLink, myFaceBoundaryAspect, FaceBoundaryAspect());
+        }
+
+        if (myPlaneAspect.IsNull())
+        {
+          myPlaneAspect = new Prs3d_PlaneAspect();
+        }
+        if (myArrowAspect.IsNull())
+        {
+          myArrowAspect = new Prs3d_ArrowAspect();
+        }
+        if (myDatumAspect.IsNull())
+        {
+          myDatumAspect = new Prs3d_DatumAspect();
+        }
+      }
+
+      setAspectProgram (theProgram, myUIsoAspect);
+      setAspectProgram (theProgram, myVIsoAspect);
+      setAspectProgram (theProgram, myWireAspect);
+      setAspectProgram (theProgram, myLineAspect);
+      setAspectProgram (theProgram, mySeenLineAspect);
+      setAspectProgram (theProgram, myHiddenLineAspect);
+      setAspectProgram (theProgram, myVectorAspect);
+      setAspectProgram (theProgram, mySectionAspect);
+      setAspectProgram (theProgram, myFreeBoundaryAspect);
+      setAspectProgram (theProgram, myUnFreeBoundaryAspect);
+      setAspectProgram (theProgram, myFaceBoundaryAspect);
+      if (!myPlaneAspect.IsNull())
+      {
+        setAspectProgram (theProgram, myPlaneAspect->EdgesAspect());
+        setAspectProgram (theProgram, myPlaneAspect->IsoAspect());
+        setAspectProgram (theProgram, myPlaneAspect->ArrowAspect());
+      }
+      if (!myDatumAspect.IsNull())
+      {
+        setAspectProgram (theProgram, myDatumAspect->FirstAxisAspect());
+        setAspectProgram (theProgram, myDatumAspect->SecondAxisAspect());
+        setAspectProgram (theProgram, myDatumAspect->ThirdAxisAspect());
+      }
+      setAspectProgram (theProgram, myArrowAspect);
+      return;
+    }
+    case Graphic3d_ASPECT_TEXT:
+    {
+      if (theToOverrideDefaults
+       && myTextAspect.IsNull())
+      {
+        myTextAspect = new Prs3d_TextAspect();
+        if (!myLink.IsNull())
+        {
+          *myTextAspect->Aspect() = *myLink->TextAspect()->Aspect();
+        }
+      }
+
+      setAspectProgram (theProgram, myTextAspect);
+      return;
+    }
+    case Graphic3d_ASPECT_MARKER:
+    {
+      if (theToOverrideDefaults
+       && myPointAspect.IsNull())
+      {
+        myPointAspect = new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_YELLOW, 1.0);
+        if (!myLink.IsNull())
+        {
+          *myPointAspect->Aspect() = *myLink->PointAspect()->Aspect();
+        }
+      }
+
+      setAspectProgram (theProgram, myPointAspect);
+      return;
+    }
+    case Graphic3d_ASPECT_FILL_AREA:
+    {
+      if (myShadingAspect.IsNull()
+       && theToOverrideDefaults)
+      {
+        myShadingAspect = new Prs3d_ShadingAspect();
+        if (!myLink.IsNull())
+        {
+          *myShadingAspect->Aspect() = *myLink->ShadingAspect()->Aspect();
+        }
+      }
+      setAspectProgram (theProgram, myShadingAspect);
+      return;
+    }
+  }
+}
index a114f12..2126e1d 100644 (file)
@@ -22,6 +22,8 @@
 #include <Standard_Boolean.hxx>
 #include <Quantity_Length.hxx>
 #include <Aspect_TypeOfDeflection.hxx>
+#include <Graphic3d_GroupAspect.hxx>
+#include <Graphic3d_ShaderProgram.hxx>
 #include <Standard_Real.hxx>
 #include <Prs3d_VertexDrawMode.hxx>
 #include <Prs3d_DimensionUnits.hxx>
@@ -854,6 +856,15 @@ public:
   //! Removes local attributes. 
   Standard_EXPORT void ClearLocalAttributes();
 
+  //! Assign shader program for specified type of primitives.
+  //! @param theProgram new program to set (might be NULL)
+  //! @param theAspect  the type of primitives
+  //! @param theToOverrideDefaults if true then non-overridden attributes using defaults will be allocated and copied from the Link;
+  //!                              otherwise, only already customized attributes will be changed
+  Standard_EXPORT void SetShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProgram,
+                                         const Graphic3d_GroupAspect            theAspect,
+                                         const bool                             theToOverrideDefaults = false);
+
 protected:
 
   Handle(Prs3d_Drawer)          myLink;
index f11ef39..51d3911 100644 (file)
@@ -554,11 +554,24 @@ static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
           anIter.More(); anIter.Next())
     {
       anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
-      if (!anIO.IsNull())
+      if (anIO.IsNull())
       {
-        anIO->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
+        continue;
+      }
+
+      if (!anIO->Attributes()->HasOwnShadingAspect())
+      {
+        Handle(Prs3d_ShadingAspect) aNewAspect = new Prs3d_ShadingAspect();
+        *aNewAspect->Aspect() = *anIO->Attributes()->ShadingAspect()->Aspect();
+        aNewAspect->Aspect()->SetShaderProgram (aProgram);
+        anIO->Attributes()->SetShadingAspect (aNewAspect);
         aCtx->Redisplay (anIO, Standard_False);
       }
+      else
+      {
+        anIO->Attributes()->SetShaderProgram (aProgram, Graphic3d_ASPECT_FILL_AREA);
+        anIO->SynchronizeAspects();
+      }
     }
     aCtx->UpdateCurrentViewer();
     return 0;
@@ -578,8 +591,20 @@ static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
       std::cerr << "Warning: " << aName.ToCString() << " is not an AIS object\n";
       continue;
     }
-    anIO->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
-    aCtx->Redisplay (anIO, Standard_False);
+
+    if (!anIO->Attributes()->HasOwnShadingAspect())
+    {
+      Handle(Prs3d_ShadingAspect) aNewAspect = new Prs3d_ShadingAspect();
+      *aNewAspect->Aspect() = *anIO->Attributes()->ShadingAspect()->Aspect();
+      aNewAspect->Aspect()->SetShaderProgram (aProgram);
+      anIO->Attributes()->SetShadingAspect (aNewAspect);
+      aCtx->Redisplay (anIO, Standard_False);
+    }
+    else
+    {
+      anIO->Attributes()->SetShaderProgram (aProgram, Graphic3d_ASPECT_FILL_AREA);
+      anIO->SynchronizeAspects();
+    }
   }
 
   aCtx->UpdateCurrentViewer();