0027555: Visualization, AIS_Shape - own deviation coefficient change is not considere...
[occt.git] / src / AIS / AIS_Shape.cxx
index a569bfe..c536640 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <AIS_Shape.ixx>
 
-
-#include <Standard_ErrorHandler.hxx>
-#include <OSD_Timer.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-
-#include <Quantity_Color.hxx>
-
-#include <gp_Pnt.hxx>
+#include <AIS_GraphicTool.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_Shape.hxx>
+#include <Aspect_TypeOfLine.hxx>
 #include <Bnd_Box.hxx>
 #include <BRep_Builder.hxx>
-#include <BRepTools_ShapeSet.hxx>
-#include <BRepTools.hxx>
 #include <BRepBndLib.hxx>
-#include <TopExp.hxx>
-#include <TopExp_Explorer.hxx>
-
-#include <Aspect_TypeOfLine.hxx>
-#include <Graphic3d_Structure.hxx>
-#include <Graphic3d_Group.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_ShapeSet.hxx>
+#include <Geom_Transformation.hxx>
+#include <gp_Pnt.hxx>
+#include <Graphic3d_ArrayOfPolylines.hxx>
+#include <Graphic3d_AspectFillArea3d.hxx>
 #include <Graphic3d_AspectLine3d.hxx>
-#include <Graphic3d_AspectText3d.hxx>
 #include <Graphic3d_AspectMarker3d.hxx>
-#include <Graphic3d_AspectFillArea3d.hxx>
-#include <Graphic3d_ArrayOfPolylines.hxx>
+#include <Graphic3d_AspectText3d.hxx>
+#include <Graphic3d_Group.hxx>
 #include <Graphic3d_MaterialAspect.hxx>
-
+#include <Graphic3d_SequenceOfGroup.hxx>
+#include <Graphic3d_Structure.hxx>
+#include <HLRBRep.hxx>
+#include <OSD_Timer.hxx>
+#include <Precision.hxx>
+#include <Prs3d.hxx>
+#include <Prs3d_Drawer.hxx>
+#include <Prs3d_IsoAspect.hxx>
 #include <Prs3d_Presentation.hxx>
+#include <Prs3d_Projector.hxx>
 #include <Prs3d_Root.hxx>
 #include <Prs3d_ShadingAspect.hxx>
-#include <Prs3d_Drawer.hxx>
-#include <Prs3d_IsoAspect.hxx>
-
-#include <StdPrs_WFShape.hxx>
-#include <StdPrs_WFDeflectionShape.hxx>
-#include <StdPrs_ShadedShape.hxx>
-#include <StdPrs_HLRShape.hxx>
-#include <StdPrs_HLRPolyShape.hxx>
-
+#include <StdPrs_BndBox.hxx>
+#include <StdPrs_ToolTriangulatedShape.hxx>
 #include <PrsMgr_ModedPresentation.hxx>
-
+#include <Quantity_Color.hxx>
+#include <Select3D_SensitiveBox.hxx>
 #include <Select3D_SensitiveEntity.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+#include <Standard_Type.hxx>
+#include <StdPrs_HLRPolyShape.hxx>
+#include <StdPrs_HLRShape.hxx>
+#include <StdPrs_ShadedShape.hxx>
+#include <StdPrs_WFShape.hxx>
 #include <StdSelect.hxx>
-#include <StdSelect_BRepSelectionTool.hxx>
 #include <StdSelect_BRepOwner.hxx>
+#include <StdSelect_BRepSelectionTool.hxx>
 #include <StdSelect_DisplayMode.hxx>
-
-#include <AIS_GraphicTool.hxx>
-#include <AIS_InteractiveContext.hxx>
-#include <AIS_Drawer.hxx>
-#include <HLRBRep.hxx>
-#include <Precision.hxx>
-
-#include <Standard_Failure.hxx>
-#include <Standard_ErrorHandler.hxx>
-#include <Select3D_SensitiveBox.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
 
-static Standard_Boolean myFirstCompute;
-
-Standard_Real AIS_Shape::GetDeflection(const TopoDS_Shape& aShape,
-                                       const Handle(Prs3d_Drawer)& aDrawer)
-{
-  // WARNING: this same piece of code appears several times in Prs3d classes
-  Standard_Real aDeflection = aDrawer->MaximalChordialDeviation();
-  if (aDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE) {
-    Bnd_Box B;
-    BRepBndLib::Add(aShape, B, Standard_False);
-    if ( ! B.IsVoid() )
-    {
-      Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
-      B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
-      aDeflection = Max( aXmax-aXmin, Max(aYmax-aYmin, aZmax-aZmin)) *
-                    aDrawer->DeviationCoefficient() * 4;
-    }
-  }
-  return aDeflection;
-}
-
-void AIS_Shape::DisplayBox(const Handle(Prs3d_Presentation)& aPrs,
-                           const Bnd_Box& B,
-                           const Handle(Prs3d_Drawer)& aDrawer)
-{
-  static const Standard_Integer Indx[][3] =
-  { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 }, { 0, 0, 1 },
-    { 0, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0 }, { 0, 1, 0 },
-    { 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 },
-    { 0, 1, 1 }, { 0, 1, 0 }, { 1, 1, 0 }, { 1, 0, 0 } };
-
-  if ( B.IsVoid() )
-    return; // nothing to show
-
-  Standard_Real X[2],Y[2],Z[2];
-  B.Get(X[0], Y[0], Z[0], X[1], Y[1], Z[1]);
-
-  Handle(Graphic3d_Group) G = Prs3d_Root::CurrentGroup(aPrs);
-  Quantity_Color Q;
-  Aspect_TypeOfLine A;
-  Standard_Real W;
-  aDrawer->LineAspect()->Aspect()->Values(Q,A,W);
-
-  G->SetGroupPrimitivesAspect(new Graphic3d_AspectLine3d(Q,Aspect_TOL_DOTDASH,W));
-
-  Handle(Graphic3d_ArrayOfPolylines) aPolyline = new Graphic3d_ArrayOfPolylines(16);
-  Standard_Integer i(0);
-  for(;i<16;i++)
-    aPolyline->AddVertex(X[Indx[i][0]],Y[Indx[i][1]],Z[Indx[i][2]]);
-  G->AddPrimitiveArray(aPolyline);
-}
+IMPLEMENT_STANDARD_RTTIEXT(AIS_Shape,AIS_InteractiveObject)
 
 static Standard_Boolean IsInList(const TColStd_ListOfInteger& LL, const Standard_Integer aMode)
 {
@@ -142,11 +87,9 @@ static Standard_Boolean IsInList(const TColStd_ListOfInteger& LL, const Standard
 AIS_Shape::
 AIS_Shape(const TopoDS_Shape& shap):
 AIS_InteractiveObject(PrsMgr_TOP_ProjectorDependant),
-myshape(shap),
-myCompBB(Standard_True),
 myInitAng(0.)
 {
-  myFirstCompute = Standard_True;
+  Set (shap);
   SetHilightMode(0);
   myDrawer->SetShadingAspectGlobal(Standard_False);
 }
@@ -179,7 +122,7 @@ Standard_Boolean AIS_Shape::AcceptShapeDecomposition() const
 //=======================================================================
 void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
                         const Handle(Prs3d_Presentation)& aPrs,
-                        const Standard_Integer aMode)
+                        const Standard_Integer theMode)
 {  
   aPrs->Clear();
   if(myshape.IsNull()) return;
@@ -199,74 +142,86 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat
     }
   }
 
