0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / AIS / AIS_Shape.cxx
index 51aa9ab..b1afa4b 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <AIS_Shape.ixx>
+#include <AIS_Shape.hxx>
 
-
-#include <Standard_ErrorHandler.hxx>
-#include <OSD_Timer.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-
-#include <Quantity_Color.hxx>
-
-#include <gp_Pnt.hxx>
-#include <Bnd_Box.hxx>
+#include <AIS_GraphicTool.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <Aspect_TypeOfLine.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 <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 <Message.hxx>
+#include <Message_Messenger.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_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 <PrsMgr_ModedPresentation.hxx>
-
+#include <Prs3d_BndBox.hxx>
+#include <StdPrs_ToolTriangulatedShape.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_DisplayMode.hxx>
+#include <StdSelect_BRepSelectionTool.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TopExp.hxx>
 
-#include <AIS_GraphicTool.hxx>
-#include <AIS_InteractiveContext.hxx>
-#include <AIS_Drawer.hxx>
-#include <HLRBRep.hxx>
-#include <Precision.hxx>
+IMPLEMENT_STANDARD_RTTIEXT(AIS_Shape,AIS_InteractiveObject)
 
-#include <Standard_Failure.hxx>
-#include <Standard_ErrorHandler.hxx>
-#include <Select3D_SensitiveBox.hxx>
-#include <TopoDS_Iterator.hxx>
+// Auxiliary macros
+#define replaceAspectWithDef(theMap, theAspect) \
+  if (myDrawer->Link()->theAspect()->Aspect() != myDrawer->theAspect()->Aspect()) \
+  { \
+    theMap.Bind (myDrawer->theAspect()->Aspect(), myDrawer->Link()->theAspect()->Aspect()); \
+  }
 
-static Standard_Boolean myFirstCompute;
+// Auxiliary macros for replaceWithNewOwnAspects()
+#define replaceAspectWithOwn(theMap, theAspect) \
+  if (myDrawer->Link()->theAspect()->Aspect() != myDrawer->theAspect()->Aspect()) \
+  { \
+    theMap.Bind (myDrawer->Link()->theAspect()->Aspect(), myDrawer->theAspect()->Aspect()); \
+  }
 
-void AIS_Shape::DisplayBox(const Handle(Prs3d_Presentation)& aPrs,
-                           const Bnd_Box& B,
-                           const Handle(Prs3d_Drawer)& aDrawer)
+//=======================================================================
+//function : replaceWithNewOwnAspects
+//purpose  :
+//=======================================================================
+void AIS_Shape::replaceWithNewOwnAspects()
 {
-  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);
-}
+  Graphic3d_MapOfAspectsToAspects aReplaceMap;
 
-static Standard_Boolean IsInList(const TColStd_ListOfInteger& LL, const Standard_Integer aMode)
-{
-  TColStd_ListIteratorOfListOfInteger It(LL);
-  for(;It.More();It.Next()){
-    if(It.Value()==aMode) 
-      return Standard_True;}
-  return Standard_False;
+  replaceAspectWithOwn (aReplaceMap, ShadingAspect);
+  replaceAspectWithOwn (aReplaceMap, LineAspect);
+  replaceAspectWithOwn (aReplaceMap, WireAspect);
+  replaceAspectWithOwn (aReplaceMap, FreeBoundaryAspect);
+  replaceAspectWithOwn (aReplaceMap, UnFreeBoundaryAspect);
+  replaceAspectWithOwn (aReplaceMap, SeenLineAspect);
+  replaceAspectWithOwn (aReplaceMap, FaceBoundaryAspect);
+  replaceAspectWithOwn (aReplaceMap, PointAspect);
+
+  replaceAspects (aReplaceMap);
 }
 
 //==================================================
-// Function: 
+// Function: AIS_Shape
 // Purpose :
 //==================================================
-
-AIS_Shape::
-AIS_Shape(const TopoDS_Shape& shap):
-AIS_InteractiveObject(PrsMgr_TOP_ProjectorDependant),
-myshape(shap),
-myCompBB(Standard_True),
-myInitAng(0.)
+AIS_Shape::AIS_Shape(const TopoDS_Shape& theShape)
+: AIS_InteractiveObject (PrsMgr_TOP_ProjectorDependant),
+  myshape (theShape),
+  myUVOrigin(0.0, 0.0),
+  myUVRepeat(1.0, 1.0),
+  myUVScale (1.0, 1.0),
+  myInitAng (0.0),
+  myCompBB (Standard_True)
 {
-  myFirstCompute = Standard_True;
-  SetHilightMode(0);
-  myDrawer->SetShadingAspectGlobal(Standard_False);
+  //
 }
 
-//=======================================================================
-//function : Type
-//purpose  : 
-//=======================================================================
-AIS_KindOfInteractive AIS_Shape::Type() const 
-{return AIS_KOI_Shape;}
-
-
-//=======================================================================
-//function : Signature
-//purpose  : 
-//=======================================================================
-Standard_Integer AIS_Shape::Signature() const 
-{return 0;}
-
-//=======================================================================
-//function : AcceptShapeDecomposition
-//purpose  : 
-//=======================================================================
-Standard_Boolean AIS_Shape::AcceptShapeDecomposition() const 
-{return Standard_True;}
-
 //=======================================================================
 //function : Compute
 //purpose  : 
 //=======================================================================
 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;
 
   // wire,edge,vertex -> pas de HLR + priorite display superieure
@@ -174,222 +131,176 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat
     aPrs->SetDisplayPriority(TheType+2);
   }
   // Shape vide -> Assemblage vide.
