0027060: Visualization issue with TopoDS_Vertex after call of AIS_Shape::SetColor()
[occt.git] / src / AIS / AIS_Shape.cxx
index bc913c3..c2721c5 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;
+IMPLEMENT_STANDARD_RTTIEXT(AIS_Shape,AIS_InteractiveObject)
 
-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);
-}
+static Standard_Boolean myFirstCompute;
 
 static Standard_Boolean IsInList(const TColStd_ListOfInteger& LL, const Standard_Integer aMode)
 {
@@ -143,10 +89,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.)
 {
+  Set (shap);
   myFirstCompute = Standard_True;
   SetHilightMode(0);
   myDrawer->SetShadingAspectGlobal(Standard_False);
@@ -200,66 +145,96 @@ 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 duting FITALL
   }
-  case 1:
+
+  switch (aMode)
+  {
+    case AIS_WireFrame:
     {
-      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()))
+      try
       {
-        BRepTools::Clean (myshape);
+        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);
+      }
+      break;
+    }
+    case AIS_Shaded:
+    {
+      if (myDrawer->IsAutoTriangulation())
+      {
+        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()))
+        {
+          BRepTools::Clean (myshape);
+        }
       }
 
-      //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 {
+      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();
 }
 
 //=======================================================================
@@ -303,27 +278,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 {
@@ -339,7 +312,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);
@@ -428,15 +401,10 @@ void AIS_Shape::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
   static TopAbs_ShapeEnum TypOfSel;
   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,
@@ -445,10 +413,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);
@@ -493,33 +462,65 @@ void AIS_Shape::SetColor(const Quantity_NameOfColor aCol)
 //purpose  :
 //=======================================================================
 
-void AIS_Shape::setColor (const Handle(AIS_Drawer)& theDrawer,
-                          const Quantity_Color&     theColor) const
+void AIS_Shape::setColor (const Handle(Prs3d_Drawer)& theDrawer,
+                          const Quantity_Color&       theColor) const
 {
-  if (!theDrawer->HasShadingAspect())
+  if (!theDrawer->HasOwnShadingAspect())
   {
     theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
-    *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
+    }
   }
-  if (!theDrawer->HasLineAspect())
+  if (!theDrawer->HasOwnLineAspect())
   {
     theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
+    }
   }
-  if (!theDrawer->HasWireAspect())
+  if (!theDrawer->HasOwnWireAspect())
   {
     theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
+    }
   }
-  if (!theDrawer->HasPointAspect())
+  if (!theDrawer->HasOwnPointAspect())
   {
-    theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_BLACK, 1.0));
-    *theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
+    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();
+    }
   }
-  // disable dedicated line aspects
-  theDrawer->SetFreeBoundaryAspect  (theDrawer->LineAspect());
-  theDrawer->SetUnFreeBoundaryAspect(theDrawer->LineAspect());
-  theDrawer->SetSeenLineAspect      (theDrawer->LineAspect());
 
   // override color
   theDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel);
@@ -527,6 +528,9 @@ void AIS_Shape::setColor (const Handle(AIS_Drawer)& theDrawer,
   theDrawer->LineAspect()->SetColor (theColor);
   theDrawer->WireAspect()->SetColor (theColor);
   theDrawer->PointAspect()->SetColor (theColor);
+  theDrawer->FreeBoundaryAspect()->SetColor (theColor);
+  theDrawer->UnFreeBoundaryAspect()->SetColor (theColor);
+  theDrawer->SeenLineAspect()->SetColor (theColor);
 }
 
 //=======================================================================
@@ -612,26 +616,53 @@ void AIS_Shape::UnsetColor()
   }
   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);
   }
 
   if (HasMaterial()
    || IsTransparent())
   {
-    Graphic3d_MaterialAspect mat = AIS_GraphicTool::GetMaterial(HasMaterial()? myDrawer : myDrawer->Link());
+    Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
+    Graphic3d_MaterialAspect mat = aDefaultMat;
+    if (HasMaterial() || myDrawer->HasLink())
+    {
+      mat = AIS_GraphicTool::GetMaterial(HasMaterial()? myDrawer : myDrawer->Link());
+    }
     if (HasMaterial())
     {
-      Quantity_Color aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
+      Quantity_Color aColor = aDefaultMat.AmbientColor();
+      if (myDrawer->HasLink())
+      {
+        aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
+      }
       mat.SetColor (aColor);
     }
     if (IsTransparent())
@@ -691,27 +722,56 @@ void AIS_Shape::UnsetColor()
 //purpose  :
 //=======================================================================
 
-void AIS_Shape::setWidth (const Handle(AIS_Drawer)& theDrawer,
-                          const Standard_Real       theLineWidth) const
+void AIS_Shape::setWidth (const Handle(Prs3d_Drawer)& theDrawer,
+                          const Standard_Real         theLineWidth) const
 {
-  if (!theDrawer->HasLineAspect())
+  if (!theDrawer->HasOwnLineAspect())
   {
     theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
+    }
   }
-  if (!theDrawer->HasWireAspect())
+  if (!theDrawer->HasOwnWireAspect())
   {
     theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
+    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();
+    }
+  }
+  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();
+    }
   }