-  if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //not taken in account duting FITALL
-  switch (aMode) {
-  case 0:{
-    try { OCC_CATCH_SIGNALS  StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); }
-    catch (Standard_Failure) { 
-#ifdef DEB
-      cout << "AIS_Shape::Compute()  failed"<< endl;
-#endif
-      cout << "a Shape should be incorrect : No Compute can be maked on it  "<< endl;     
-// presentation of the bounding box is calculated
-//      Compute(aPresentationManager,aPrs,2);
-    }
-    break;
+  if (IsInfinite())
+  {
+    aPrs->SetInfiniteState (Standard_True); //not taken in account during FITALL
   }
-  case 1:
+
+  switch (theMode)
+  {
+    case AIS_WireFrame:
     {
-      Standard_Real prevangle ;
-      Standard_Real newangle  ; 
-      Standard_Real prevcoeff ;
-      Standard_Real newcoeff  ; 
-      
-      Standard_Boolean isOwnDeviationAngle = OwnDeviationAngle(newangle,prevangle);
-      Standard_Boolean isOwnDeviationCoefficient = OwnDeviationCoefficient(newcoeff,prevcoeff);
-      if (((Abs (newangle - prevangle) > Precision::Angular()) && isOwnDeviationAngle) ||
-          ((Abs (newcoeff - prevcoeff) > Precision::Confusion()) && isOwnDeviationCoefficient)) { 
-#ifdef DEB
-        cout << "AIS_Shape : compute"<<endl;
-        cout << "newangl   : " << newangle << " # de " << "prevangl  : " << prevangle << " OU "<<endl;
-        cout << "newcoeff  : " << newcoeff << " # de " << "prevcoeff : " << prevcoeff << endl;
-#endif
-        BRepTools::Clean(myshape);
+      StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
+      try
+      {
+        OCC_CATCH_SIGNALS
+        StdPrs_WFShape::Add (aPrs, myshape, myDrawer);
+      }
+      catch (Standard_Failure)
+      {
+      #ifdef OCCT_DEBUG
+        cout << "AIS_Shape::Compute() failed" << endl;
+        cout << "a Shape should be incorrect : No Compute can be maked on it " << endl;
+      #endif
+        // presentation of the bounding box is calculated
+        //      Compute(aPresentationManager,aPrs,2);
       }
-      
-      //shading only on face...
-      if ((Standard_Integer) myshape.ShapeType()>4)
-        StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
-      else {
-        myDrawer->SetShadingAspectGlobal(Standard_False);
-        if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
-        else {
+      break;
+    }
+    case AIS_Shaded:
+    {
+      StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
+      if ((Standard_Integer) myshape.ShapeType() > 4)
+      {
+        StdPrs_WFShape::Add (aPrs, myshape, myDrawer);
+      }
+      else
+      {
+        myDrawer->SetShadingAspectGlobal (Standard_False);
+        if (IsInfinite())
+        {
+          StdPrs_WFShape::Add (aPrs, myshape, myDrawer);
+        }
+        else
+        {
+          try
           {
-            try {
-              OCC_CATCH_SIGNALS
-              StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer);
-            }
-            catch (Standard_Failure) {
-#ifdef DEB
-              cout << "AIS_Shape::Compute() in ShadingMode failed"<< endl;
-#endif
-              StdPrs_WFShape::Add(aPrs,myshape,myDrawer);
-            }
+            OCC_CATCH_SIGNALS
+            StdPrs_ShadedShape::Add (aPrs, myshape, myDrawer);
+          }
+          catch (Standard_Failure)
+          {
+          #ifdef OCCT_DEBUG
+            cout << "AIS_Shape::Compute() in ShadingMode failed" << endl;
+          #endif
+            StdPrs_WFShape::Add (aPrs, myshape, myDrawer);
           }
         }
       }
-      Standard_Real value = Transparency() ;
-      if( value > 0. ) {
-        SetTransparency( value );
+      Standard_Real aTransparency = Transparency() ;
+      if (aTransparency > 0.0)
+      {
+        SetTransparency (aTransparency);
       }
       break;
     }
-  case 2:
+
+    // Bounding box.
+    case 2:
     {
-      // bounding box
-      if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
-      else DisplayBox(aPrs,BoundingBox(),myDrawer);
+      if (IsInfinite())
+      {
+        StdPrs_WFShape::Add (aPrs, myshape, myDrawer);
+      }
+      else
+      {
+        StdPrs_BndBox::Add (aPrs, BoundingBox(), myDrawer);
+      }
     }
-  } // end switch
-  aPrs->ReCompute(); // for hidden line recomputation if necessary...
+  }
+
+  // Recompute hidden line presentation (if necessary).
+  aPrs->ReCompute();
 }
 
 //=======================================================================
@@ -310,27 +265,25 @@ void AIS_Shape::Compute(const Handle(Prs3d_Projector)& aProjector,
   }
 
   Handle (Prs3d_Drawer) defdrawer = GetContext()->DefaultDrawer();
-  if (defdrawer->DrawHiddenLine()) 
+  if (defdrawer->DrawHiddenLine())
     {myDrawer->EnableDrawHiddenLine();}
   else {myDrawer->DisableDrawHiddenLine();}
 
   Aspect_TypeOfDeflection prevdef = defdrawer->TypeOfDeflection();
   defdrawer->SetTypeOfDeflection(Aspect_TOD_RELATIVE);
 
-// coefficients for calculation
-
-  Standard_Real prevangle, newangle ,prevcoeff,newcoeff ; 
-  Standard_Boolean isOwnHLRDeviationAngle = OwnHLRDeviationAngle(newangle,prevangle);
-  Standard_Boolean isOwnHLRDeviationCoefficient = OwnHLRDeviationCoefficient(newcoeff,prevcoeff);
-  if (((Abs (newangle - prevangle) > Precision::Angular()) && isOwnHLRDeviationAngle) ||
-      ((Abs (newcoeff - prevcoeff) > Precision::Confusion()) && isOwnHLRDeviationCoefficient)) {
-#ifdef DEB
-      cout << "AIS_Shape : compute"<<endl;
-      cout << "newangle  : " << newangle << " # de " << "prevangl  : " << prevangle << " OU "<<endl;
-      cout << "newcoeff  : " << newcoeff << " # de " << "prevcoeff : " << prevcoeff << endl;
-#endif
+  if (myDrawer->IsAutoTriangulation())
+  {
+    // coefficients for calculation
+    Standard_Real aPrevAngle, aNewAngle, aPrevCoeff, aNewCoeff;
+    Standard_Boolean isOwnHLRDeviationAngle = OwnHLRDeviationAngle (aNewAngle, aPrevAngle);
+    Standard_Boolean isOwnHLRDeviationCoefficient = OwnHLRDeviationCoefficient (aNewCoeff, aPrevCoeff);
+    if (((Abs (aNewAngle - aPrevAngle) > Precision::Angular()) && isOwnHLRDeviationAngle) ||
+        ((Abs (aNewCoeff - aPrevCoeff) > Precision::Confusion()) && isOwnHLRDeviationCoefficient))
+    {
       BRepTools::Clean(SH);
     }
+  }
   
   {
     try {
@@ -346,7 +299,7 @@ void AIS_Shape::Compute(const Handle(Prs3d_Projector)& aProjector,
       }
     }
     catch (Standard_Failure) {
-#ifdef DEB
+#ifdef OCCT_DEBUG
       cout <<"AIS_Shape::Compute(Proj) HLR Algorithm failed" << endl;
 #endif
       StdPrs_WFShape::Add(aPresentation,SH,myDrawer);
@@ -432,18 +385,12 @@ void AIS_Shape::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
       return;
   }
 
-  static TopAbs_ShapeEnum TypOfSel;
-  TypOfSel = AIS_Shape::SelectionType(aMode);
+  TopAbs_ShapeEnum TypOfSel = AIS_Shape::SelectionType(aMode);
   TopoDS_Shape shape = myshape;
-  if( HasTransformation() ) {
-    Handle(Geom_Transformation) trsf = Transformation();
-    shape = shape.Located(TopLoc_Location(trsf->Trsf())*shape.Location());
-  }
 
 // POP protection against crash in low layers
 
-  Standard_Real aDeflection = GetDeflection(shape, myDrawer);
-  Standard_Boolean autoTriangulation = Standard_True;
+  Standard_Real aDeflection = Prs3d::GetDeflection(shape, myDrawer);
   try {  
     OCC_CATCH_SIGNALS
     StdSelect_BRepSelectionTool::Load(aSelection,
@@ -452,10 +399,11 @@ void AIS_Shape::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
                                       TypOfSel,
                                       aDeflection,
                                       myDrawer->HLRAngle(),
-                                      autoTriangulation); 
+                                      myDrawer->IsAutoTriangulation());
   } catch ( Standard_Failure ) {
 //    cout << "a Shape should be incorrect : A Selection on the Bnd  is activated   "<<endl;
     if ( aMode == 0 ) {
+      aSelection->Clear();
       Bnd_Box B = BoundingBox();
       Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner(shape,this);
       Handle(Select3D_SensitiveBox) aSensitiveBox = new Select3D_SensitiveBox(aOwner,B);
@@ -496,197 +444,406 @@ void AIS_Shape::SetColor(const Quantity_NameOfColor aCol)
 }
 
 //=======================================================================
-//function : SetColor
-//purpose  : 
+//function : setColor
+//purpose  :
 //=======================================================================
 
-void AIS_Shape::SetColor(const Quantity_Color &aCol)
+void AIS_Shape::setColor (const Handle(Prs3d_Drawer)& theDrawer,
+                          const Quantity_Color&       theColor) const
 {
-  if( !HasColor() && !IsTransparent() && !HasMaterial() ) {
-    myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
+  if (!theDrawer->HasOwnShadingAspect())
+  {
+    theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
+    }
+  }
+  if (!theDrawer->HasOwnLineAspect())
+  {
+    theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
+    }
+  }
+  if (!theDrawer->HasOwnWireAspect())
+  {
+    theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
+    }
+  }
+  if (!theDrawer->HasOwnPointAspect())
+  {
+    theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_BLACK, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
+    }
+  }
+  if (!theDrawer->HasOwnFreeBoundaryAspect())
+  {
+    theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
+    }
+  }
+  if (!theDrawer->HasOwnUnFreeBoundaryAspect())
+  {
+    theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
+    }
+  }
+  if (!theDrawer->HasOwnSeenLineAspect())
+  {
+    theDrawer->SetSeenLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->SeenLineAspect()->Aspect() = *theDrawer->Link()->SeenLineAspect()->Aspect();
+    }
   }