-  if (myshape.ShapeType() == TopAbs_COMPOUND) {
-    TopoDS_Iterator anExplor (myshape);
+  if (myshape.ShapeType() == TopAbs_COMPOUND && myshape.NbChildren() == 0)
+  {
+    return;
+  }
 
-    if (!anExplor.More()) {
-      return;
-    }
+  if (IsInfinite())
+  {
+    aPrs->SetInfiniteState (Standard_True); //not taken in account during FITALL
   }
 
-  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);
+  switch (theMode)
+  {
+    case AIS_WireFrame:
+    {
+      StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
+      try
+      {
+        OCC_CATCH_SIGNALS
+        StdPrs_WFShape::Add (aPrs, myshape, myDrawer);
+      }
+      catch (Standard_Failure const& anException)
+      {
+        Message::SendFail (TCollection_AsciiString("Error: AIS_Shape::Compute() wireframe presentation builder has failed (")
+                         + anException.GetMessageString() + ")");
+      }
+      break;
     }
-    break;
-  }
-  case 1:
+    case AIS_Shaded:
     {
-      Standard_Real anAnglePrev, anAngleNew, aCoeffPrev, aCoeffNew;
-      Standard_Boolean isOwnDeviationAngle       = OwnDeviationAngle      (anAngleNew, anAnglePrev);
-      Standard_Boolean isOwnDeviationCoefficient = OwnDeviationCoefficient(aCoeffNew,  aCoeffPrev);
-      if ((isOwnDeviationAngle       && Abs (anAngleNew - anAnglePrev) > Precision::Angular())
-       || (isOwnDeviationCoefficient && Abs (aCoeffNew  - aCoeffPrev)  > Precision::Confusion()))
+      StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
+      if ((Standard_Integer) myshape.ShapeType() > 4)
       {
-        BRepTools::Clean (myshape);
+        StdPrs_WFShape::Add (aPrs, myshape, myDrawer);
       }
-
-      //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 {
+      else
+      {
+        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,
+                                     myDrawer->ShadingAspect()->Aspect()->ToMapTexture()
+                                 && !myDrawer->ShadingAspect()->Aspect()->TextureMap().IsNull(),
+                                     myUVOrigin, myUVRepeat, myUVScale);
+          }
+          catch (Standard_Failure const& anException)
+          {
+            Message::SendFail (TCollection_AsciiString("Error: AIS_Shape::Compute() shaded presentation builder has failed (")
+                             + anException.GetMessageString() + ")");
+            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
+      {
+        Prs3d_BndBox::Add (aPrs, BoundingBox(), myDrawer);
+      }
     }
-  } // end switch
-  aPrs->ReCompute(); // for hidden line recomputation if necessary...
-}
+  }
 
-//=======================================================================
-//function : Compute
-//purpose  : Hidden Line Removal
-//=======================================================================
-void AIS_Shape::Compute(const Handle(Prs3d_Projector)& aProjector,
-                        const Handle(Prs3d_Presentation)& aPresentation)
-{
-  Compute(aProjector,aPresentation,myshape);
+  // Recompute hidden line presentation (if necessary).
+  aPrs->ReCompute();
 }
 
 //=======================================================================
-//function : Compute
-//purpose  : 
+//function : computeHlrPresentation
+//purpose  :
 //=======================================================================
-
-void AIS_Shape::Compute(const Handle(Prs3d_Projector)&     aProjector,
-                        const Handle(Geom_Transformation)& TheTrsf,
-                        const Handle(Prs3d_Presentation)&  aPresentation)
+void AIS_Shape::computeHlrPresentation (const Handle(Graphic3d_Camera)& theProjector,
+                                        const Handle(Prs3d_Presentation)& thePrs,
+                                        const TopoDS_Shape& theShape,
+                                        const Handle(Prs3d_Drawer)& theDrawer)
 {
-  const TopLoc_Location& loc = myshape.Location();
-  TopoDS_Shape shbis = myshape.Located(TopLoc_Location(TheTrsf->Trsf())*loc);
-  Compute(aProjector,aPresentation,shbis);
-}
+  if (theShape.IsNull())
+  {
+    return;
+  }
 
-//=======================================================================
-//function : Compute
-//purpose  : 
-//=======================================================================
+  switch (theShape.ShapeType())
+  {
+    case TopAbs_VERTEX:
+    case TopAbs_EDGE:
+    case TopAbs_WIRE:
+    {
+      thePrs->SetDisplayPriority (4);
+      StdPrs_WFShape::Add (thePrs, theShape, theDrawer);
+      return;
+    }
+    case TopAbs_COMPOUND:
+    {
+      if (theShape.NbChildren() == 0)
+      {
+        return;
+      }
+      break;
+    }
+    default:
+    {
+      break;
+    }
+  }
 
