0031153: Visualization - Non clear highlighting of selected trihedron elements
[occt.git] / src / AIS / AIS_Trihedron.cxx
index 2bdee5f..f6ed7e1 100644 (file)
 
 #include <AIS_Trihedron.hxx>
 
-#include <AIS_Axis.hxx>
 #include <AIS_InteractiveContext.hxx>
-#include <AIS_InteractiveObject.hxx>
-#include <AIS_Plane.hxx>
-#include <AIS_Point.hxx>
-#include <Aspect_TypeOfLine.hxx>
-#include <DsgPrs_DatumPrs.hxx>
+#include <AIS_TrihedronOwner.hxx>
 #include <Geom_Axis2Placement.hxx>
-#include <Geom_CartesianPoint.hxx>
-#include <Geom_Line.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_Point.hxx>
 #include <Geom_Transformation.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Ax2.hxx>
-#include <gp_Dir.hxx>
 #include <gp_Pnt.hxx>
-#include <gp_Trsf.hxx>
-#include <gp_Vec.hxx>
-#include <Graphic3d_AspectFillArea3d.hxx>
+#include <Graphic3d_ArrayOfPoints.hxx>
+#include <Graphic3d_ArrayOfSegments.hxx>
 #include <Graphic3d_AspectLine3d.hxx>
-#include <Graphic3d_MaterialAspect.hxx>
-#include <Graphic3d_Structure.hxx>
+#include <Graphic3d_ArrayOfPoints.hxx>
+#include <Graphic3d_ArrayOfPolylines.hxx>
+
+#include <Prs3d_Arrow.hxx>
 #include <Prs3d_ArrowAspect.hxx>
 #include <Prs3d_DatumAspect.hxx>
 #include <Prs3d_Drawer.hxx>
 #include <Prs3d_LineAspect.hxx>
+#include <Prs3d_PointAspect.hxx>
 #include <Prs3d_Presentation.hxx>
 #include <Prs3d_Projector.hxx>
+#include <Prs3d_ShadingAspect.hxx>
+#include <Prs3d_Text.hxx>
 #include <Prs3d_TextAspect.hxx>
-#include <Quantity_Color.hxx>
-#include <Select3D_SensitiveBox.hxx>
+#include <Prs3d_ToolSphere.hxx>
+
 #include <Select3D_SensitivePoint.hxx>
+#include <Select3D_SensitivePrimitiveArray.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <Select3D_SensitiveTriangle.hxx>
-#include <SelectBasics_EntityOwner.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <Standard_Type.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <UnitsAPI.hxx>
 
-IMPLEMENT_STANDARD_RTTIEXT(AIS_Trihedron,AIS_InteractiveObject)
+IMPLEMENT_STANDARD_RTTIEXT(AIS_Trihedron, AIS_InteractiveObject)
 
 //=======================================================================
 //function : AIS_Trihedron
-//purpose  : 
+//purpose  :
 //=======================================================================
-AIS_Trihedron::AIS_Trihedron(const Handle(Geom_Axis2Placement)& aComponent):
-myComponent (aComponent),
-myHasOwnSize (Standard_False),
-myHasOwnTextColor (Standard_False),
-myHasOwnArrowColor (Standard_False)
+AIS_Trihedron::AIS_Trihedron (const Handle(Geom_Axis2Placement)& theComponent)
+: myHasOwnSize (Standard_False),
+  myHasOwnTextColor (Standard_False),
+  myHasOwnArrowColor (Standard_False),
+  myTrihDispMode (Prs3d_DM_WireFrame),
+  myComponent (theComponent)
 {
-  LoadSubObjects();
+  myAutoHilight = Standard_False;
+
+  // selection priorities
+  mySelectionPriority.Bind (Prs3d_DP_None,   5); // complete triedron: priority 5 (same as faces)
+  mySelectionPriority.Bind (Prs3d_DP_Origin, 8); // origin: priority 8
+  for (int aPartIter = Prs3d_DP_XAxis; aPartIter <= Prs3d_DP_ZAxis; ++aPartIter)
+  {
+    mySelectionPriority.Bind ((Prs3d_DatumParts )aPartIter, 7); // axes: priority: 7
+  }
+  for (int aPartIter = Prs3d_DP_XOYAxis; aPartIter <= Prs3d_DP_XOZAxis; ++aPartIter)
+  {
+    mySelectionPriority.Bind ((Prs3d_DatumParts )aPartIter, 5); // planes: priority: 5
+  }
+  myHiddenLineAspect = new Graphic3d_AspectLine3d (Quantity_NOC_WHITE, Aspect_TOL_EMPTY, 1.0f);
+
+  // trihedron labels
+  myLabel.Bind (Prs3d_DP_XAxis, "X");
+  myLabel.Bind (Prs3d_DP_YAxis, "Y");
+  myLabel.Bind (Prs3d_DP_ZAxis, "Z");
 }
 
 //=======================================================================
 //function : SetComponent
-//purpose  : 
+//purpose  :
 //=======================================================================
-
-void AIS_Trihedron::SetComponent(const Handle(Geom_Axis2Placement)& aComponent)
+void AIS_Trihedron::SetComponent (const Handle(Geom_Axis2Placement)& theComponent)
 {
-  myComponent = aComponent;
-
-  // Remove from current context and nullify objects to update
-  Handle(AIS_InteractiveContext) anAISContext = GetContext();
-  Standard_Boolean hasContext = (anAISContext.IsNull() == Standard_False);
-  Standard_Integer anIdx;
-  for (anIdx = 0; anIdx < 7; anIdx++)
-  {
-    // Deselect object
-    if (hasContext)
-    {
-      if (anAISContext->IsSelected (myShapes[anIdx]))
-        anAISContext->AddOrRemoveSelected (myShapes[anIdx], Standard_False);
-
-      anAISContext->Remove (myShapes[anIdx], Standard_False);
-    }
-    myShapes[anIdx].Nullify();
-  }
-
-  LoadSubObjects();
+  myComponent = theComponent;
+  SetToUpdate();
 }
 
 //=======================================================================
-//function : setLocalTransformation
+//function : setOwnDatumAspect
 //purpose  :
 //=======================================================================