-  hasOwnColor = Standard_True;
 
-  myDrawer->ShadingAspect()->SetColor(aCol,myCurrentFacingModel);
-  myDrawer->ShadingAspect()->SetTransparency(myTransparency,myCurrentFacingModel);
-  myDrawer->SetShadingAspectGlobal(Standard_False);
+  // override color
+  theDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel);
+  theDrawer->SetShadingAspectGlobal (Standard_False);
+  theDrawer->LineAspect()->SetColor (theColor);
+  theDrawer->WireAspect()->SetColor (theColor);
+  theDrawer->PointAspect()->SetColor (theColor);
+  theDrawer->FreeBoundaryAspect()->SetColor (theColor);
+  theDrawer->UnFreeBoundaryAspect()->SetColor (theColor);
+  theDrawer->SeenLineAspect()->SetColor (theColor);
+}
 
+//=======================================================================
+//function : SetColor
+//purpose  :
+//=======================================================================
 
-  const Standard_Real WW = HasWidth()? Width():AIS_GraphicTool::GetLineWidth(myDrawer->Link(),AIS_TOA_Line);
+void AIS_Shape::SetColor (const Quantity_Color& theColor)
+{
+  setColor (myDrawer, theColor);
+  myOwnColor  = theColor;
+  hasOwnColor = Standard_True;
 
-  myDrawer->SetLineAspect(new Prs3d_LineAspect(aCol,Aspect_TOL_SOLID,WW));
-  myDrawer->SetWireAspect(new Prs3d_LineAspect(aCol,Aspect_TOL_SOLID,WW));
-  myDrawer->SetFreeBoundaryAspect(new Prs3d_LineAspect(aCol,Aspect_TOL_SOLID,WW));
-  myDrawer->SetUnFreeBoundaryAspect(new Prs3d_LineAspect(aCol,Aspect_TOL_SOLID,WW));
-  myDrawer->SetSeenLineAspect(new Prs3d_LineAspect(aCol,Aspect_TOL_SOLID,WW));
+  // modify shading presentation without re-computation
+  const PrsMgr_Presentations&        aPrsList     = Presentations();
+  Handle(Graphic3d_AspectFillArea3d) anAreaAspect = myDrawer->ShadingAspect()->Aspect();
+  Handle(Graphic3d_AspectLine3d)     aLineAspect  = myDrawer->LineAspect()->Aspect();
+  Handle(Graphic3d_AspectMarker3d)   aPointAspect = myDrawer->PointAspect()->Aspect();
+  for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
+  {
+    const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
+    if (aPrsModed.Mode() != AIS_Shaded)
+    {
+      continue;
+    }
 
-  // fast shading modification...
-  if(!GetContext().IsNull()){
-    if( GetContext()->MainPrsMgr()->HasPresentation(this,1)){
-      Handle(Prs3d_Presentation) aPresentation = GetContext()->MainPrsMgr()->Presentation (this, 1)->Presentation();
-      Handle(Graphic3d_Group) aCurGroup = Prs3d_Root::CurrentGroup(aPresentation);
-      Handle(Graphic3d_AspectFillArea3d) anAreaAspect = myDrawer->ShadingAspect()->Aspect();
-      Handle(Graphic3d_AspectLine3d) aLineAspect = myDrawer->LineAspect()->Aspect();
+    const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
+
+    // Set aspects for presentation
+    aPrs->SetPrimitivesAspect (anAreaAspect);
+    aPrs->SetPrimitivesAspect (aLineAspect);
+    aPrs->SetPrimitivesAspect (aPointAspect);
+
+    // Go through all groups to change color for all primitives
+    for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
+    {
+      const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
 
-      // Set aspects for presentation and for group
-      aPresentation->SetPrimitivesAspect(anAreaAspect);
-      aPresentation->SetPrimitivesAspect(aLineAspect);
       // Check if aspect of given type is set for the group, 
       // because setting aspect for group with no already set aspect
       // can lead to loss of presentation data
-      if (aCurGroup->IsGroupPrimitivesAspectSet(Graphic3d_ASPECT_FILL_AREA))
-        aCurGroup->SetGroupPrimitivesAspect(anAreaAspect);
-      if (aCurGroup->IsGroupPrimitivesAspectSet(Graphic3d_ASPECT_LINE))
-        aCurGroup->SetGroupPrimitivesAspect(aLineAspect);
+      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
+      {
+        aGroup->SetGroupPrimitivesAspect (anAreaAspect);
+      }
+      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
+      {
+        aGroup->SetGroupPrimitivesAspect (aLineAspect);
+      }
+      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
+      {
+        aGroup->SetGroupPrimitivesAspect (aPointAspect);
+      }
     }
   }
 
-  LoadRecomputable(0);
-  LoadRecomputable(2);
+  LoadRecomputable (AIS_WireFrame);
+  LoadRecomputable (2);
 }
 
 //=======================================================================
 //function : UnsetColor
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void AIS_Shape::UnsetColor()
 {
-  if ( !HasColor() )
+  if (!HasColor())
   {
     myToRecomputeModes.Clear();
     return;
   }
   hasOwnColor = Standard_False;
 
-  Handle(Prs3d_LineAspect) NullAsp;
-  Handle(Prs3d_ShadingAspect) NullShA;
-  
-  if(!HasWidth()) {
-    myDrawer->SetLineAspect(NullAsp);
-    myDrawer->SetWireAspect(NullAsp);
-    myDrawer->SetFreeBoundaryAspect(NullAsp);
-    myDrawer->SetUnFreeBoundaryAspect(NullAsp);
-    myDrawer->SetSeenLineAspect(NullAsp);
+  if (!HasWidth())
+  {
+    Handle(Prs3d_LineAspect) anEmptyAsp;
+    myDrawer->SetLineAspect          (anEmptyAsp);
+    myDrawer->SetWireAspect          (anEmptyAsp);
+    myDrawer->SetFreeBoundaryAspect  (anEmptyAsp);
+    myDrawer->SetUnFreeBoundaryAspect(anEmptyAsp);
+    myDrawer->SetSeenLineAspect      (anEmptyAsp);
   }
-  else {
-    Quantity_Color CC;
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_Line,CC);
-    myDrawer->LineAspect()->SetColor(CC);
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_Wire,CC);
-    myDrawer->WireAspect()->SetColor(CC);
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_Free,CC);
-    myDrawer->FreeBoundaryAspect()->SetColor(CC);
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_UnFree,CC);
-    myDrawer->UnFreeBoundaryAspect()->SetColor(CC);
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_Seen,CC);
-    myDrawer->SeenLineAspect()->SetColor(CC);
+  else
+  {
+    Quantity_Color aColor = Quantity_NOC_YELLOW;
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Line,   aColor);
+    }
+    myDrawer->LineAspect()->SetColor (aColor);
+    aColor = Quantity_NOC_RED;
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Wire,   aColor);
+    }
+    myDrawer->WireAspect()->SetColor (aColor);
+    aColor = Quantity_NOC_GREEN;
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Free,   aColor);
+    }
+    myDrawer->FreeBoundaryAspect()->SetColor (aColor);
+    aColor = Quantity_NOC_YELLOW;
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_UnFree, aColor);
+    }
+    myDrawer->UnFreeBoundaryAspect()->SetColor (aColor);
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Seen,   aColor);
+    }
+    myDrawer->SeenLineAspect()->SetColor (aColor);
   }
 