-void AIS_Shape::Compute(const Handle(Prs3d_Projector)& aProjector,
-                        const Handle(Prs3d_Presentation)& aPresentation,
-                        const TopoDS_Shape& SH)
-{
-  if (SH.ShapeType() == TopAbs_COMPOUND) {
-    TopoDS_Iterator anExplor (SH);
+  const Handle(Prs3d_Drawer)& aDefDrawer = theDrawer->Link();
+  if (aDefDrawer->DrawHiddenLine())
+  {
+    theDrawer->EnableDrawHiddenLine();
+  }
+  else
+  {
+    theDrawer->DisableDrawHiddenLine();
+  }
 
-    if (!anExplor.More()) // Shape vide -> Assemblage vide.
-      return;
+  const Aspect_TypeOfDeflection aPrevDef = aDefDrawer->TypeOfDeflection();
+  aDefDrawer->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
+  if (theDrawer->IsAutoTriangulation())
+  {
+    StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (theShape, theDrawer, Standard_True);
   }
 
-  Handle (Prs3d_Drawer) defdrawer = GetContext()->DefaultDrawer();
-  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
-      BRepTools::Clean(SH);
-    }
-  
   {
-    try {
+    try
+    {
       OCC_CATCH_SIGNALS
-      switch (TypeOfHLR()) {
+      switch (theDrawer->TypeOfHLR())
+      {
         case Prs3d_TOH_Algo:
-          StdPrs_HLRShape::Add (aPresentation, SH, myDrawer, aProjector);
+        {
+          StdPrs_HLRShape aBuilder;
+          aBuilder.ComputeHLR (thePrs, theShape, theDrawer, theProjector);
           break;
+        }
         case Prs3d_TOH_PolyAlgo:
-        default:
-          StdPrs_HLRPolyShape::Add (aPresentation, SH, myDrawer, aProjector);
+        case Prs3d_TOH_NotSet:
+        {
+          StdPrs_HLRPolyShape aBuilder;
+          aBuilder.ComputeHLR (thePrs, theShape, theDrawer, theProjector);
           break;
+        }
       }
     }
-    catch (Standard_Failure) {
-#ifdef DEB
-      cout <<"AIS_Shape::Compute(Proj) HLR Algorithm failed" << endl;
-#endif
-      StdPrs_WFShape::Add(aPresentation,SH,myDrawer);
+    catch (Standard_Failure const& anException)
+    {
+      Message::SendFail (TCollection_AsciiString("Error: AIS_Shape::Compute() HLR Algorithm has failed (")
+                       + anException.GetMessageString() + ")");
+      StdPrs_WFShape::Add (thePrs, theShape, theDrawer);
     }
   }
 
-  defdrawer->SetTypeOfDeflection (prevdef);
-}
-
-//=======================================================================
-//function : SelectionType
-//purpose  : gives the type according to the Index of Selection Mode
-//=======================================================================
-
-TopAbs_ShapeEnum AIS_Shape::SelectionType(const Standard_Integer aMode)
-{
-  switch(aMode){
-  case 1:
-    return TopAbs_VERTEX;
-  case 2:
-    return TopAbs_EDGE;
-  case 3:
-    return TopAbs_WIRE;
-  case 4:
-    return TopAbs_FACE;
-  case 5:
-    return TopAbs_SHELL;
-  case 6:
-    return TopAbs_SOLID;
-  case 7:
-    return TopAbs_COMPSOLID;
-  case 8:
-    return TopAbs_COMPOUND;
-  case 0:
-  default:
-    return TopAbs_SHAPE;
-  }
-  
+  aDefDrawer->SetTypeOfDeflection (aPrevDef);
 }
-//=======================================================================
-//function : SelectionType
-//purpose  : gives the SelectionMode according to the Type od Decomposition...
-//=======================================================================
-Standard_Integer AIS_Shape::SelectionMode(const TopAbs_ShapeEnum aType)
-{
-  switch(aType){
-  case TopAbs_VERTEX:
-    return 1;
-  case TopAbs_EDGE:
-    return 2;
-  case TopAbs_WIRE:
-    return 3;
-  case  TopAbs_FACE:
-    return 4;
-  case TopAbs_SHELL:
-    return 5;
-  case TopAbs_SOLID:
-    return 6;
-  case TopAbs_COMPSOLID:
-    return 7;
-  case TopAbs_COMPOUND:
-    return 8;
-  case TopAbs_SHAPE:
-  default:
-    return 0;
-  }
-}
-
 
 //=======================================================================
 //function : ComputeSelection
@@ -400,37 +311,36 @@ void AIS_Shape::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
                                               const Standard_Integer aMode)
 {
   if(myshape.IsNull()) return;
-  if (myshape.ShapeType() == TopAbs_COMPOUND) {
-    TopoDS_Iterator anExplor (myshape);
-
-    if (!anExplor.More()) // empty Shape -> empty Assembly.
-      return;
+  if (myshape.ShapeType() == TopAbs_COMPOUND && myshape.NbChildren() == 0)
+  {
+    // empty Shape -> empty Assembly.
+    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 = Prs3d::GetDeflection(shape, myDrawer);
-  Standard_Boolean autoTriangulation = Standard_True;
-  try {  
+  Standard_Real aDeflection = StdPrs_ToolTriangulatedShape::GetDeflection(shape, myDrawer);
+  try
+  {
     OCC_CATCH_SIGNALS
     StdSelect_BRepSelectionTool::Load(aSelection,
                                       this,
                                       shape,
                                       TypOfSel,
                                       aDeflection,
-                                      myDrawer->HLRAngle(),
-                                      autoTriangulation); 
-  } catch ( Standard_Failure ) {
-//    cout << "a Shape should be incorrect : A Selection on the Bnd  is activated   "<<endl;
-    if ( aMode == 0 ) {
+                                      myDrawer->DeviationAngle(),
+                                      myDrawer->IsAutoTriangulation());
+  }
+  catch (Standard_Failure const& anException)
+  {
+    Message::SendFail (TCollection_AsciiString("Error: AIS_Shape::ComputeSelection(") + aMode + ") has failed ("
+                     + anException.GetMessageString() + ")");
+    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);
@@ -442,12 +352,6 @@ void AIS_Shape::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
   StdSelect::SetDrawerForBRepOwner(aSelection,myDrawer);
 }
 
-Quantity_NameOfColor AIS_Shape::Color() const {
-Quantity_Color aColor;
-  Color(aColor);
-  return aColor.Name();
-}
-
 void AIS_Shape::Color( Quantity_Color& aColor ) const {
   aColor = myDrawer->ShadingAspect()->Color(myCurrentFacingModel);
 }
@@ -460,55 +364,29 @@ Standard_Real AIS_Shape::Transparency() const {
   return myDrawer->ShadingAspect()->Transparency(myCurrentFacingModel);
 }
 
-//=======================================================================
-//function : SetColor
-//purpose  : 
-//=======================================================================
-
-void AIS_Shape::SetColor(const Quantity_NameOfColor aCol)
-{
-  SetColor(Quantity_Color(aCol));
-}
-
 //=======================================================================
 //function : setColor
 //purpose  :
 //=======================================================================
 
-void AIS_Shape::setColor (const Handle(AIS_Drawer)& theDrawer,
-                          const Quantity_Color&     theColor) const
+bool AIS_Shape::setColor (const Handle(Prs3d_Drawer)& theDrawer,
+                          const Quantity_Color&       theColor) const
 {
-  if (!theDrawer->HasShadingAspect())
-  {
-    theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
-    *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
-  }
-  if (!theDrawer->HasLineAspect())
-  {
-    theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
-  }
-  if (!theDrawer->HasWireAspect())
-  {
-    theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
-  }
-  if (!theDrawer->HasPointAspect())
-  {
-    theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_BLACK, 1.0));
-    *theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
-  }
-  // disable dedicated line aspects
-  theDrawer->SetFreeBoundaryAspect  (theDrawer->LineAspect());
-  theDrawer->SetUnFreeBoundaryAspect(theDrawer->LineAspect());
-  theDrawer->SetSeenLineAspect      (theDrawer->LineAspect());
+  bool toRecompute = false;
+  toRecompute = theDrawer->SetupOwnShadingAspect() || toRecompute;
+  toRecompute = theDrawer->SetOwnLineAspects() || toRecompute;
+  toRecompute = theDrawer->SetupOwnPointAspect() || toRecompute;
 
   // 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);
+  theDrawer->FaceBoundaryAspect()->SetColor (theColor);
+  return toRecompute;
 }
 
 //=======================================================================
@@ -518,55 +396,20 @@ void AIS_Shape::setColor (const Handle(AIS_Drawer)& theDrawer,
 
 void AIS_Shape::SetColor (const Quantity_Color& theColor)
 {
-  setColor (myDrawer, theColor);
-  myOwnColor  = theColor;
+  const bool toRecompute = setColor (myDrawer, theColor);
+  myDrawer->SetColor (theColor);
   hasOwnColor = Standard_True;
 
-  // 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)
+  if (!toRecompute
+   || !myDrawer->HasLink())
   {
-    const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
-    if (aPrsModed.Mode() != AIS_Shaded)
-    {
-      continue;
-    }
-
-    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();
-
-      // 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 (anAreaAspect);
-      }
-      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
-      {
-        aGroup->SetGroupPrimitivesAspect (aLineAspect);
-      }
-      if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
-      {
-        aGroup->SetGroupPrimitivesAspect (aPointAspect);
-      }
-    }
+    SynchronizeAspects();
   }
-
-  LoadRecomputable (AIS_WireFrame);
-  LoadRecomputable (2);
+  else
+  {
+    replaceWithNewOwnAspects();
+  }
+  recomputeComputed();
 }
 
 //=======================================================================
@@ -578,94 +421,119 @@ void AIS_Shape::UnsetColor()
 {
   if (!HasColor())
   {
-    myToRecomputeModes.Clear();
     return;
   }
+
   hasOwnColor = Standard_False;
+  myDrawer->SetColor (myDrawer->HasLink() ? myDrawer->Link()->Color() : Quantity_Color (Quantity_NOC_WHITE));
 
+  Graphic3d_MapOfAspectsToAspects aReplaceMap;
   if (!HasWidth())
   {
-    Handle(Prs3d_LineAspect) anEmptyAsp;
-    myDrawer->SetLineAspect          (anEmptyAsp);
-    myDrawer->SetWireAspect          (anEmptyAsp);
-    myDrawer->SetFreeBoundaryAspect  (anEmptyAsp);
-    myDrawer->SetUnFreeBoundaryAspect(anEmptyAsp);
-    myDrawer->SetSeenLineAspect      (anEmptyAsp);
+    replaceAspectWithDef (aReplaceMap, LineAspect);
+    replaceAspectWithDef (aReplaceMap, WireAspect);
+    replaceAspectWithDef (aReplaceMap, FreeBoundaryAspect);
+    replaceAspectWithDef (aReplaceMap, UnFreeBoundaryAspect);
+    replaceAspectWithDef (aReplaceMap, SeenLineAspect);
+    replaceAspectWithDef (aReplaceMap, FaceBoundaryAspect);
+    myDrawer->SetLineAspect          (Handle(Prs3d_LineAspect)());
+    myDrawer->SetWireAspect          (Handle(Prs3d_LineAspect)());
+    myDrawer->SetFreeBoundaryAspect  (Handle(Prs3d_LineAspect)());
+    myDrawer->SetUnFreeBoundaryAspect(Handle(Prs3d_LineAspect)());
+    myDrawer->SetSeenLineAspect      (Handle(Prs3d_LineAspect)());
+    myDrawer->SetFaceBoundaryAspect  (Handle(Prs3d_LineAspect)());
   }
   else
   {
-    Quantity_Color aColor;
-    AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Line,   aColor);
+    Quantity_Color aColor = Quantity_NOC_YELLOW;
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Line,   aColor);
+    }
     myDrawer->LineAspect()->SetColor (aColor);
-    AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Wire,   aColor);
+    aColor = Quantity_NOC_RED;
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Wire,   aColor);
+    }
     myDrawer->WireAspect()->SetColor (aColor);