-  // disable dedicated line aspects
-  theDrawer->SetFreeBoundaryAspect  (theDrawer->LineAspect());
-  theDrawer->SetUnFreeBoundaryAspect(theDrawer->LineAspect());
-  theDrawer->SetSeenLineAspect      (theDrawer->LineAspect());
 
   // override width
   theDrawer->LineAspect()->SetWidth (theLineWidth);
   theDrawer->WireAspect()->SetWidth (theLineWidth);
+  theDrawer->FreeBoundaryAspect()->SetWidth (theLineWidth);
+  theDrawer->UnFreeBoundaryAspect()->SetWidth (theLineWidth);
+  theDrawer->SeenLineAspect()->SetWidth (theLineWidth);
 }
 
 //=======================================================================
@@ -754,15 +814,52 @@ void AIS_Shape::UnsetWidth()
   }
   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.);
   }
   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 (theToKeepColor)
+  {
+    theDrawer->ShadingAspect()->SetColor (aColor, myCurrentFacingModel);
+  }
+  if (theToKeepTransp)
+  {
+    theDrawer->ShadingAspect()->SetTransparency (aTransp, myCurrentFacingModel);
+  }
+}
+
 //=======================================================================
 //function : SetMaterial
 //purpose  : 
@@ -780,20 +877,9 @@ 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();
-  }
+  setMaterial (myDrawer, theMat, HasColor(), IsTransparent());
   hasOwnMaterial = Standard_True;
 
-  myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
-  if (HasColor())
-  {
-    myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
-  }
-  myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
-
   // modify shading presentation without re-computation
   const PrsMgr_Presentations&        aPrsList  = Presentations();
   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
@@ -840,8 +926,11 @@ void AIS_Shape::UnsetMaterial()
   if (HasColor()
    || IsTransparent())
   {
-    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);
@@ -886,13 +975,16 @@ 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())
+  if (!theDrawer->HasOwnShadingAspect())
   {
     theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
-    *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
+    if (theDrawer->HasLink())
+    {
+      *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
+    }
   }
 
   // override transparency
@@ -945,7 +1037,7 @@ void AIS_Shape::SetTransparency (const Standard_Real theValue)
 void AIS_Shape::UnsetTransparency()
 {
   myTransparency = 0.0;
-  if (!myDrawer->HasShadingAspect())
+  if (!myDrawer->HasOwnShadingAspect())
   {
     return;
   }
@@ -1031,7 +1123,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;
 }
@@ -1044,7 +1136,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;
 
@@ -1058,7 +1150,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;
 
@@ -1072,7 +1164,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;
 
@@ -1173,7 +1265,7 @@ Standard_Boolean AIS_Shape::OwnDeviationCoefficient ( Standard_Real &  aCoeffici
 {
   aCoefficient = myDrawer->DeviationCoefficient();
   aPreviousCoefficient = myDrawer->PreviousDeviationCoefficient ();
-  return myDrawer->IsOwnDeviationCoefficient() ;
+  return myDrawer->HasOwnDeviationCoefficient() ;
 }
 
 //=======================================================================
@@ -1186,7 +1278,7 @@ Standard_Boolean AIS_Shape::OwnHLRDeviationCoefficient ( Standard_Real & aCoeffi
 {
   aCoefficient = myDrawer->HLRDeviationCoefficient();
   aPreviousCoefficient = myDrawer->PreviousHLRDeviationCoefficient ();
-  return myDrawer->IsOwnHLRDeviationCoefficient();
+  return myDrawer->HasOwnHLRDeviationCoefficient();
 
 }
 
@@ -1200,7 +1292,7 @@ Standard_Boolean AIS_Shape::OwnDeviationAngle ( Standard_Real &  anAngle,
 {
   anAngle = myDrawer->DeviationAngle();
   aPreviousAngle = myDrawer->PreviousDeviationAngle (); 
-  return myDrawer->IsOwnDeviationAngle();
+  return myDrawer->HasOwnDeviationAngle();
 }
 
 //=======================================================================
@@ -1213,5 +1305,5 @@ Standard_Boolean AIS_Shape::OwnHLRDeviationAngle ( Standard_Real &  anAngle,
 {
   anAngle = myDrawer->HLRAngle();
   aPreviousAngle = myDrawer->PreviousHLRDeviationAngle (); 
-  return myDrawer->IsOwnHLRDeviationAngle();
+  return myDrawer->HasOwnHLRDeviationAngle();
 }