-  if( HasMaterial() || IsTransparent()) {
-    Graphic3d_MaterialAspect mat = AIS_GraphicTool::GetMaterial(HasMaterial()? myDrawer : myDrawer->Link());
-    if( HasMaterial() ) {
-      Quantity_Color color = myDrawer->Link()->ShadingAspect()->Color(myCurrentFacingModel);
-      mat.SetColor(color);
+  if (HasMaterial()
+   || IsTransparent())
+  {
+    Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
+    Graphic3d_MaterialAspect mat = aDefaultMat;
+    if (HasMaterial() || myDrawer->HasLink())
+    {
+      mat = AIS_GraphicTool::GetMaterial(HasMaterial()? myDrawer : myDrawer->Link());
     }
-    if( IsTransparent() ) {
-      Standard_Real trans = myDrawer->ShadingAspect()->Transparency(myCurrentFacingModel);
-      mat.SetTransparency(trans);
+    if (HasMaterial())
+    {
+      Quantity_Color aColor = aDefaultMat.AmbientColor();
+      if (myDrawer->HasLink())
+      {
+        aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
+      }
+      mat.SetColor (aColor);
     }
-    myDrawer->ShadingAspect()->SetMaterial(mat,myCurrentFacingModel);
+    if (IsTransparent())
+    {
+      Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
+      mat.SetTransparency (aTransp);
+    }
+    myDrawer->ShadingAspect()->SetMaterial (mat ,myCurrentFacingModel);
   }
-  else {
-    myDrawer->SetShadingAspect(NullShA);
+  else
+  {
+    myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
   }
+  myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
 
-  if(!GetContext().IsNull()){
-    if(GetContext()->MainPrsMgr()->HasPresentation(this,1)){
-      Handle(Prs3d_Presentation) aPresentation = GetContext()->MainPrsMgr()->Presentation (this, 1)->Presentation();
-      Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(aPresentation);
-
-      Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect();
-      Handle(Graphic3d_AspectLine3d) aLineAsp = myDrawer->Link()->LineAspect()->Aspect();
-      Quantity_Color CC;
-      AIS_GraphicTool::GetInteriorColor(myDrawer->Link(),CC);
-      anAreaAsp->SetInteriorColor(CC);
-      aPresentation->SetPrimitivesAspect(anAreaAsp);
-      aPresentation->SetPrimitivesAspect(aLineAsp);
-      // Check if aspect of given type is set for the group, 
+  // modify shading presentation without re-computation
+  const PrsMgr_Presentations&        aPrsList  = Presentations();
+  Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect();
+  Handle(Graphic3d_AspectLine3d)     aLineAsp  = myDrawer->Link()->LineAspect()->Aspect();
+  for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
+  {
+    const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
+    if (aPrsModed.Mode() != AIS_Shaded)
+    {
+      continue;
+    }
+
+    const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
+
+    aPrs->SetPrimitivesAspect (anAreaAsp);
+    aPrs->SetPrimitivesAspect (aLineAsp);
+
+    for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
+    {
+      const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
+
+      // Check if aspect of given type is set for the group,
       // because setting aspect for group with no already set aspect
       // can lead to loss of presentation data
-      if (aGroup->IsGroupPrimitivesAspectSet(Graphic3d_ASPECT_FILL_AREA))
-        aGroup->SetGroupPrimitivesAspect(anAreaAsp);
-      if (aGroup->IsGroupPrimitivesAspectSet(Graphic3d_ASPECT_LINE))
-        aGroup->SetGroupPrimitivesAspect(aLineAsp);
+      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
+      {
+        aGroup->SetGroupPrimitivesAspect (anAreaAsp);
+      }
+      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
+      {
+        aGroup->SetGroupPrimitivesAspect (aLineAsp);
+      }
     }
   }
-  LoadRecomputable(0);
-  LoadRecomputable(2);
+
+  LoadRecomputable (AIS_WireFrame);
+  LoadRecomputable (2);
 }
 
 //=======================================================================
-//function : SetWidth
-//purpose  : 
+//function : setWidth
+//purpose  :
 //=======================================================================
 
-void AIS_Shape::SetWidth(const Standard_Real W)
+void AIS_Shape::setWidth (const Handle(Prs3d_Drawer)& theDrawer,
+                          const Standard_Real         theLineWidth) const
 {
-  if(HasColor() || HasWidth()){
-    myDrawer->LineAspect()->SetWidth(W);
-    myDrawer->WireAspect()->SetWidth(W);
-    myDrawer->FreeBoundaryAspect()->SetWidth(W);
-    myDrawer->UnFreeBoundaryAspect()->SetWidth(W);
-    myDrawer->SeenLineAspect()->SetWidth(W);
+  if (!theDrawer->HasOwnLineAspect())
+  {
+    theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
+    }
+  }
+  if (!theDrawer->HasOwnWireAspect())
+  {
+    theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
+    }
+  }
+  if (!theDrawer->HasOwnFreeBoundaryAspect())
+  {
+    theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
+    }
   }
-  else{
-    Quantity_Color CC;
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_Line,CC);
-    myDrawer->SetLineAspect(new Prs3d_LineAspect(CC,Aspect_TOL_SOLID,W));
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_Wire,CC);
-    myDrawer->SetWireAspect(new Prs3d_LineAspect(CC,Aspect_TOL_SOLID,W));
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_Free,CC);
-    myDrawer->SetFreeBoundaryAspect(new Prs3d_LineAspect(CC,Aspect_TOL_SOLID,W));
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_UnFree,CC);
-    myDrawer->SetUnFreeBoundaryAspect(new Prs3d_LineAspect(CC,Aspect_TOL_SOLID,W));
-    AIS_GraphicTool::GetLineColor(myDrawer->Link(),AIS_TOA_Seen,CC);
-    myDrawer->SetSeenLineAspect(new Prs3d_LineAspect(CC,Aspect_TOL_SOLID,W));
+  if (!theDrawer->HasOwnUnFreeBoundaryAspect())
+  {
+    theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
+    }
   }