-    AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Free,   aColor);
+    aColor = Quantity_NOC_GREEN;
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Free,   aColor);
+    }
     myDrawer->FreeBoundaryAspect()->SetColor (aColor);
-    AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_UnFree, aColor);
+    aColor = Quantity_NOC_YELLOW;
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_UnFree, aColor);
+    }
     myDrawer->UnFreeBoundaryAspect()->SetColor (aColor);
-    AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Seen,   aColor);
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Seen,   aColor);
+    }
     myDrawer->SeenLineAspect()->SetColor (aColor);
+    aColor = Quantity_NOC_BLACK;
+    if (myDrawer->HasLink())
+    {
+      AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_FaceBoundary, aColor);
+    }
+    myDrawer->FaceBoundaryAspect()->SetColor (aColor);
   }
 
-  if (HasMaterial()
-   || IsTransparent())
+  if (!myDrawer->HasOwnShadingAspect())
+  {
+    //
+  }
+  else if (HasMaterial()
+        || IsTransparent()
+        || myDrawer->ShadingAspect()->Aspect()->ToMapTexture())
   {
-    Graphic3d_MaterialAspect mat = AIS_GraphicTool::GetMaterial(HasMaterial()? myDrawer : myDrawer->Link());
+    const Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
+    Graphic3d_MaterialAspect mat = aDefaultMat;
+    Quantity_Color anInteriorColors[2] = {Quantity_NOC_CYAN1, Quantity_NOC_CYAN1};
+    if (myDrawer->HasLink())
+    {
+      anInteriorColors[0] = myDrawer->Link()->ShadingAspect()->Aspect()->InteriorColor();
+      anInteriorColors[1] = myDrawer->Link()->ShadingAspect()->Aspect()->BackInteriorColor();
+    }
+    if (HasMaterial() || myDrawer->HasLink())
+    {
+      const Handle(Graphic3d_AspectFillArea3d)& aSrcAspect = (HasMaterial() ? myDrawer : myDrawer->Link())->ShadingAspect()->Aspect();
+      mat = myCurrentFacingModel != Aspect_TOFM_BACK_SIDE
+          ? aSrcAspect->FrontMaterial()
+          : aSrcAspect->BackMaterial();
+    }
     if (HasMaterial())
     {
-      Quantity_Color aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
+      const Quantity_Color aColor = myDrawer->HasLink()
+                                  ? myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel)
+                                  : aDefaultMat.AmbientColor();
       mat.SetColor (aColor);
     }
     if (IsTransparent())
     {
       Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
-      mat.SetTransparency (aTransp);
+      mat.SetTransparency (Standard_ShortReal(aTransp));
     }