-
-void AIS_Trihedron::setLocalTransformation (const Handle(Geom_Transformation)& theTrsf)
+void AIS_Trihedron::setOwnDatumAspect()
 {
-  // Update location to the subshapes
-  Standard_Integer anIdx;
-  for (anIdx = 0; anIdx < 7; anIdx++)
-    myShapes[anIdx]->SetLocalTransformation (theTrsf);
+  if (myDrawer->HasOwnDatumAspect())
+    return;
+
+  Handle(Prs3d_DatumAspect) aNewAspect = new Prs3d_DatumAspect();
+  myDrawer->SetDatumAspect(aNewAspect);
 
-  AIS_InteractiveObject::setLocalTransformation (theTrsf);
+  if (myDrawer->Link().IsNull())
+    return;
+
+  myDrawer->DatumAspect()->SetDrawArrows (myDrawer->Link()->DatumAspect()->ToDrawArrows());
+  myDrawer->DatumAspect()->SetDrawLabels (myDrawer->Link()->DatumAspect()->ToDrawLabels());
+  *myDrawer->DatumAspect()->TextAspect()->Aspect() =
+                                     *myDrawer->Link()->DatumAspect()->TextAspect()->Aspect();
+  *myDrawer->DatumAspect()->PointAspect()->Aspect() =
+                                     *myDrawer->Link()->DatumAspect()->PointAspect()->Aspect();
+  *myDrawer->DatumAspect()->ArrowAspect()->Aspect() =
+                                     *myDrawer->Link()->DatumAspect()->ArrowAspect()->Aspect();
+
+  for (int aPartIter = Prs3d_DP_Origin; aPartIter <= Prs3d_DP_XOZAxis; ++aPartIter)
+  {
+    const Prs3d_DatumParts aPart = (Prs3d_DatumParts )aPartIter;
+    if (!aNewAspect->LineAspect(aPart).IsNull())
+      *myDrawer->DatumAspect()->LineAspect(aPart)->Aspect() =
+                                 *myDrawer->Link()->DatumAspect()->LineAspect(aPart)->Aspect();
+    if (!aNewAspect->ShadingAspect(aPart).IsNull())
+      *myDrawer->DatumAspect()->ShadingAspect(aPart)->Aspect() =
+                                 *myDrawer->Link()->DatumAspect()->ShadingAspect(aPart)->Aspect();
+  }
 }
 
 //=======================================================================
 //function : SetSize
-//purpose  : 
+//purpose  :
 //=======================================================================
 void AIS_Trihedron::SetSize(const Standard_Real aValue)
 {
   myHasOwnSize = Standard_True;
-  if(!myDrawer->HasOwnDatumAspect()){
-    Handle (Prs3d_DatumAspect) DA = new Prs3d_DatumAspect();
-    myDrawer->SetDatumAspect(DA);
-  }
-  
-  myDrawer->DatumAspect()->SetAxisLength(aValue,aValue,aValue);
-  
-  for(Standard_Integer i=4;i<=6;i++) 
-    Handle(AIS_Plane)::DownCast (myShapes[i])->SetSize(aValue);
 
-  Update();
+  setOwnDatumAspect();
+  myDrawer->DatumAspect()->SetAxisLength(aValue, aValue, aValue);
+
+  SetToUpdate();
   UpdateSelection();
 }
 
-
-
 //=======================================================================
 //function : UnsetSize
-//purpose  : if the object has 1 color, the default size of the 
-//           drawer is reproduced, otherwise DatumAspect becomes null
+//purpose  :
 //=======================================================================
-
 void AIS_Trihedron::UnsetSize()
 {
-  if(!myHasOwnSize) return;
-  
+  if (!myHasOwnSize)
+  {
+    return;
+  }
+
   myHasOwnSize = Standard_False;
-  if(hasOwnColor){
-    const Handle(Prs3d_DatumAspect) DA =
-      myDrawer->HasLink() ? myDrawer->Link()->DatumAspect() : new Prs3d_DatumAspect();
-    myDrawer->DatumAspect()->SetAxisLength(DA->FirstAxisLength(),
-                                          DA->SecondAxisLength(),
-                                          DA->ThirdAxisLength());
+  if (hasOwnColor)
+  {
+    const Handle(Prs3d_DatumAspect) DA = myDrawer->HasLink()
+                                       ? myDrawer->Link()->DatumAspect()
+                                       : new Prs3d_DatumAspect();
+    myDrawer->DatumAspect()->SetAxisLength (DA->AxisLength (Prs3d_DP_XAxis),
+                                            DA->AxisLength (Prs3d_DP_YAxis),
+                                            DA->AxisLength (Prs3d_DP_ZAxis));
   }
   else
   {
-    myDrawer->SetDatumAspect (Handle(Prs3d_DatumAspect)());
+    SetToUpdate();
   }
-  Update();
   UpdateSelection();
-
 }
 
 //=======================================================================
 //function : Size
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 Standard_Real AIS_Trihedron::Size() const 
 {
-  return myDrawer->DatumAspect()->FirstAxisLength();
+  return myDrawer->DatumAspect()->AxisLength(Prs3d_DP_XAxis);
 }
 
 //=======================================================================
-//function : XAxis
-//purpose  : 
+//function : Compute
+//purpose  :
 //=======================================================================
-Handle(AIS_Axis) AIS_Trihedron::XAxis() const 
+void AIS_Trihedron::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
+                             const Handle(Prs3d_Presentation)& thePrs,
+                             const Standard_Integer theMode)
 {
-  Handle(AIS_Axis) anAxis = Handle(AIS_Axis)::DownCast(myShapes[1]);
-  if (anAxis.IsNull())
+  if (theMode != 0)
   {
-    anAxis = new AIS_Axis (myComponent,AIS_TOAX_XAxis);
+    return;
   }
-  return anAxis;
+
+  thePrs->SetInfiniteState (Standard_True);
+
+  gp_Ax2 anAxis (myComponent->Ax2());
+  updatePrimitives (myDrawer->DatumAspect(), myTrihDispMode, anAxis.Location(),
+                    anAxis.XDirection(), anAxis.YDirection(), anAxis.Direction());
+  computePresentation (thePrsMgr, thePrs);
 }
 
 //=======================================================================
-//function : YAxis
-//purpose  : 
+//function : Compute
+//purpose  :
 //=======================================================================
-Handle(AIS_Axis) AIS_Trihedron::YAxis() const 
+void AIS_Trihedron::Compute (const Handle(Prs3d_Projector)& theProjector,
+                             const Handle(Geom_Transformation)& theTrsf,
+                             const Handle(Prs3d_Presentation)& thePrs)
 {
-  Handle(AIS_Axis) anAxis = Handle(AIS_Axis)::DownCast(myShapes[2]);
-  if (anAxis.IsNull())
-  {
-    anAxis = new AIS_Axis (myComponent,AIS_TOAX_YAxis);
-  }
-
-  return anAxis;
+  PrsMgr_PresentableObject::Compute (theProjector, theTrsf, thePrs);
 }
 
 //=======================================================================
-//function : Axis
-//purpose  : 
+//function : ComputeSelection
+//purpose  :
 //=======================================================================