-  myOwnWidth = W;
-  LoadRecomputable(0); // means that it is necessary to recompute only the wireframe....
-  LoadRecomputable(2); // and the bounding box...
+  if (!theDrawer->HasOwnSeenLineAspect())
+  {
+    theDrawer->SetSeenLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->SeenLineAspect()->Aspect() = *theDrawer->Link()->SeenLineAspect()->Aspect();
+    }
+  }
+
+  // override width
+  theDrawer->LineAspect()->SetWidth (theLineWidth);
+  theDrawer->WireAspect()->SetWidth (theLineWidth);
+  theDrawer->FreeBoundaryAspect()->SetWidth (theLineWidth);
+  theDrawer->UnFreeBoundaryAspect()->SetWidth (theLineWidth);
+  theDrawer->SeenLineAspect()->SetWidth (theLineWidth);
 }
 
 //=======================================================================
-//function : UnsetWidth
+//function : SetWidth
 //purpose  : 
 //=======================================================================
 
+void AIS_Shape::SetWidth (const Standard_Real theLineWidth)
+{
+  setWidth (myDrawer, theLineWidth);
+  myOwnWidth = theLineWidth;
+  LoadRecomputable (AIS_WireFrame); // means that it is necessary to recompute only the wireframe....
+  LoadRecomputable (2);             // and the bounding box...
+}
+
+//=======================================================================
+//function : UnsetWidth
+//purpose  :
+//=======================================================================
+
 void AIS_Shape::UnsetWidth()
 {
-  if(myOwnWidth == 0.0)
+  if (myOwnWidth == 0.0)
   {
     myToRecomputeModes.Clear();
     return;
   }
-  myOwnWidth=0.0;
 
-  Handle(Prs3d_LineAspect) NullAsp;
+  myOwnWidth = 0.0;
+
+  Handle(Prs3d_LineAspect) anEmptyAsp;
+
+  if (!HasColor())
+  {
+    myDrawer->SetLineAspect          (anEmptyAsp);
+    myDrawer->SetWireAspect          (anEmptyAsp);
+    myDrawer->SetFreeBoundaryAspect  (anEmptyAsp);
+    myDrawer->SetUnFreeBoundaryAspect(anEmptyAsp);
+    myDrawer->SetSeenLineAspect      (anEmptyAsp);
+  }
+  else
+  {
+    myDrawer->LineAspect()          ->SetWidth (myDrawer->HasLink() ?
+      AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Line) : 1.);
+    myDrawer->WireAspect()          ->SetWidth (myDrawer->HasLink() ?
+      AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Wire) : 1.);
+    myDrawer->FreeBoundaryAspect()  ->SetWidth (myDrawer->HasLink() ?
+      AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Free) : 1.);
+    myDrawer->UnFreeBoundaryAspect()->SetWidth (myDrawer->HasLink() ?
+      AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_UnFree) : 1.);
+    myDrawer->SeenLineAspect()      ->SetWidth (myDrawer->HasLink() ?
+      AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Seen) : 1.);
+  }
+  LoadRecomputable (AIS_WireFrame);
+}
+
+//=======================================================================
+//function : setMaterial
+//purpose  :
+//=======================================================================
+
+void AIS_Shape::setMaterial (const Handle(Prs3d_Drawer)&     theDrawer,
+                             const Graphic3d_MaterialAspect& theMaterial,
+                             const Standard_Boolean          theToKeepColor,
+                             const Standard_Boolean          theToKeepTransp) const
+{
+  const Quantity_Color aColor  = theDrawer->ShadingAspect()->Material     (myCurrentFacingModel).Color();
+  const Standard_Real  aTransp = theDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
+  if (!theDrawer->HasOwnShadingAspect())
+  {
+    theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
+    }
+  }
+  theDrawer->ShadingAspect()->SetMaterial (theMaterial, myCurrentFacingModel);
 