-    myDrawer->ShadingAspect()->SetMaterial (mat ,myCurrentFacingModel);
+    myDrawer->ShadingAspect()->SetMaterial (mat, myCurrentFacingModel);
+    myDrawer->ShadingAspect()->Aspect()->SetInteriorColor    (anInteriorColors[0]);
+    myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor(anInteriorColors[1]);
   }
   else
   {
+    replaceAspectWithDef (aReplaceMap, ShadingAspect);
     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
   }
-  myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
-
-  // 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)
+  if (myDrawer->HasOwnPointAspect())
   {
-    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);
-      }
-    }
+    replaceAspectWithDef (aReplaceMap, PointAspect);
+    myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
   }
-
-  LoadRecomputable (AIS_WireFrame);
-  LoadRecomputable (2);
+  replaceAspects (aReplaceMap);
+  SynchronizeAspects();
+  recomputeComputed();
 }
 
 //=======================================================================
@@ -673,27 +541,19 @@ void AIS_Shape::UnsetColor()
 //purpose  :
 //=======================================================================
 
-void AIS_Shape::setWidth (const Handle(AIS_Drawer)& theDrawer,
-                          const Standard_Real       theLineWidth) const
+bool AIS_Shape::setWidth (const Handle(Prs3d_Drawer)& theDrawer,
+                          const Standard_Real         theLineWidth) const
 {
-  if (!theDrawer->HasLineAspect())
-  {
-    theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
-  }
-  if (!theDrawer->HasWireAspect())
-  {
-    theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
-  }
-  // disable dedicated line aspects
-  theDrawer->SetFreeBoundaryAspect  (theDrawer->LineAspect());
-  theDrawer->SetUnFreeBoundaryAspect(theDrawer->LineAspect());
-  theDrawer->SetSeenLineAspect      (theDrawer->LineAspect());
+  bool toRecompute = theDrawer->SetOwnLineAspects();
 
   // override width
   theDrawer->LineAspect()->SetWidth (theLineWidth);
   theDrawer->WireAspect()->SetWidth (theLineWidth);
+  theDrawer->FreeBoundaryAspect()->SetWidth (theLineWidth);
+  theDrawer->UnFreeBoundaryAspect()->SetWidth (theLineWidth);
+  theDrawer->SeenLineAspect()->SetWidth (theLineWidth);
+  theDrawer->FaceBoundaryAspect()->SetWidth (theLineWidth);
+  return toRecompute;
 }
 
 //=======================================================================
@@ -703,10 +563,18 @@ void AIS_Shape::setWidth (const Handle(AIS_Drawer)& theDrawer,
 
 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...
+  myOwnWidth = (Standard_ShortReal )theLineWidth;
+
+  if (!setWidth (myDrawer, theLineWidth)
+   || !myDrawer->HasLink())
+  {
+    SynchronizeAspects();
+  }
+  else
+  {
+    replaceWithNewOwnAspects();
+  }
+  recomputeComputed();
 }
 
 //=======================================================================