-Handle(AIS_Axis) AIS_Trihedron::Axis() const 
+void AIS_Trihedron::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
+                                      const Standard_Integer theMode)
 {
-  Handle(AIS_Axis) anAxis = Handle(AIS_Axis)::DownCast(myShapes[3]);
-  if (anAxis.IsNull())
+  Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
+  switch (theMode)
   {
-    anAxis = new AIS_Axis (myComponent,AIS_TOAX_ZAxis);
+    case AIS_TrihedronSelectionMode_EntireObject:
+    {
+      Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (
+                                        this, mySelectionPriority.Find (Prs3d_DP_None));
+      const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
+      for (int aPartIter = isShadingMode ? Prs3d_DP_Origin : Prs3d_DP_XAxis; aPartIter <= Prs3d_DP_ZAxis;
+           ++aPartIter)
+      {
+        const Prs3d_DatumParts aPart = (Prs3d_DatumParts )aPartIter;
+        if (!anAspect->DrawDatumPart (aPart))
+        {
+          continue;
+        }
+        theSelection->Add (createSensitiveEntity (aPart, anOwner));
+      }
+      break;
+    }
+    case AIS_TrihedronSelectionMode_Origin:
+    {
+      const Prs3d_DatumParts aPart = Prs3d_DP_Origin;
+      if (anAspect->DrawDatumPart (aPart))
+      {
+        Handle(SelectMgr_EntityOwner) anOwner = new AIS_TrihedronOwner (this, aPart,
+                                                                 mySelectionPriority.Find (aPart));
+        Handle(Graphic3d_ArrayOfPrimitives) aPrimitives = arrayOfPrimitives(aPart);
+        theSelection->Add (createSensitiveEntity (aPart, anOwner));
+      }
+      break;
+    }
+    case AIS_TrihedronSelectionMode_Axes:
+    {
+      for (int aPartIter = Prs3d_DP_XAxis; aPartIter <= Prs3d_DP_ZAxis; ++aPartIter)
+      {
+        const Prs3d_DatumParts aPart = (Prs3d_DatumParts )aPartIter;
+        if (!anAspect->DrawDatumPart (aPart))
+        {
+          continue;
+        }
+        Handle(SelectMgr_EntityOwner) anOwner = new AIS_TrihedronOwner (this, aPart,
+                                                                        mySelectionPriority.Find (aPart));
+        theSelection->Add (createSensitiveEntity (aPart, anOwner));
+      }
+      break;
+    }
+    case AIS_TrihedronSelectionMode_MainPlanes:
+    {
+      // create owner for each trihedron plane
+      {
+        for (int aPartIter = Prs3d_DP_XOYAxis; aPartIter <= Prs3d_DP_XOZAxis; ++aPartIter)
+        {
+          const Prs3d_DatumParts aPart = (Prs3d_DatumParts )aPartIter;
+          if (!anAspect->DrawDatumPart (aPart))
+          {
+            continue;
+          }
+          Handle(SelectMgr_EntityOwner) anOwner = new AIS_TrihedronOwner (this, aPart,
+                                                                          mySelectionPriority.Find (aPart));
+          theSelection->Add (createSensitiveEntity (aPart, anOwner));
+        }
+      }
+      break;
+    }
   }
-  return anAxis;
 }
 
 //=======================================================================
-//function : Position
-//purpose  : 
+//function : HilightOwnerWithColor
+//purpose  :
 //=======================================================================
-Handle(AIS_Point) AIS_Trihedron::Position() const 
+void AIS_Trihedron::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                           const Handle(Prs3d_Drawer)& theStyle,
+                                           const Handle(SelectMgr_EntityOwner)& theOwner)
 {
-  Handle(AIS_Point) aPt = Handle(AIS_Point)::DownCast(myShapes[0]);
-  if (aPt.IsNull()) {
-    gp_Pnt aPnt = myComponent->Ax2().Location();
-    Handle(Geom_Point) aPoint = new Geom_CartesianPoint(aPnt);
-    aPt = new AIS_Point (aPoint);
+  Handle(AIS_TrihedronOwner) anOwner = Handle(AIS_TrihedronOwner)::DownCast (theOwner);
+  if (anOwner.IsNull())
+  {
+    /// default 0 selection mode
+    Standard_Integer aHiMode = HasHilightMode() ? HilightMode() : 0;
+    thePM->Color (this, theStyle, aHiMode, NULL, Graphic3d_ZLayerId_Top);
+    return;
   }
-  return aPt;
-}
 
-//=======================================================================
-//function : XYPlane
-//purpose  : 
-//=======================================================================
-Handle(AIS_Plane) AIS_Trihedron::XYPlane() const 
-{
-  Handle(AIS_Plane) aPl = Handle(AIS_Plane)::DownCast(myShapes[4]);
-  if (aPl.IsNull()) aPl = new AIS_Plane (myComponent,AIS_TOPL_XYPlane);
-  return aPl;
-}
+  Handle(Prs3d_Presentation) aPresentation = GetHilightPresentation (thePM);
+  if (aPresentation.IsNull())
+  {
+    return;
+  }
 
-//=======================================================================
-//function : XZPlane
-//purpose  : 
-//=======================================================================
-Handle(AIS_Plane) AIS_Trihedron::XZPlane() const 
-{
-  Handle(AIS_Plane) aPl = Handle(AIS_Plane)::DownCast(myShapes[5]);
-  if (aPl.IsNull()) aPl = new AIS_Plane (myComponent,AIS_TOPL_XZPlane);
-  return aPl;
-}
+  aPresentation->Clear();
+  const Prs3d_DatumParts aPart = anOwner->DatumPart();
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPresentation);
+  if (aPart >= Prs3d_DP_XOYAxis && aPart <= Prs3d_DP_XOZAxis)
+  {
+    // planes selection is equal in both shading and wireframe mode
+    aGroup->SetGroupPrimitivesAspect (theStyle->LineAspect()->Aspect());
+  }
+  else
+  {
+    if (myTrihDispMode == Prs3d_DM_Shaded)
+    {
+      aGroup->SetGroupPrimitivesAspect (theStyle->ShadingAspect()->Aspect());
+    }
+    else
+    {
+      if (aPart == Prs3d_DP_Origin)
+      {
+        aGroup->SetGroupPrimitivesAspect (theStyle->PointAspect()->Aspect());
+      }
+      else
+      {
+        aGroup->SetGroupPrimitivesAspect(theStyle->LineAspect()->Aspect());
+      }
+    }
+  }
+  aGroup->AddPrimitiveArray (arrayOfPrimitives(aPart));
 
-//=======================================================================
-//function : YZPlane
-//purpose  : 
-//=======================================================================
-Handle(AIS_Plane) AIS_Trihedron::YZPlane() const 
-{
-  Handle(AIS_Plane) aPl = Handle(AIS_Plane)::DownCast(myShapes[6]);
-  if (aPl.IsNull()) aPl = new AIS_Plane (myComponent,AIS_TOPL_YZPlane);
-  return aPl;
+  const Graphic3d_ZLayerId aLayer = theStyle->ZLayer() != Graphic3d_ZLayerId_UNKNOWN ? theStyle->ZLayer() : myDrawer->ZLayer();
+  if (aPresentation->GetZLayer() != aLayer)
+  {
+    aPresentation->SetZLayer (aLayer);
+  }
+
+  aPresentation->Highlight (theStyle);
+  thePM->AddToImmediateList (aPresentation);
 }
 