-  if(!HasColor()){
-    myDrawer->SetLineAspect(NullAsp);
-    myDrawer->SetWireAspect(NullAsp);
-    myDrawer->SetFreeBoundaryAspect(NullAsp);
-    myDrawer->SetUnFreeBoundaryAspect(NullAsp);
-    myDrawer->SetSeenLineAspect(NullAsp);
+  if (theToKeepColor)
+  {
+    theDrawer->ShadingAspect()->SetColor (aColor, myCurrentFacingModel);
   }
-  else{
-    myDrawer->LineAspect()->SetWidth(AIS_GraphicTool::GetLineWidth(myDrawer->Link(),AIS_TOA_Line));
-    myDrawer->WireAspect()->SetWidth(AIS_GraphicTool::GetLineWidth(myDrawer->Link(),AIS_TOA_Wire));
-    myDrawer->FreeBoundaryAspect()->SetWidth(AIS_GraphicTool::GetLineWidth(myDrawer->Link(),AIS_TOA_Free));
-    myDrawer->UnFreeBoundaryAspect()->SetWidth(AIS_GraphicTool::GetLineWidth(myDrawer->Link(),AIS_TOA_UnFree));
-    myDrawer->SeenLineAspect()->SetWidth(AIS_GraphicTool::GetLineWidth(myDrawer->Link(),AIS_TOA_Seen));
+  if (theToKeepTransp)
+  {
+    theDrawer->ShadingAspect()->SetTransparency (aTransp, myCurrentFacingModel);
   }
-  LoadRecomputable(0);
 }
 
 //=======================================================================
@@ -701,143 +858,209 @@ void AIS_Shape::SetMaterial(const Graphic3d_NameOfMaterial aMat)
 
 //=======================================================================
 //function : SetMaterial
-//purpose  : 
+//purpose  :
 //=======================================================================
 
-void AIS_Shape::SetMaterial(const Graphic3d_MaterialAspect& aMat)
+void AIS_Shape::SetMaterial (const Graphic3d_MaterialAspect& theMat)
 {
-  if( !HasColor() && !IsTransparent() && !HasMaterial() ) {
-    myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
-  }
+  setMaterial (myDrawer, theMat, HasColor(), IsTransparent());
   hasOwnMaterial = Standard_True;
 
-  myDrawer->ShadingAspect()->SetMaterial(aMat,myCurrentFacingModel);
-  myDrawer->ShadingAspect()->SetTransparency(myTransparency,myCurrentFacingModel);
+  // modify shading presentation without re-computation
+  const PrsMgr_Presentations&        aPrsList  = Presentations();
+  Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
+  for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
+  {
+    const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
+    if (aPrsModed.Mode() != AIS_Shaded)
+    {
+      continue;
+    }
 
-  if(!GetContext().IsNull()){
-    if(GetContext()->MainPrsMgr()->HasPresentation(this,1))
+    const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
+    aPrs->SetPrimitivesAspect (anAreaAsp);
+    for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
     {
-      Handle(Prs3d_Presentation) aPresentation = GetContext()->MainPrsMgr()->Presentation (this, 1)->Presentation();
-      Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(aPresentation);
-    
-      Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
-      aPresentation->SetPrimitivesAspect(anAreaAsp);
+      const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
+
       // Check if aspect of given type is set for the group, 
       // because setting aspect for group with no already set aspect
       // can lead to loss of presentation data
-      if (aGroup->IsGroupPrimitivesAspectSet(Graphic3d_ASPECT_FILL_AREA))
-        aGroup->SetGroupPrimitivesAspect(anAreaAsp);
+      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
+      {
+        aGroup->SetGroupPrimitivesAspect (anAreaAsp);
+      }
     }
-    myRecomputeEveryPrs =Standard_False; // no mode to recalculate  :only viewer update
-    myToRecomputeModes.Clear();
   }
+
+  myRecomputeEveryPrs = Standard_False; // no mode to recalculate  :only viewer update
+  myToRecomputeModes.Clear();
 }
+
 //=======================================================================
 //function : UnsetMaterial
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void AIS_Shape::UnsetMaterial()
 {
-  if( !HasMaterial() ) return;
+  if (!HasMaterial())
+  {
+    return;
+  }
 
-  if( HasColor() || IsTransparent()) {
-    Graphic3d_MaterialAspect mat = AIS_GraphicTool::GetMaterial(myDrawer->Link()); 
-    if( HasColor() ) {
-      Quantity_Color color = myDrawer->ShadingAspect()->Color(myCurrentFacingModel);
-      mat.SetColor(color);
+  if (HasColor()
+   || IsTransparent())
+  {
+    if(myDrawer->HasLink())
+    {
+      myDrawer->ShadingAspect()->SetMaterial (myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel),
+                                              myCurrentFacingModel);
     }
-    if( IsTransparent() ) {
-      Standard_Real trans = myDrawer->ShadingAspect()->Transparency(myCurrentFacingModel);
-      mat.SetTransparency(trans);
+    if (HasColor())
+    {
+      myDrawer->ShadingAspect()->SetColor        (myOwnColor,     myCurrentFacingModel);
+      myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
     }
-    myDrawer->ShadingAspect()->SetMaterial(mat,myCurrentFacingModel);
-  } else {
-    Handle(Prs3d_ShadingAspect) SA;
-    myDrawer->SetShadingAspect(SA);
+  }
+  else
+  {
+    myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
   }
   hasOwnMaterial = Standard_False;
-  if(!GetContext().IsNull()){
-    if(GetContext()->MainPrsMgr()->HasPresentation(this,1)){
-      Handle(Prs3d_Presentation) aPresentation = GetContext()->MainPrsMgr()->Presentation (this, 1)->Presentation();
-      Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(aPresentation);
-      Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
-      aPresentation->SetPrimitivesAspect(anAreaAsp);
-      // Check if aspect of given type is set for the group, 
-      // because setting aspect for group with no already set aspect
-      // can lead to loss of presentation data
-      if (aGroup->IsGroupPrimitivesAspectSet(Graphic3d_ASPECT_FILL_AREA))
-        aGroup->SetGroupPrimitivesAspect(anAreaAsp);
+
+  // modify shading presentation without re-computation
+  const PrsMgr_Presentations&        aPrsList  = Presentations();
+  Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
+  for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
+  {
+    const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
+    if (aPrsModed.Mode() != AIS_Shaded)
+    {
+      continue;
+    }
+
+    const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
+    aPrs->SetPrimitivesAspect (anAreaAsp);
+    for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
+    {
+      const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
+      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
+      {
+        aGroup->SetGroupPrimitivesAspect (anAreaAsp);
+      }
     }
   }
-  myRecomputeEveryPrs =Standard_False; // no mode to recalculate :only viewer update
+
+  myRecomputeEveryPrs = Standard_False; // no mode to recalculate :only viewer update
   myToRecomputeModes.Clear();  
 }
 
 //=======================================================================
-//function : SetTransparency
-//purpose  : 
+//function : setTransparency
+//purpose  :
 //=======================================================================
 
-void AIS_Shape::SetTransparency(const Standard_Real AValue)
+void AIS_Shape::setTransparency (const Handle(Prs3d_Drawer)& theDrawer,
+                                 const Standard_Real         theValue) const
 {
-  if ( !HasColor() && !HasMaterial() ) {
-    myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
+  if (!theDrawer->HasOwnShadingAspect())
+  {
+    theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
+    }
   }
-  myDrawer->ShadingAspect()->SetTransparency(AValue,myCurrentFacingModel);
-  myTransparency = AValue;
-
-  if(!GetContext().IsNull()){
-    if(GetContext()->MainPrsMgr()->HasPresentation(this,1)){
-      Handle(Prs3d_Presentation) aPresentation = GetContext()->MainPrsMgr()->Presentation (this, 1)->Presentation();
-      Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(aPresentation);
-      Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
-      aPresentation->SetPrimitivesAspect(anAreaAsp);
-      //force highest priority for transparent objects
-      aPresentation->SetDisplayPriority(10);
-      // Check if aspect of given type is set for the group, 
-      // because setting aspect for group with no already set aspect
-      // can lead to loss of presentation data
-      if (aGroup->IsGroupPrimitivesAspectSet(Graphic3d_ASPECT_FILL_AREA))
-        aGroup->SetGroupPrimitivesAspect(anAreaAsp);
+
+  // override transparency
+  theDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
+}
+
+//=======================================================================
+//function : SetTransparency
+//purpose  :
+//=======================================================================
+
+void AIS_Shape::SetTransparency (const Standard_Real theValue)
+{
+  setTransparency (myDrawer, theValue);
+  myTransparency = theValue;
+
+  // modify shading presentation without re-computation
+  const PrsMgr_Presentations&        aPrsList  = Presentations();
+  Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
+  for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
+  {
+    const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
+    if (aPrsModed.Mode() != AIS_Shaded)
+    {
+      continue;
+    }
+
+    const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
+    aPrs->SetPrimitivesAspect (anAreaAsp);
+    aPrs->SetDisplayPriority (10); // force highest priority for translucent objects
+    for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
+    {
+      const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
+      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
+      {
+        aGroup->SetGroupPrimitivesAspect (anAreaAsp);
+      }
     }
   }
-  myRecomputeEveryPrs =Standard_False; // no mode to recalculate :only viewer update
+
+  myRecomputeEveryPrs = Standard_False; // no mode to recalculate - only viewer update
   myToRecomputeModes.Clear();
 }
 
 //=======================================================================
 //function : UnsetTransparency
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void AIS_Shape::UnsetTransparency()
 {
-  if( HasColor() || HasMaterial() ) {
-    myDrawer->ShadingAspect()->SetTransparency(0.0,myCurrentFacingModel);
-  } else {
-    Handle(Prs3d_ShadingAspect) SA;
-    myDrawer->SetShadingAspect(SA);
-  }
-
   myTransparency = 0.0;
+  if (!myDrawer->HasOwnShadingAspect())
+  {
+    return;
+  }
+  else if (HasColor() || HasMaterial())
+  {
+    myDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
+  }
+  else
+  {
+    myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
+  }
 
-  if(!GetContext().IsNull()){
-    if(GetContext()->MainPrsMgr()->HasPresentation(this,1)){
-      Handle(Prs3d_Presentation) aPresentation = GetContext()->MainPrsMgr()->Presentation (this, 1)->Presentation();
-      Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(aPresentation);
-      Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
-      aPresentation->SetPrimitivesAspect(anAreaAsp);
-      // Check if aspect of given type is set for the group, 
-      // because setting aspect for group with no already set aspect
-      // can lead to loss of presentation data
-      if (aGroup->IsGroupPrimitivesAspectSet(Graphic3d_ASPECT_FILL_AREA))
-        aGroup->SetGroupPrimitivesAspect(anAreaAsp);
+  // modify shading presentation without re-computation
+  const PrsMgr_Presentations&        aPrsList  = Presentations();
+  Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
+  for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
+  {
+    const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
+    if (aPrsModed.Mode() != AIS_Shaded)
+    {
+      continue;
+    }
 
-      aPresentation->ResetDisplayPriority();
+    const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
+    aPrs->SetPrimitivesAspect (anAreaAsp);
+    for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
+    {
+      const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
+      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
+      {
+        aGroup->SetGroupPrimitivesAspect (anAreaAsp);
+      }
     }
+    aPrs->ResetDisplayPriority();
   }
-  myRecomputeEveryPrs =Standard_False; // no mode to recalculate :only viewer update
+
+  myRecomputeEveryPrs = Standard_False; // no mode to recalculate :only viewer update
   myToRecomputeModes.Clear();
 }
 
@@ -886,7 +1109,7 @@ const Bnd_Box& AIS_Shape::BoundingBox()
 
 Standard_Boolean AIS_Shape::SetOwnDeviationCoefficient ()
 {
-  Standard_Boolean itSet = myDrawer->IsOwnDeviationCoefficient();
+  Standard_Boolean itSet = myDrawer->HasOwnDeviationCoefficient();
   if(itSet)  myDrawer->SetDeviationCoefficient();
   return itSet;
 }
@@ -899,7 +1122,7 @@ Standard_Boolean AIS_Shape::SetOwnDeviationCoefficient ()
 
 Standard_Boolean AIS_Shape::SetOwnHLRDeviationCoefficient ()
 {
-  Standard_Boolean itSet = myDrawer->IsOwnHLRDeviationCoefficient();
+  Standard_Boolean itSet = myDrawer->HasOwnHLRDeviationCoefficient();
   if(itSet)  myDrawer->SetHLRDeviationCoefficient();
   return itSet;
 
@@ -913,7 +1136,7 @@ Standard_Boolean AIS_Shape::SetOwnHLRDeviationCoefficient ()
 
 Standard_Boolean AIS_Shape::SetOwnDeviationAngle ()
 {
-  Standard_Boolean itSet = myDrawer->IsOwnDeviationAngle();
+  Standard_Boolean itSet = myDrawer->HasOwnDeviationAngle();
   if(itSet)  myDrawer->SetDeviationAngle();
   return itSet;
 
@@ -927,7 +1150,7 @@ Standard_Boolean AIS_Shape::SetOwnDeviationAngle ()
 
 Standard_Boolean AIS_Shape::SetOwnHLRDeviationAngle ()
 {
-  Standard_Boolean itSet = myDrawer->IsOwnHLRDeviationAngle();
+  Standard_Boolean itSet = myDrawer->HasOwnHLRDeviationAngle();
   if(itSet)  myDrawer->SetHLRAngle();
   return itSet;
 
@@ -1028,7 +1251,7 @@ Standard_Boolean AIS_Shape::OwnDeviationCoefficient ( Standard_Real &  aCoeffici
 {
   aCoefficient = myDrawer->DeviationCoefficient();
   aPreviousCoefficient = myDrawer->PreviousDeviationCoefficient ();
-  return myDrawer->IsOwnDeviationCoefficient() ;
+  return myDrawer->HasOwnDeviationCoefficient() ;
 }
 
 //=======================================================================
@@ -1041,7 +1264,7 @@ Standard_Boolean AIS_Shape::OwnHLRDeviationCoefficient ( Standard_Real & aCoeffi
 {
   aCoefficient = myDrawer->HLRDeviationCoefficient();
   aPreviousCoefficient = myDrawer->PreviousHLRDeviationCoefficient ();
-  return myDrawer->IsOwnHLRDeviationCoefficient();
+  return myDrawer->HasOwnHLRDeviationCoefficient();
 
 }
 
@@ -1055,7 +1278,7 @@ Standard_Boolean AIS_Shape::OwnDeviationAngle ( Standard_Real &  anAngle,
 {
   anAngle = myDrawer->DeviationAngle();
   aPreviousAngle = myDrawer->PreviousDeviationAngle (); 
-  return myDrawer->IsOwnDeviationAngle();
+  return myDrawer->HasOwnDeviationAngle();
 }
 
 //=======================================================================
@@ -1068,5 +1291,5 @@ Standard_Boolean AIS_Shape::OwnHLRDeviationAngle ( Standard_Real &  anAngle,
 {
   anAngle = myDrawer->HLRAngle();
   aPreviousAngle = myDrawer->PreviousHLRDeviationAngle (); 
-  return myDrawer->IsOwnHLRDeviationAngle();
+  return myDrawer->HasOwnHLRDeviationAngle();
 }