@@ -716,43 +584,71 @@ void AIS_Shape::SetWidth (const Standard_Real theLineWidth)
 
 void AIS_Shape::UnsetWidth()
 {
-  if (myOwnWidth == 0.0)
+  if (myOwnWidth == 0.0f)
   {
-    myToRecomputeModes.Clear();
     return;
   }
 
-  myOwnWidth = 0.0;
-
-  Handle(Prs3d_LineAspect) anEmptyAsp;
-
+  myOwnWidth = 0.0f;
   if (!HasColor())
   {
-    myDrawer->SetLineAspect          (anEmptyAsp);
-    myDrawer->SetWireAspect          (anEmptyAsp);
-    myDrawer->SetFreeBoundaryAspect  (anEmptyAsp);
-    myDrawer->SetUnFreeBoundaryAspect(anEmptyAsp);
-    myDrawer->SetSeenLineAspect      (anEmptyAsp);
+    Graphic3d_MapOfAspectsToAspects aReplaceMap;
+    replaceAspectWithDef (aReplaceMap, LineAspect);
+    replaceAspectWithDef (aReplaceMap, WireAspect);
+    replaceAspectWithDef (aReplaceMap, FreeBoundaryAspect);
+    replaceAspectWithDef (aReplaceMap, UnFreeBoundaryAspect);
+    replaceAspectWithDef (aReplaceMap, SeenLineAspect);
+    replaceAspectWithDef (aReplaceMap, FaceBoundaryAspect);
+    myDrawer->SetLineAspect          (Handle(Prs3d_LineAspect)());
+    myDrawer->SetWireAspect          (Handle(Prs3d_LineAspect)());
+    myDrawer->SetFreeBoundaryAspect  (Handle(Prs3d_LineAspect)());
+    myDrawer->SetUnFreeBoundaryAspect(Handle(Prs3d_LineAspect)());
+    myDrawer->SetSeenLineAspect      (Handle(Prs3d_LineAspect)());
+    myDrawer->SetFaceBoundaryAspect  (Handle(Prs3d_LineAspect)());
+    replaceAspects (aReplaceMap);
   }
   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));
+    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.);
+    myDrawer->FaceBoundaryAspect()      ->SetWidth (myDrawer->HasLink() ?
+      AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_FaceBoundary) : 1.);
+    SynchronizeAspects();
   }
-  LoadRecomputable (AIS_WireFrame);
+  recomputeComputed();
 }
 
 //=======================================================================
-//function : SetMaterial
-//purpose  : 
+//function : setMaterial
+//purpose  :
 //=======================================================================
 
-void AIS_Shape::SetMaterial(const Graphic3d_NameOfMaterial aMat)
+void AIS_Shape::setMaterial (const Handle(Prs3d_Drawer)&     theDrawer,
+                             const Graphic3d_MaterialAspect& theMaterial,
+                             const Standard_Boolean          theToKeepColor,
+                             const Standard_Boolean          theToKeepTransp) const
 {
-  SetMaterial(Graphic3d_MaterialAspect(aMat));
+  const Quantity_Color aColor  = theDrawer->ShadingAspect()->Color (myCurrentFacingModel);
+  const Standard_Real  aTransp = theDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
+  theDrawer->SetupOwnShadingAspect();
+  theDrawer->ShadingAspect()->SetMaterial (theMaterial, myCurrentFacingModel);
+
+  if (theToKeepColor)
+  {
+    theDrawer->ShadingAspect()->SetColor (aColor, myCurrentFacingModel);
+  }
+  if (theToKeepTransp)
+  {
+    theDrawer->ShadingAspect()->SetTransparency (aTransp, myCurrentFacingModel);
+  }
 }
 
 //=======================================================================
@@ -762,49 +658,19 @@ void AIS_Shape::SetMaterial(const Graphic3d_NameOfMaterial aMat)
 
 void AIS_Shape::SetMaterial (const Graphic3d_MaterialAspect& theMat)
 {
-  if (!myDrawer->HasShadingAspect())
-  {
-    myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
-    *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
-  }
+  const bool toRecompute = !myDrawer->HasOwnShadingAspect();
+  setMaterial (myDrawer, theMat, HasColor(), IsTransparent());
   hasOwnMaterial = Standard_True;
 
-  myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
-  if (HasColor())
+  if (!toRecompute
+   || !myDrawer->HasLink())
   {
-    myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
+    SynchronizeAspects();
   }
-  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)
+  else
   {
-    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();
-
-      // 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);
-      }
-    }
+    replaceWithNewOwnAspects();
   }
-
-  myRecomputeEveryPrs = Standard_False; // no mode to recalculate  :only viewer update
-  myToRecomputeModes.Clear();
 }
 
 //=======================================================================
@@ -819,48 +685,33 @@ void AIS_Shape::UnsetMaterial()
     return;
   }
 
-  if (HasColor()
-   || IsTransparent())
+  if (!myDrawer->HasOwnShadingAspect())
+  {
+    //
+  }
+  else if (HasColor()
+        || IsTransparent()
+        || myDrawer->ShadingAspect()->Aspect()->ToMapTexture())
   {
-    myDrawer->ShadingAspect()->SetMaterial (myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel),
-                                            myCurrentFacingModel);
+    if(myDrawer->HasLink())
+    {
+      myDrawer->ShadingAspect()->SetMaterial (myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel),
+                                              myCurrentFacingModel);
+    }
     if (HasColor())
     {
-      myDrawer->ShadingAspect()->SetColor        (myOwnColor,     myCurrentFacingModel);
-      myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
+      myDrawer->ShadingAspect()->SetColor        (myDrawer->Color(),        myCurrentFacingModel);
+      myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
     }