-//=======================================================================
-//function : Compute
-//purpose  : 
-//=======================================================================
-void AIS_Trihedron::Compute(
- const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
- const Handle(Prs3d_Presentation)& aPresentation, 
- const Standard_Integer aMode)
+//========================================================================
+//function : HilightSelected
+//purpose  :
+//========================================================================
+void AIS_Trihedron::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                     const SelectMgr_SequenceOfOwner& theOwners)
 {
-  aPresentation->SetInfiniteState (Standard_True);
-  switch(aMode){
-  case 0: 
-    DsgPrs_DatumPrs::Add(aPresentation,myComponent->Ax2(),myDrawer);
-    break;
-  case 1:
-    break;
-  case 2:
-    break;
+  if (theOwners.IsEmpty() || !HasInteractiveContext())
+  {
+    return;
+  }
+
+  const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
+
+  Handle(Prs3d_Drawer) anAspect = !myHilightDrawer.IsNull() ? myHilightDrawer : GetContext()->SelectionStyle();
+  for (SelectMgr_SequenceOfOwner::Iterator anIterator (theOwners); anIterator.More(); anIterator.Next())
+  {
+    const Handle(SelectMgr_EntityOwner)& anOwner = anIterator.Value();
+    Handle(AIS_TrihedronOwner) aTrihedronOwner = Handle(AIS_TrihedronOwner)::DownCast(anOwner);
+    if (aTrihedronOwner.IsNull())
+    {
+      thePM->Color (this, anAspect, 0);
+      continue;
+    }
+      
+    const Prs3d_DatumParts aPart = aTrihedronOwner->DatumPart();
+    Handle(Graphic3d_Group) aGroup;
+    if (mySelectedParts.Contains (aPart) || !myPartToGroup.Find (aPart, aGroup))
+    {
+      continue;
+    }
+
+    if (aPart >= Prs3d_DP_XOYAxis
+     && aPart <= Prs3d_DP_XOZAxis)
+    {
+      aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect()->Aspect());
+    }
+    else
+    {
+      if (isShadingMode)
+      {
+        aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect()->Aspect());
+      }
+      else
+      {
+        if (aPart == Prs3d_DP_Origin)
+        {
+          aGroup->SetGroupPrimitivesAspect (anAspect->PointAspect()->Aspect());
+        }
+        else
+        {
+          aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect()->Aspect());
+        }
+      }
+    }
+    mySelectedParts.Append (aPart);
   }
 }
 
 //=======================================================================
-//function : Compute
-//purpose  : 
+//function : ClearSelected
+//purpose  :
 //=======================================================================
-
-void AIS_Trihedron::Compute(const Handle(Prs3d_Projector)& aProjector,
-                            const Handle(Geom_Transformation)& aTransformation,
-                            const Handle(Prs3d_Presentation)& aPresentation)
+void AIS_Trihedron::ClearSelected()
 {
-// Standard_NotImplemented::Raise("AIS_Trihedron::Compute(const Handle(Prs3d_Projector)&, const Handle(Geom_Transformation)&, const Handle(Prs3d_Presentation)&)");
- PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation) ;
+  Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
+  const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
+  for (NCollection_List<Prs3d_DatumParts>::Iterator anIterator (mySelectedParts); anIterator.More();
+       anIterator.Next())
+  {
+    const Prs3d_DatumParts aPart = anIterator.Value();
+    Handle(Graphic3d_Group) aGroup = myPartToGroup.Find (aPart);
+    if (aPart >= Prs3d_DP_XOYAxis
+     && aPart <= Prs3d_DP_XOZAxis)
+    {
+      aGroup->SetGroupPrimitivesAspect (myHiddenLineAspect);
+    }
+    else if (isShadingMode)
+    {
+      aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
+    }
+    else
+    {
+      if (aPart == Prs3d_DP_Origin)
+      {
+        aGroup->SetGroupPrimitivesAspect (anAspect->PointAspect()->Aspect());
+      }
+      else
+      {
+        aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
+      }
+    }
+  }
+  mySelectedParts.Clear();
 }
 
 //=======================================================================
-//function : ComputeSelection
-//purpose  : 
+//function : computePresentation
+//purpose  :
 //=======================================================================