+    SynchronizeAspects();
   }
   else
   {
+    Graphic3d_MapOfAspectsToAspects aReplaceMap;
+    replaceAspectWithDef (aReplaceMap, ShadingAspect);
     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
+    replaceAspects (aReplaceMap);
   }
-  hasOwnMaterial = Standard_False;
-
-  // 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
-  myToRecomputeModes.Clear();  
 }
 
 //=======================================================================
@@ -868,15 +719,10 @@ void AIS_Shape::UnsetMaterial()
 //purpose  :
 //=======================================================================
 
-void AIS_Shape::setTransparency (const Handle(AIS_Drawer)& theDrawer,
-                                 const Standard_Real       theValue) const
+void AIS_Shape::setTransparency (const Handle(Prs3d_Drawer)& theDrawer,
+                                 const Standard_Real         theValue) const
 {
-  if (!theDrawer->HasShadingAspect())
-  {
-    theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
-    *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
-  }
-
+  theDrawer->SetupOwnShadingAspect();
   // override transparency
   theDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
 }
@@ -888,35 +734,19 @@ void AIS_Shape::setTransparency (const Handle(AIS_Drawer)& theDrawer,
 
 void AIS_Shape::SetTransparency (const Standard_Real theValue)
 {
+  const bool toRecompute = !myDrawer->HasOwnShadingAspect();
   setTransparency (myDrawer, theValue);
-  myTransparency = theValue;
+  myDrawer->SetTransparency ((Standard_ShortReal )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)
+  if (!toRecompute
+   || !myDrawer->HasLink())
   {
-    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);
-      }
-    }
+    SynchronizeAspects();
+  }
+  else
+  {
+    replaceWithNewOwnAspects();
   }
-
-  myRecomputeEveryPrs = Standard_False; // no mode to recalculate - only viewer update
-  myToRecomputeModes.Clear();
 }
 
 //=======================================================================
@@ -926,58 +756,25 @@ void AIS_Shape::SetTransparency (const Standard_Real theValue)
 
 void AIS_Shape::UnsetTransparency()
 {
-  myTransparency = 0.0;
-  if (!myDrawer->HasShadingAspect())
+  myDrawer->SetTransparency (0.0f);
+  if (!myDrawer->HasOwnShadingAspect())
   {
     return;
   }
-  else if (HasColor() || HasMaterial())
+  else if (HasColor()
+        || HasMaterial()
+        || myDrawer->ShadingAspect()->Aspect()->ToMapTexture())
   {
     myDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
+    SynchronizeAspects();
   }
   else
   {
+    Graphic3d_MapOfAspectsToAspects aReplaceMap;
+    replaceAspectWithDef (aReplaceMap, ShadingAspect);
     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
+    replaceAspects (aReplaceMap);
   }
-
-  // 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);
-      }
-    }
-    aPrs->ResetDisplayPriority();
-  }
-
-  myRecomputeEveryPrs = Standard_False; // no mode to recalculate :only viewer update
-  myToRecomputeModes.Clear();
-}
-
-//=======================================================================
-//function : LoadRecomputable
-//purpose  : 
-//=======================================================================
-
-void AIS_Shape::LoadRecomputable(const Standard_Integer TheMode)
-{
-  myRecomputeEveryPrs = Standard_False;
-  if(!IsInList(myToRecomputeModes,TheMode))
-    myToRecomputeModes.Append(TheMode);
 }
 
 //=======================================================================
@@ -987,17 +784,15 @@ void AIS_Shape::LoadRecomputable(const Standard_Integer TheMode)
 
 const Bnd_Box& AIS_Shape::BoundingBox()  
 {
-  if (myshape.ShapeType() == TopAbs_COMPOUND) {
-    TopoDS_Iterator anExplor (myshape);
-
-    if (!anExplor.More()) { // empty Shape  -> empty Assembly.
-      myBB.SetVoid();
-      return myBB;
-    }
+  if (myshape.ShapeType() == TopAbs_COMPOUND && myshape.NbChildren() == 0)
+  {
+    // empty Shape  -> empty Assembly.
+    myBB.SetVoid ();
+    return myBB;
   }
 
   if(myCompBB) {
-    BRepBndLib::AddClose(myshape, myBB);
+    BRepBndLib::Add (myshape, myBB, false);
     myCompBB = Standard_False;
   }
   return myBB;
@@ -1013,25 +808,11 @@ 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;
 }
 
-//=======================================================================
-//function : SetHLROwnDeviationCoefficient
-//purpose  : resets myhasOwnHLRDeviationCoefficient to Standard_False and
-//           returns Standard_True if it change
-//=======================================================================
-
-Standard_Boolean AIS_Shape::SetOwnHLRDeviationCoefficient ()
-{
-  Standard_Boolean itSet = myDrawer->IsOwnHLRDeviationCoefficient();
-  if(itSet)  myDrawer->SetHLRDeviationCoefficient();
-  return itSet;
-
-}
-
 //=======================================================================
 //function : SetOwnDeviationAngle
 //purpose  : resets myhasOwnDeviationAngle to Standard_False and
@@ -1040,26 +821,12 @@ 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;
 
 }
 
-//=======================================================================
-//function : SetOwnHLRDeviationAngle
-//purpose  : resets myhasOwnHLRDeviationAngle to Standard_False and
-//           returns Standard_True if it change
-//=======================================================================
-
-Standard_Boolean AIS_Shape::SetOwnHLRDeviationAngle ()
-{
-  Standard_Boolean itSet = myDrawer->IsOwnHLRDeviationAngle();
-  if(itSet)  myDrawer->SetHLRAngle();
-  return itSet;
-
-}
-//***** SetOwn
 //=======================================================================
 //function : SetOwnDeviationCoefficient
 //purpose  : 
@@ -1068,19 +835,7 @@ Standard_Boolean AIS_Shape::SetOwnHLRDeviationAngle ()
 void AIS_Shape::SetOwnDeviationCoefficient ( const Standard_Real  aCoefficient )
 {
   myDrawer->SetDeviationCoefficient( aCoefficient );
-  SetToUpdate(0) ; // WireFrame
-  SetToUpdate(1) ; // Shadding
-}
-
-//=======================================================================
-//function : SetOwnHLRDeviationCoefficient
-//purpose  : 
-//=======================================================================
-
-void AIS_Shape::SetOwnHLRDeviationCoefficient ( const Standard_Real  aCoefficient )
-{
-  myDrawer->SetHLRDeviationCoefficient( aCoefficient );
-  
+  SetToUpdate();
 }
 
 //=======================================================================
@@ -1088,11 +843,10 @@ void AIS_Shape::SetOwnHLRDeviationCoefficient ( const Standard_Real  aCoefficien
 //purpose  : 
 //=======================================================================
 
-void AIS_Shape::SetOwnDeviationAngle ( const Standard_Real  anAngle )
+void AIS_Shape::SetOwnDeviationAngle (const Standard_Real theAngle)
 {
-
-  myDrawer->SetDeviationAngle(anAngle );
-  SetToUpdate(0) ;   // WireFrame
+  myDrawer->SetDeviationAngle (theAngle);
+  SetToUpdate (AIS_WireFrame);
 }
 //=======================================================================
 //function : SetOwnDeviationAngle
@@ -1106,8 +860,7 @@ void AIS_Shape::SetAngleAndDeviation ( const Standard_Real  anAngle )
   SetOwnDeviationAngle(anAngle) ;
   SetOwnDeviationCoefficient(OutDefl) ;
   myInitAng = anAngle;
-  SetToUpdate(0);
-  SetToUpdate(1);
+  SetToUpdate();
 }
 
 //=======================================================================
@@ -1120,31 +873,6 @@ Standard_Real AIS_Shape::UserAngle() const
   return myInitAng ==0. ? GetContext()->DeviationAngle(): myInitAng;
 }
 
-
-//=======================================================================
-//function : SetHLRAngleAndDeviation
-//purpose  : 
-//=======================================================================
-
-void AIS_Shape::SetHLRAngleAndDeviation ( const Standard_Real  anAngle )
-{
-  Standard_Real OutAngl,OutDefl;
-  HLRBRep::PolyHLRAngleAndDeflection(anAngle,OutAngl,OutDefl);
-  SetOwnHLRDeviationAngle( OutAngl );
-  SetOwnHLRDeviationCoefficient(OutDefl);
-
-}
-//=======================================================================
-//function : SetOwnHLRDeviationAngle
-//purpose  : 
-//=======================================================================
-
-void AIS_Shape::SetOwnHLRDeviationAngle ( const Standard_Real  anAngle )
-{
-  myDrawer->SetHLRAngle( anAngle );
-}
-
-//***** GetOwn
 //=======================================================================
 //function : OwnDeviationCoefficient
 //purpose  : 
@@ -1155,21 +883,7 @@ Standard_Boolean AIS_Shape::OwnDeviationCoefficient ( Standard_Real &  aCoeffici
 {
   aCoefficient = myDrawer->DeviationCoefficient();
   aPreviousCoefficient = myDrawer->PreviousDeviationCoefficient ();
-  return myDrawer->IsOwnDeviationCoefficient() ;
-}
-
-//=======================================================================
-//function : OwnHLRDeviationCoefficient
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean AIS_Shape::OwnHLRDeviationCoefficient ( Standard_Real & aCoefficient,
-                                                         Standard_Real & aPreviousCoefficient ) const
-{
-  aCoefficient = myDrawer->HLRDeviationCoefficient();
-  aPreviousCoefficient = myDrawer->PreviousHLRDeviationCoefficient ();
-  return myDrawer->IsOwnHLRDeviationCoefficient();
-
+  return myDrawer->HasOwnDeviationCoefficient() ;
 }
 
 //=======================================================================
@@ -1182,18 +896,21 @@ Standard_Boolean AIS_Shape::OwnDeviationAngle ( Standard_Real &  anAngle,
 {
   anAngle = myDrawer->DeviationAngle();
   aPreviousAngle = myDrawer->PreviousDeviationAngle (); 
-  return myDrawer->IsOwnDeviationAngle();
+  return myDrawer->HasOwnDeviationAngle();
 }
 
 //=======================================================================
-//function : OwnHLRDeviationAngle
+//function : DumpJson
 //purpose  : 
 //=======================================================================
-
-Standard_Boolean AIS_Shape::OwnHLRDeviationAngle ( Standard_Real &  anAngle,
-                                                   Standard_Real & aPreviousAngle ) const
+void AIS_Shape::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
 {
-  anAngle = myDrawer->HLRAngle();
-  aPreviousAngle = myDrawer->PreviousHLRDeviationAngle (); 
-  return myDrawer->IsOwnHLRDeviationAngle();
+  OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
+  OCCT_DUMP_BASE_CLASS (theOStream, theDepth, AIS_InteractiveObject)
+
+  OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myshape)
+  OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myBB)
+
+  OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myInitAng)
+  OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCompBB)
 }