-
-void AIS_Trihedron::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
-                                     const Standard_Integer aMode)
+void AIS_Trihedron::computePresentation (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
+                                         const Handle(Prs3d_Presentation)& thePrs)
 {
-  // retrieve the tops of the trihedron.
-  Standard_Integer Prior, anIdx;
-  Handle(SelectMgr_EntityOwner) eown;
-  TColgp_Array1OfPnt PP(1,4),PO(1,4);
-  ExtremityPoints(PP);
-
-  // remove shapes from active selections
-  Handle(AIS_InteractiveContext) anAISContext = GetContext();
-  if (!anAISContext.IsNull())
-    for (anIdx = 0; anIdx < 7; anIdx++)
+  myPartToGroup.Clear();
+  Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
+  const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
+  // display origin
+  {
+    // Origin is visualized only in shading mode
+    Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
+    const Prs3d_DatumParts aPart = Prs3d_DP_Origin;
+    if (anAspect->DrawDatumPart(aPart))
     {
-      // Deselect object
-      if (anAISContext->IsSelected (myShapes[anIdx]))
-        anAISContext->AddOrRemoveSelected (myShapes[anIdx], Standard_False);
-
-      anAISContext->Remove (myShapes[anIdx], Standard_False);
-    }
-  
-  switch (aMode) {
-  case 0:
-    {   // complete triedron only 1 owner : this... priority 5 (same as faces)
-      Prior = 5;
-      eown = new SelectMgr_EntityOwner(this,Prior);
-      for (Standard_Integer i=1; i<=3;i++)
-       aSelection->Add(new Select3D_SensitiveSegment(eown,PP(1),PP(i+1)));
-      break;
+      myPartToGroup.Bind (aPart, aGroup);
+      if (isShadingMode)
+      {
+        aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
+      }
+      else
+      {
+        aGroup->SetGroupPrimitivesAspect (anAspect->PointAspect()->Aspect());
+      }
+      aGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
     }
-  case 1:
-    {  //origin : 
-      Prior = 8;
-      const Handle(SelectMgr_SelectableObject)& anObj = myShapes[0]; // to avoid ambiguity
-      eown= new SelectMgr_EntityOwner(anObj,Prior);
-      
-      aSelection->Add(new Select3D_SensitivePoint (eown,myComponent->Location()));
-      // If the trihedron's shapes display and selection modes are the same
-      // the shapes are still displayed after selection, so we need to
-      // use different presentation and hide it by nullifying
-      if (!anAISContext.IsNull())
+  }
+
+  // display axes
+  {
+    for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
+    {
+      Prs3d_DatumParts aPart = (Prs3d_DatumParts )anAxisIter;
+      if (!anAspect->DrawDatumPart (aPart))
       {
-        anAISContext->Display (myShapes[0], 1, 0, Standard_False);
-        anAISContext->ClearPrs (myShapes[0], 1, Standard_False);
+        continue;
       }
-      
-      break;
+
+      Handle(Graphic3d_Group) anAxisGroup = Prs3d_Root::NewGroup (thePrs);
+      myPartToGroup.Bind (aPart, anAxisGroup);
+      if (isShadingMode)
+      {
+        anAxisGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
+      }
+      else
+      {
+        anAxisGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
+      }
+      anAxisGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
+
+      // draw arrow
+      Prs3d_DatumParts anArrowPart = anAspect->ArrowPartForAxis (aPart);
+      if (!anAspect->DrawDatumPart (anArrowPart))
+      {
+        continue;
+      }
+
+      Handle(Graphic3d_Group) anArrowGroup = Prs3d_Root::NewGroup (thePrs);
+      anArrowGroup->SetGroupPrimitivesAspect (anAspect->ArrowAspect()->Aspect());
+      anArrowGroup->AddPrimitiveArray (arrayOfPrimitives (anArrowPart));
     }
-  case 2:
-    {  //axes ... priority 7
-      Prior = 7;
-      for (Standard_Integer i=1; i<=3;i++){
-        const Handle(SelectMgr_SelectableObject)& anObj = myShapes[i]; // to avoid ambiguity
-       eown= new SelectMgr_EntityOwner(anObj,Prior);
-       aSelection->Add(new Select3D_SensitiveSegment(eown,PP(1),PP(i+1)));
+  }
 
+  // display labels
+  if (anAspect->ToDrawLabels())
+  {
+    Handle(Geom_Axis2Placement) aComponent = myComponent;
+    const gp_Pnt anOrigin = aComponent->Location();
+    for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
+    {
+      const Prs3d_DatumParts aPart = (Prs3d_DatumParts )anAxisIter;
+      if (!anAspect->DrawDatumPart (aPart))
+      {
+        continue;
       }
 
-      // If the trihedron's shapes display and selection modes are the same
-      // the shapes are still displayed after selection, so we need to
-      // use different presentation and hide it by nullifying
-      AIS_TypeOfAxis anAxisType;
-      if (!anAISContext.IsNull())
-        for (anIdx = 1; anIdx <= 3; anIdx++)
-        {
-          // update AIS_Axis for selection
-          Handle(AIS_Axis) anAxis = Handle(AIS_Axis)::DownCast(myShapes[anIdx]);
-          Handle(Prs3d_Drawer) aDrawer = anAxis->Attributes();
-          Handle(Prs3d_DatumAspect) aDatum = myDrawer->DatumAspect();
-          aDrawer->SetDatumAspect (aDatum);
-          anAxisType = anAxis->TypeOfAxis();
-          anAxis->SetAxis2Placement (myComponent, anAxisType);
-
-          // display
-          anAISContext->Display (myShapes[anIdx], 1, 0, Standard_False);
-          anAISContext->ClearPrs (myShapes[anIdx], 1, Standard_False);
-        }
-      
-      break;
+      const Standard_Real anAxisLength = anAspect->AxisLength (aPart);
+      const TCollection_ExtendedString& aLabel = myLabel.Find (aPart);
+      gp_Dir aDir;
+      switch (aPart)
+      {
+        case Prs3d_DP_XAxis: aDir = aComponent->XDirection(); break;
+        case Prs3d_DP_YAxis: aDir = aComponent->YDirection(); break;
+        case Prs3d_DP_ZAxis: aDir = aComponent->Direction();  break;
+        default: break;
+      }
+      Handle(Graphic3d_Group) aLabelGroup = Prs3d_Root::NewGroup (thePrs);
+      const gp_Pnt aPoint = anOrigin.XYZ() + aDir.XYZ() * anAxisLength;
+      Prs3d_Text::Draw (aLabelGroup, anAspect->TextAspect(), aLabel, aPoint);
     }
-    
-  case 3:
-    {  // main planes priority 6
-//      PO(1) = PP(1);
-//      PO(4) = PP(1);
-      Prior =5;
-      
-      
-      const Handle(SelectMgr_SelectableObject)& anObj4 = myShapes[4]; // to avoid ambiguity
-      eown= new SelectMgr_EntityOwner(anObj4,Prior);
-//      PO(2) = PP(2);PO(3) = PP(3);
-      aSelection->Add(new Select3D_SensitiveTriangle(eown,PP(1),PP(2),PP(3)));
-
-      const Handle(SelectMgr_SelectableObject)& anObj5 = myShapes[5]; // to avoid ambiguity
-      eown= new SelectMgr_EntityOwner(anObj5,Prior);
-//      PO(2) = PP(3);PO(3) = PP(4);
-      aSelection->Add(new Select3D_SensitiveTriangle(eown,PP(1),PP(2),PP(4)));
-
-      const Handle(SelectMgr_SelectableObject)& anObj6 = myShapes[6]; // to avoid ambiguity
-      eown= new SelectMgr_EntityOwner(anObj6,Prior);
-//      PO(2) = PP(4);PO(3) = PP(2);
-      aSelection->Add(new Select3D_SensitiveTriangle(eown,PP(1),PP(3),PP(4)));
-      
-      // If the trihedron's shapes display and selection modes are the same
-      // the shapes are still displayed after selection, so we need to
-      // use different presentation and hide it by nullifying
-      if (!anAISContext.IsNull())
-        for (anIdx = 4; anIdx < 7; anIdx++)
-       {
-          anAISContext->Display (myShapes[anIdx], 1, 0, Standard_False);
-          anAISContext->ClearPrs (myShapes[anIdx], 1, Standard_False);
-        }
+  }
+
+  // planes invisible group for planes selection
+  for (Standard_Integer anAxisIter = Prs3d_DP_XOYAxis; anAxisIter <= Prs3d_DP_XOZAxis; ++anAxisIter)
+  {
+    Prs3d_DatumParts aPart = (Prs3d_DatumParts)anAxisIter;
+    if (!anAspect->DrawDatumPart(aPart))
+    {
+      continue;
     }
+
+    Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
+    myPartToGroup.Bind (aPart, aGroup);
+
+    aGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
+    aGroup->SetGroupPrimitivesAspect (myHiddenLineAspect);
   }
-  
 }
 
 //=======================================================================
 //function : SetColor
-//purpose  : 
+//purpose  :
 //=======================================================================
-
-void AIS_Trihedron::SetColor(const Quantity_NameOfColor aCol)
+void AIS_Trihedron::SetDatumPartColor (const Prs3d_DatumParts thePart,
+                                       const Quantity_Color&  theColor)
 {
-  SetColor(Quantity_Color(aCol));
-}
-
-void AIS_Trihedron::SetColor(const Quantity_Color &aCol)
-{
-  hasOwnColor=Standard_True;
-  myOwnColor = aCol;
-  
-  if(!myDrawer->HasOwnDatumAspect()){
-    Handle (Prs3d_DatumAspect) DA = new Prs3d_DatumAspect();
-    
-    DA->SetAxisLength(myDrawer->DatumAspect()->FirstAxisLength(),
-                     myDrawer->DatumAspect()->SecondAxisLength(),
-                     myDrawer->DatumAspect()->ThirdAxisLength());
-    myDrawer->SetDatumAspect(DA);
-  }
-  myDrawer->DatumAspect()->FirstAxisAspect()->SetColor(aCol);
-  myDrawer->DatumAspect()->SecondAxisAspect()->SetColor(aCol);
-  myDrawer->DatumAspect()->ThirdAxisAspect()->SetColor(aCol);
+  setOwnDatumAspect();
 
+  myDrawer->DatumAspect()->ShadingAspect (thePart)->SetColor (theColor);
+  if (thePart != Prs3d_DP_Origin)
+  {
+    myDrawer->DatumAspect()->LineAspect (thePart)->SetColor (theColor);
+  }
 }
 
 //=======================================================================
 //function : SetTextColor
-//purpose  : 
+//purpose  :
 //=======================================================================
-
-void AIS_Trihedron::SetTextColor(const Quantity_NameOfColor aCol)
+void AIS_Trihedron::SetTextColor (const Quantity_Color& theColor)
 {
-  myHasOwnTextColor = Standard_True;
-  myOwnTextColor = aCol;
-  
-  if(!myDrawer->HasOwnDatumAspect()){
-    Handle (Prs3d_DatumAspect) DA = new Prs3d_DatumAspect();
-    
-    DA->SetAxisLength(myDrawer->DatumAspect()->FirstAxisLength(),
-                     myDrawer->DatumAspect()->SecondAxisLength(),
-                     myDrawer->DatumAspect()->ThirdAxisLength());
-    myDrawer->SetDatumAspect(DA);
-  }
-  Handle(Prs3d_TextAspect) aspect = myDrawer->TextAspect();
-  aspect->SetColor(aCol);
-  myDrawer->SetTextAspect(aspect);
+  setOwnDatumAspect();
+  myDrawer->DatumAspect()->TextAspect()->SetColor (theColor);
 }
 
-void AIS_Trihedron::SetArrowColor(const Quantity_NameOfColor aCol)
+//=======================================================================
+//function : Color
+//purpose  :
+//=======================================================================
+Quantity_Color AIS_Trihedron::DatumPartColor (Prs3d_DatumParts thePart)
 {
-  myHasOwnArrowColor = Standard_True;
-  myOwnArrowColor = aCol;
-  
-  if(!myDrawer->HasOwnDatumAspect()){
-    Handle (Prs3d_DatumAspect) DA = new Prs3d_DatumAspect();
-    
-    DA->SetAxisLength(myDrawer->DatumAspect()->FirstAxisLength(),
-                     myDrawer->DatumAspect()->SecondAxisLength(),
-                     myDrawer->DatumAspect()->ThirdAxisLength());
-    myDrawer->SetDatumAspect(DA);
-  }
-  Handle(Prs3d_ArrowAspect) aspect = myDrawer->ArrowAspect();
-  aspect->SetColor(aCol);
-  myDrawer->SetArrowAspect(aspect);
+  if (myTrihDispMode == Prs3d_DM_Shaded)
+  {
+    return myDrawer->DatumAspect()->ShadingAspect (thePart)->Color();
+  }
+  else
+  {
+    return myDrawer->DatumAspect()->LineAspect (thePart)->Aspect()->Color();
+  }
 }
 
 //=======================================================================
-Standard_Boolean AIS_Trihedron::HasTextColor() const {
-
-  return myHasOwnTextColor;
-}
-
+//function : SetOriginColor
+//purpose  :
 //=======================================================================
-Quantity_NameOfColor AIS_Trihedron::TextColor() const {
-
-  return myOwnTextColor;
+void AIS_Trihedron::SetOriginColor (const Quantity_Color& theColor)
+{
+  if (myTrihDispMode == Prs3d_DM_Shaded)
+  {
+    SetDatumPartColor (Prs3d_DP_Origin, theColor);
+  }
 }
 
 //=======================================================================
-Standard_Boolean AIS_Trihedron::HasArrowColor() const {
-
-  return myHasOwnArrowColor;
+//function : SetXAxisColor
+//purpose  :
+//=======================================================================
+void AIS_Trihedron::SetXAxisColor (const Quantity_Color& theColor)
+{
+  SetDatumPartColor (Prs3d_DP_XAxis, theColor);
 }
 
 //=======================================================================
-Quantity_NameOfColor AIS_Trihedron::ArrowColor() const {
-
-  return myOwnArrowColor;
+//function : SetYAxisColor
+//purpose  :
+//=======================================================================
+void AIS_Trihedron::SetYAxisColor (const Quantity_Color& theColor)
+{
+  SetDatumPartColor (Prs3d_DP_YAxis, theColor);
 }
 
-
 //=======================================================================
-//function : Compute
-//purpose  : to avoid warning
+//function : SetAxisColor
+//purpose  :
 //=======================================================================
-void AIS_Trihedron::Compute(const Handle(Prs3d_Projector)&, 
-                              const Handle(Prs3d_Presentation)&)
+void AIS_Trihedron::SetAxisColor (const Quantity_Color& theColor)
 {
+  SetDatumPartColor (Prs3d_DP_ZAxis, theColor);
 }
+
 //=======================================================================
-//function : Type
-//purpose  : 
+//function : SetColor
+//purpose  :
 //=======================================================================
+void AIS_Trihedron::SetColor (const Quantity_Color& theColor)
+{
+  hasOwnColor = Standard_True;
+  myDrawer->SetColor (theColor);
 
-AIS_KindOfInteractive AIS_Trihedron::Type() const 
-{return AIS_KOI_Datum;}
-
+  SetDatumPartColor (Prs3d_DP_Origin, theColor);
+  SetDatumPartColor (Prs3d_DP_XAxis,  theColor);
+  SetDatumPartColor (Prs3d_DP_YAxis,  theColor);
+  SetDatumPartColor (Prs3d_DP_ZAxis,  theColor);
+}
 
 //=======================================================================
-//function : Signature
-//purpose  : 
+//function : SetArrowColor
+//purpose  :
 //=======================================================================
+void AIS_Trihedron::SetArrowColor (const Quantity_Color& theColor)
+{
+  setOwnDatumAspect();
 
- Standard_Integer AIS_Trihedron::Signature() const 
-{return 3;}
+  myHasOwnArrowColor = Standard_True;
+  myDrawer->DatumAspect()->ArrowAspect()->SetColor (theColor);
+}
 
 //=======================================================================
-//function : ExtremityPoints
-//purpose  : to avoid warning
+//function : TextColor
+//purpose  :
 //=======================================================================
-void  AIS_Trihedron::ExtremityPoints(TColgp_Array1OfPnt& PP) const 
+Quantity_Color AIS_Trihedron::TextColor() const
 {
-  gp_Ax2 theax(myComponent->Ax2());
-  PP(1) = theax.Location();
-
-  Standard_Real len = myDrawer->DatumAspect()->FirstAxisLength();
-  gp_Vec vec = theax.XDirection();
-  vec *= len;
-  PP(2) = PP(1).Translated(vec);
-  
-  len = myDrawer->DatumAspect()->SecondAxisLength();
-  vec = theax.YDirection();
-  vec *= len;
-  PP(3) = PP(1).Translated(vec);
-
-  len = myDrawer->DatumAspect()->ThirdAxisLength();
-  vec = theax.Direction();
-  vec *= len;
-  PP(4) = PP(1).Translated(vec);
+  return myDrawer->DatumAspect()->TextAspect()->Aspect()->Color();
 }
 
 //=======================================================================
-//function : AcceptDisplayMode
-//purpose  : 
+//function : ArrowColor
+//purpose  :
 //=======================================================================
-
- Standard_Boolean  AIS_Trihedron::
-AcceptDisplayMode(const Standard_Integer aMode) const
-{return aMode == 0;}
-
-
+Quantity_Color AIS_Trihedron::ArrowColor() const
+{
+  return myDrawer->DatumAspect()->ArrowAspect()->Aspect()->Color();
+}
 
 //=======================================================================
 //function : UnsetColor
 //purpose  : 
 //=======================================================================
-
 void AIS_Trihedron::UnsetColor()
 {
-  hasOwnColor=Standard_False;
-  myOwnColor = Quantity_NOC_LIGHTSTEELBLUE4;
-  myDrawer->DatumAspect()->FirstAxisAspect()->SetColor(myOwnColor);
-  myDrawer->DatumAspect()->SecondAxisAspect()->SetColor(myOwnColor);
-  myDrawer->DatumAspect()->ThirdAxisAspect()->SetColor(myOwnColor);
-  if( HasTextColor() ) {
-    SetTextColor(myOwnColor.Name());
+  hasOwnColor = Standard_False;
+  Quantity_Color aDefaultColor (Quantity_NOC_LIGHTSTEELBLUE4);
+  SetColor (aDefaultColor);
+  if (HasTextColor())
+  {
+    SetTextColor (aDefaultColor);
     myHasOwnTextColor = Standard_False;
   }
-  if( HasArrowColor() ) {
-    SetArrowColor(myOwnColor.Name());
+  if (HasArrowColor())
+  {
+    SetArrowColor (aDefaultColor);
     myHasOwnArrowColor = Standard_False;
   }
-  
 }
 
 //=======================================================================
-//function : UnsetWitdth
-//purpose  : 
+//function : ToDrawArrows
+//purpose  :
 //=======================================================================
-
-void AIS_Trihedron::UnsetWidth()
+Standard_Boolean AIS_Trihedron::ToDrawArrows() const
 {
-  myOwnWidth =0.0;
-  myDrawer->DatumAspect()->FirstAxisAspect()->SetWidth(1.);
-  myDrawer->DatumAspect()->SecondAxisAspect()->SetWidth(1.);
-  myDrawer->DatumAspect()->ThirdAxisAspect()->SetWidth(1.);
-
+  return myDrawer->DatumAspect()->ToDrawArrows();
 }
-void AIS_Trihedron::LoadSubObjects()
+
+//=======================================================================
+//function : SetDrawArrows
+//purpose  :
+//=======================================================================
+void AIS_Trihedron::SetDrawArrows (const Standard_Boolean theToDraw)
 {
-  myShapes[0] = Position();
-  myShapes[1] = XAxis();
-  myShapes[2] = YAxis();
-  myShapes[3] = Axis();
-  myShapes[4] = XYPlane();
-  myShapes[5] = XZPlane();
-  myShapes[6] = YZPlane();
+  setOwnDatumAspect();
+  myDrawer->DatumAspect()->SetDrawArrows (theToDraw);
 }
 
 //=======================================================================
-//function : SetContext
-//purpose  : 
+//function : createSensitiveEntity
+//purpose  :
 //=======================================================================
+Handle(Select3D_SensitiveEntity) AIS_Trihedron::createSensitiveEntity (const Prs3d_DatumParts thePart,
+                                                   const Handle(SelectMgr_EntityOwner)& theOwner) const
+{
+  Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
+  Handle(Graphic3d_ArrayOfPrimitives) aPrimitives = arrayOfPrimitives (thePart);
+  if (aPrimitives.IsNull())
+  {
+    return Handle(Select3D_SensitiveEntity)();
+  }
+
+  if (thePart >= Prs3d_DP_XOYAxis
+   && thePart <= Prs3d_DP_XOZAxis)
+  { // plane
+    const gp_Pnt anXYZ1 = aPrimitives->Vertice (1);
+    const gp_Pnt anXYZ2 = aPrimitives->Vertice (2);
+    const gp_Pnt anXYZ3 = aPrimitives->Vertice (3);
+    return new Select3D_SensitiveTriangle (theOwner, anXYZ1, anXYZ2, anXYZ3);
+  }
+
+  if (myTrihDispMode == Prs3d_DM_Shaded)
+  {
+    Handle(Select3D_SensitivePrimitiveArray) aSelArray = new Select3D_SensitivePrimitiveArray (theOwner);
+    aSelArray->InitTriangulation (aPrimitives->Attributes(), aPrimitives->Indices(), TopLoc_Location());
+    return aSelArray;
+  }
+
+  if (Handle(Graphic3d_ArrayOfPoints) aPoints = Handle(Graphic3d_ArrayOfPoints)::DownCast(aPrimitives))
+  {
+    const gp_Pnt anXYZ1 = aPoints->Vertice (1);
+    return new Select3D_SensitivePoint (theOwner, anXYZ1);
+  }
+  else if (Handle(Graphic3d_ArrayOfSegments) aSegments = Handle(Graphic3d_ArrayOfSegments)::DownCast(aPrimitives))
+  {
+    const gp_Pnt anXYZ1 = aSegments->Vertice (1);
+    const gp_Pnt anXYZ2 = aSegments->Vertice (2);
+    return new Select3D_SensitiveSegment (theOwner, anXYZ1, anXYZ2);
+  }
+  return Handle(Select3D_SensitiveEntity)();
+}
+
+// =======================================================================
+// function : arrayOfPrimitives
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_ArrayOfPrimitives) AIS_Trihedron::arrayOfPrimitives(
+                                               Prs3d_DatumParts theDatumPart) const
+{
+  Handle(Graphic3d_ArrayOfPrimitives) anArray;
+  myPrimitives.Find(theDatumPart, anArray);
+  return anArray;
+}
 
-void AIS_Trihedron::SetContext(const Handle(AIS_InteractiveContext)& Ctx)
+// =======================================================================
+// function : updatePrimitives
+// purpose  :
+// =======================================================================
+void AIS_Trihedron::updatePrimitives(const Handle(Prs3d_DatumAspect)& theAspect,
+                                     Prs3d_DatumMode theMode,
+                                     const gp_Pnt& theOrigin,
+                                     const gp_Dir& theXDirection,
+                                     const gp_Dir& theYDirection,
+                                     const gp_Dir& theZDirection)
 {
-//  Standard_Boolean same_DA = myDrawer->Link() == Ctx->DefaultDrawer();
-   
-   if( Ctx.IsNull())
-   {
-      Standard_Integer anIdx;
-      for (anIdx = 0; anIdx < 7; anIdx++)
+  myPrimitives.Clear();
+
+  NCollection_DataMap<Prs3d_DatumParts, gp_Dir> anAxisDirs;
+  anAxisDirs.Bind(Prs3d_DP_XAxis, theXDirection);
+  anAxisDirs.Bind(Prs3d_DP_YAxis, theYDirection);
+  anAxisDirs.Bind(Prs3d_DP_ZAxis, theZDirection);
+
+  NCollection_DataMap<Prs3d_DatumParts, gp_Pnt> anAxisPoints;
+  gp_XYZ anXYZOrigin = theOrigin.XYZ();
+  for (int anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
+  {
+    Prs3d_DatumParts aPart = (Prs3d_DatumParts)anAxisIter;
+    anAxisPoints.Bind(aPart, gp_Pnt(anXYZOrigin + anAxisDirs.Find(aPart).XYZ() *
+                                                   theAspect->AxisLength(aPart)));
+  }
+
+  if (theMode == Prs3d_DM_WireFrame)
+  {
+    // origin
+    if (theAspect->DrawDatumPart(Prs3d_DP_Origin))
+    {
+      Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPoints(1);
+      aPrims->AddVertex(theOrigin);
+      myPrimitives.Bind(Prs3d_DP_Origin, aPrims);
+    }
+    // axes
+    for (int aPartIter = Prs3d_DP_XAxis; aPartIter <= Prs3d_DP_ZAxis; ++aPartIter)
+    {
+      const Prs3d_DatumParts aPart = (Prs3d_DatumParts)aPartIter;
+      if (theAspect->DrawDatumPart(aPart))
+      {
+        Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
+        aPrims->AddVertex(theOrigin);
+        aPrims->AddVertex(anAxisPoints.Find(aPart));
+        myPrimitives.Bind(aPart, aPrims);
+      }
+
+      Prs3d_DatumParts anArrowPart = theAspect->ArrowPartForAxis(aPart);
+      if (theAspect->DrawDatumPart(anArrowPart))
+      {
+        myPrimitives.Bind(anArrowPart,
+            Prs3d_Arrow::DrawSegments(anAxisPoints.Find(aPart), anAxisDirs.Find(aPart),
+            theAspect->ArrowAspect()->Angle(),
+            theAspect->AxisLength(aPart) * theAspect->Attribute(Prs3d_DP_ShadingConeLengthPercent),
+          (Standard_Integer)  theAspect->Attribute(Prs3d_DP_ShadingNumberOfFacettes)));
+      }
+    }
+  }
+  else
+  {
+    // shading mode
+    // origin
+    if (theAspect->DrawDatumPart(Prs3d_DP_Origin))
+    {
+      const Standard_Real aSphereRadius = theAspect->AxisLength(Prs3d_DP_XAxis) *
+                                          theAspect->Attribute(Prs3d_DP_ShadingOriginRadiusPercent);
+      const Standard_Integer aNbOfFacettes =
+                           (Standard_Integer)theAspect->Attribute(Prs3d_DP_ShadingNumberOfFacettes);
+      gp_Trsf aSphereTransform;
+      aSphereTransform.SetTranslationPart(gp_Vec(gp::Origin(), theOrigin));
+      myPrimitives.Bind(Prs3d_DP_Origin, Prs3d_ToolSphere::Create(aSphereRadius, aNbOfFacettes,
+                                                                  aNbOfFacettes, aSphereTransform));
+    }
+    // axes
+    {
+      const Standard_Integer aNbOfFacettes = 
+                               (Standard_Integer)theAspect->Attribute(Prs3d_DP_ShadingNumberOfFacettes);
+      const Standard_Real aTubeRadiusPercent = theAspect->Attribute(Prs3d_DP_ShadingTubeRadiusPercent);
+      const Standard_Real aConeLengthPercent = theAspect->Attribute(Prs3d_DP_ShadingConeLengthPercent);
+      const Standard_Real aConeRadiusPercent = theAspect->Attribute(Prs3d_DP_ShadingConeRadiusPercent);
+      for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
       {
-        myShapes[anIdx]->SetContext(Ctx);
+        const Prs3d_DatumParts aPart = (Prs3d_DatumParts)anAxisIter;
+        const Prs3d_DatumParts anArrowPart = theAspect->ArrowPartForAxis(aPart);
+        const bool aDrawArrow = theAspect->DrawDatumPart(anArrowPart);
+        const Standard_Real anAxisLength = theAspect->AxisLength(aPart);
+        const gp_Ax1 anAxis(theOrigin, anAxisDirs.Find(aPart));
+
+        if (theAspect->DrawDatumPart(aPart))
+        {
+          // draw cylinder
+          myPrimitives.Bind(aPart,
+                            Prs3d_Arrow::DrawShaded(anAxis, anAxisLength * aTubeRadiusPercent,
+                            aDrawArrow ? anAxisLength - anAxisLength * aConeLengthPercent : anAxisLength,
+                            0.0, 0.0, aNbOfFacettes));
+        }
+
+        // draw arrow
+        if (aDrawArrow)
+        {
+          myPrimitives.Bind(anArrowPart, Prs3d_Arrow::DrawShaded(anAxis, 0.0, anAxisLength,
+                                                     anAxisLength * aConeRadiusPercent,
+                                                     anAxisLength * aConeLengthPercent, aNbOfFacettes));
+        }
       }
-     AIS_InteractiveObject::SetContext (Ctx);
-     return;
-   }
-  // Remove subobjects from current context
-  Handle(AIS_InteractiveContext) anAISContext = GetContext();
-  
-  Standard_Boolean hasContext = (anAISContext.IsNull() == Standard_False);
-  Standard_Integer anIdx;
-  for (anIdx = 0; anIdx < 7; anIdx++)
+    }
+  }
+  // planes
+  for (Standard_Integer aPlaneIter = Prs3d_DP_XOYAxis; aPlaneIter <= Prs3d_DP_XOZAxis; ++aPlaneIter)
+  {
+    const Prs3d_DatumParts aPart = (Prs3d_DatumParts)aPlaneIter;
+    if (!theAspect->DrawDatumPart(aPart))
     {
-      // Deselect object
-      if (hasContext)
-       {
-         if (anAISContext->IsSelected (myShapes[anIdx]))
-           anAISContext->AddOrRemoveSelected (myShapes[anIdx]);
-         
-         anAISContext->Remove (myShapes[anIdx], Standard_False);
-       }
-      myShapes[anIdx].Nullify();
+      continue;
     }
-  AIS_InteractiveObject::SetContext (Ctx);
-  LoadSubObjects();
-  for(Standard_Integer i= 0;i<=6;i++)
-    myShapes[i]->SetContext (Ctx);
+
+    Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPolylines(4);
+    aPrims->AddVertex(theOrigin);
+
+    Prs3d_DatumParts aPart1 = Prs3d_DP_XAxis, aPart2 = Prs3d_DP_XAxis;
+    switch(aPart)
+    {
+      case Prs3d_DP_XOYAxis:
+      {
+        aPart1 = Prs3d_DP_XAxis;
+        aPart2 = Prs3d_DP_YAxis;
+        break;
+      }
+      case Prs3d_DP_YOZAxis:
+      {
+        aPart1 = Prs3d_DP_YAxis;
+        aPart2 = Prs3d_DP_ZAxis;
+        break;
+      }
+      case Prs3d_DP_XOZAxis:
+      {
+        aPart1 = Prs3d_DP_XAxis;
+        aPart2 = Prs3d_DP_ZAxis;
+        break;
+      }
+      default: break;
+    }
+    aPrims->AddVertex(anAxisPoints.Find(aPart1));
+    aPrims->AddVertex(anAxisPoints.Find(aPart2));
+
+    aPrims->AddVertex(theOrigin);
+    myPrimitives.Bind(aPart, aPrims);
+  }
 }