0030450: Visualization - AIS_InteractiveContext::MoveTo() never uses V3d_View::Immedi...
[occt.git] / src / AIS / AIS_Trihedron.cxx
1 // Created on: 1995-10-09
2 // Created by: Arnaud BOUZY/Odile Olivier
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <AIS_Trihedron.hxx>
18
19 #include <AIS_InteractiveContext.hxx>
20 #include <AIS_TrihedronOwner.hxx>
21 #include <Geom_Axis2Placement.hxx>
22 #include <Geom_Transformation.hxx>
23 #include <gp_Pnt.hxx>
24 #include <Graphic3d_ArrayOfPoints.hxx>
25 #include <Graphic3d_ArrayOfSegments.hxx>
26 #include <Graphic3d_AspectLine3d.hxx>
27 #include <Graphic3d_ArrayOfPoints.hxx>
28 #include <Graphic3d_ArrayOfPolylines.hxx>
29
30 #include <Prs3d_Arrow.hxx>
31 #include <Prs3d_ArrowAspect.hxx>
32 #include <Prs3d_DatumAspect.hxx>
33 #include <Prs3d_Drawer.hxx>
34 #include <Prs3d_LineAspect.hxx>
35 #include <Prs3d_Presentation.hxx>
36 #include <Prs3d_Projector.hxx>
37 #include <Prs3d_ShadingAspect.hxx>
38 #include <Prs3d_Text.hxx>
39 #include <Prs3d_TextAspect.hxx>
40 #include <Prs3d_ToolSphere.hxx>
41
42 #include <Select3D_SensitivePoint.hxx>
43 #include <Select3D_SensitivePrimitiveArray.hxx>
44 #include <Select3D_SensitiveSegment.hxx>
45 #include <Select3D_SensitiveTriangle.hxx>
46 #include <SelectBasics_EntityOwner.hxx>
47 #include <SelectMgr_EntityOwner.hxx>
48 #include <Standard_Type.hxx>
49
50 IMPLEMENT_STANDARD_RTTIEXT(AIS_Trihedron, AIS_InteractiveObject)
51
52 //=======================================================================
53 //function : AIS_Trihedron
54 //purpose  :
55 //=======================================================================
56 AIS_Trihedron::AIS_Trihedron (const Handle(Geom_Axis2Placement)& theComponent)
57 : myHasOwnSize (Standard_False),
58   myHasOwnTextColor (Standard_False),
59   myHasOwnArrowColor (Standard_False),
60   myTrihDispMode (Prs3d_DM_WireFrame),
61   myComponent (theComponent)
62 {
63   // selection priorities
64   mySelectionPriority.Bind (Prs3d_DP_None,   5); // complete triedron: priority 5 (same as faces)
65   mySelectionPriority.Bind (Prs3d_DP_Origin, 8); // origin: priority 8
66   for (int aPartIter = Prs3d_DP_XAxis; aPartIter <= Prs3d_DP_ZAxis; ++aPartIter)
67   {
68     mySelectionPriority.Bind ((Prs3d_DatumParts )aPartIter, 7); // axes: priority: 7
69   }
70   for (int aPartIter = Prs3d_DP_XOYAxis; aPartIter <= Prs3d_DP_XOZAxis; ++aPartIter)
71   {
72     mySelectionPriority.Bind ((Prs3d_DatumParts )aPartIter, 5); // planes: priority: 5
73   }
74
75   // trihedron labels
76   myLabel.Bind (Prs3d_DP_XAxis, "X");
77   myLabel.Bind (Prs3d_DP_YAxis, "Y");
78   myLabel.Bind (Prs3d_DP_ZAxis, "Z");
79 }
80
81 //=======================================================================
82 //function : SetComponent
83 //purpose  :
84 //=======================================================================
85 void AIS_Trihedron::SetComponent (const Handle(Geom_Axis2Placement)& theComponent)
86 {
87   myComponent = theComponent;
88   LoadRecomputable (AIS_WireFrame);
89 }
90
91 //=======================================================================
92 //function : setOwnDatumAspect
93 //purpose  :
94 //=======================================================================
95 void AIS_Trihedron::setOwnDatumAspect()
96 {
97   if (myDrawer->HasOwnDatumAspect())
98     return;
99
100   Handle(Prs3d_DatumAspect) aNewAspect = new Prs3d_DatumAspect();
101   myDrawer->SetDatumAspect(aNewAspect);
102
103   if (myDrawer->Link().IsNull())
104     return;
105
106   myDrawer->DatumAspect()->SetDrawArrows (myDrawer->Link()->DatumAspect()->ToDrawArrows());
107   myDrawer->DatumAspect()->SetDrawLabels (myDrawer->Link()->DatumAspect()->ToDrawLabels());
108   *myDrawer->DatumAspect()->TextAspect()->Aspect() =
109                                      *myDrawer->Link()->DatumAspect()->TextAspect()->Aspect();
110   *myDrawer->DatumAspect()->PointAspect()->Aspect() =
111                                      *myDrawer->Link()->DatumAspect()->PointAspect()->Aspect();
112   *myDrawer->DatumAspect()->ArrowAspect()->Aspect() =
113                                      *myDrawer->Link()->DatumAspect()->ArrowAspect()->Aspect();
114
115   for (int aPartIter = Prs3d_DP_Origin; aPartIter <= Prs3d_DP_XOZAxis; ++aPartIter)
116   {
117     const Prs3d_DatumParts aPart = (Prs3d_DatumParts )aPartIter;
118     if (!aNewAspect->LineAspect(aPart).IsNull())
119       *myDrawer->DatumAspect()->LineAspect(aPart)->Aspect() =
120                                  *myDrawer->Link()->DatumAspect()->LineAspect(aPart)->Aspect();
121     if (!aNewAspect->ShadingAspect(aPart).IsNull())
122       *myDrawer->DatumAspect()->ShadingAspect(aPart)->Aspect() =
123                                  *myDrawer->Link()->DatumAspect()->ShadingAspect(aPart)->Aspect();
124   }
125 }
126
127 //=======================================================================
128 //function : SetSize
129 //purpose  :
130 //=======================================================================
131 void AIS_Trihedron::SetSize(const Standard_Real aValue)
132 {
133   myHasOwnSize = Standard_True;
134
135   setOwnDatumAspect();
136   myDrawer->DatumAspect()->SetAxisLength(aValue, aValue, aValue);
137
138   Update();
139   UpdateSelection();
140 }
141
142 //=======================================================================
143 //function : UnsetSize
144 //purpose  :
145 //=======================================================================
146 void AIS_Trihedron::UnsetSize()
147 {
148   if (!myHasOwnSize)
149   {
150     return;
151   }
152
153   myHasOwnSize = Standard_False;
154   if (hasOwnColor)
155   {
156     const Handle(Prs3d_DatumAspect) DA = myDrawer->HasLink()
157                                        ? myDrawer->Link()->DatumAspect()
158                                        : new Prs3d_DatumAspect();
159     myDrawer->DatumAspect()->SetAxisLength (DA->AxisLength (Prs3d_DP_XAxis),
160                                             DA->AxisLength (Prs3d_DP_YAxis),
161                                             DA->AxisLength (Prs3d_DP_ZAxis));
162   }
163   else
164   {
165     Update();
166   }
167   UpdateSelection();
168 }
169
170 //=======================================================================
171 //function : Size
172 //purpose  :
173 //=======================================================================
174 Standard_Real AIS_Trihedron::Size() const 
175 {
176   return myDrawer->DatumAspect()->AxisLength(Prs3d_DP_XAxis);
177 }
178
179 //=======================================================================
180 //function : Compute
181 //purpose  :
182 //=======================================================================
183 void AIS_Trihedron::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
184                              const Handle(Prs3d_Presentation)& thePrs,
185                              const Standard_Integer theMode)
186 {
187   if (theMode != 0)
188   {
189     return;
190   }
191
192   thePrs->SetInfiniteState (Standard_True);
193
194   gp_Ax2 anAxis (myComponent->Ax2());
195   updatePrimitives (myDrawer->DatumAspect(), myTrihDispMode, anAxis.Location(),
196                     anAxis.XDirection(), anAxis.YDirection(), anAxis.Direction());
197   computePresentation (thePrsMgr, thePrs);
198 }
199
200 //=======================================================================
201 //function : Compute
202 //purpose  :
203 //=======================================================================
204 void AIS_Trihedron::Compute (const Handle(Prs3d_Projector)& theProjector,
205                              const Handle(Geom_Transformation)& theTrsf,
206                              const Handle(Prs3d_Presentation)& thePrs)
207 {
208   PrsMgr_PresentableObject::Compute (theProjector, theTrsf, thePrs);
209 }
210
211 //=======================================================================
212 //function : ComputeSelection
213 //purpose  :
214 //=======================================================================
215 void AIS_Trihedron::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
216                                       const Standard_Integer theMode)
217 {
218   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
219   switch (theMode)
220   {
221     case AIS_TrihedronSelectionMode_EntireObject:
222     {
223       Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (
224                                         this, mySelectionPriority.Find (Prs3d_DP_None));
225       const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
226       for (int aPartIter = isShadingMode ? Prs3d_DP_Origin : Prs3d_DP_XAxis; aPartIter <= Prs3d_DP_ZAxis;
227            ++aPartIter)
228       {
229         const Prs3d_DatumParts aPart = (Prs3d_DatumParts )aPartIter;
230         if (!anAspect->DrawDatumPart (aPart))
231         {
232           continue;
233         }
234         theSelection->Add (createSensitiveEntity (aPart, anOwner));
235       }
236       break;
237     }
238     case AIS_TrihedronSelectionMode_Origin:
239     {
240       const Prs3d_DatumParts aPart = Prs3d_DP_Origin;
241       if (anAspect->DrawDatumPart (aPart))
242       {
243         Handle(SelectMgr_EntityOwner) anOwner = new AIS_TrihedronOwner (this, aPart,
244                                                                  mySelectionPriority.Find (aPart));
245         Handle(Graphic3d_ArrayOfPrimitives) aPrimitives = arrayOfPrimitives(aPart);
246         theSelection->Add (createSensitiveEntity (aPart, anOwner));
247       }
248       break;
249     }
250     case AIS_TrihedronSelectionMode_Axes:
251     {
252       for (int aPartIter = Prs3d_DP_XAxis; aPartIter <= Prs3d_DP_ZAxis; ++aPartIter)
253       {
254         const Prs3d_DatumParts aPart = (Prs3d_DatumParts )aPartIter;
255         if (!anAspect->DrawDatumPart (aPart))
256         {
257           continue;
258         }
259         Handle(SelectMgr_EntityOwner) anOwner = new AIS_TrihedronOwner (this, aPart,
260                                                                         mySelectionPriority.Find (aPart));
261         theSelection->Add (createSensitiveEntity (aPart, anOwner));
262       }
263       break;
264     }
265     case AIS_TrihedronSelectionMode_MainPlanes:
266     {
267       // create owner for each trihedron plane
268       {
269         for (int aPartIter = Prs3d_DP_XOYAxis; aPartIter <= Prs3d_DP_XOZAxis; ++aPartIter)
270         {
271           const Prs3d_DatumParts aPart = (Prs3d_DatumParts )aPartIter;
272           if (!anAspect->DrawDatumPart (aPart))
273           {
274             continue;
275           }
276           Handle(SelectMgr_EntityOwner) anOwner = new AIS_TrihedronOwner (this, aPart,
277                                                                           mySelectionPriority.Find (aPart));
278           theSelection->Add (createSensitiveEntity (aPart, anOwner));
279         }
280       }
281       break;
282     }
283   }
284 }
285
286 //=======================================================================
287 //function : HilightOwnerWithColor
288 //purpose  :
289 //=======================================================================
290 void AIS_Trihedron::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
291                                            const Handle(Prs3d_Drawer)& theStyle,
292                                            const Handle(SelectMgr_EntityOwner)& theOwner)
293 {
294   Handle(AIS_TrihedronOwner) anOwner = Handle(AIS_TrihedronOwner)::DownCast (theOwner);
295   if (anOwner.IsNull())
296   {
297     /// default 0 selection mode
298     Standard_Integer aHiMode = HasHilightMode() ? HilightMode() : 0;
299     thePM->Color (this, theStyle, aHiMode, NULL, Graphic3d_ZLayerId_Top);
300     return;
301   }
302
303   Handle(Prs3d_Presentation) aPresentation = GetHilightPresentation (thePM);
304   if (aPresentation.IsNull())
305   {
306     return;
307   }
308
309   aPresentation->Clear();
310   const Prs3d_DatumParts aPart = anOwner->DatumPart();
311   Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPresentation);
312   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
313   if (aPart >= Prs3d_DP_XOYAxis && aPart <= Prs3d_DP_XOZAxis)
314   {
315     // planes selection is equal in both shading and wireframe mode
316     aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
317   }
318   else
319   {
320     if (myTrihDispMode == Prs3d_DM_Shaded)
321     {
322       aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect(aPart)->Aspect());
323     }
324     else
325     {
326       if (aPart == Prs3d_DP_Origin)
327       {
328         aGroup->SetGroupPrimitivesAspect (getHighlightPointAspect()->Aspect());
329       }
330       else
331       {
332         aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect(aPart)->Aspect());
333       }
334     }
335   }
336   aGroup->AddPrimitiveArray (arrayOfPrimitives(aPart));
337
338   if (aPresentation->GetZLayer() != theStyle->ZLayer())
339   {
340     aPresentation->SetZLayer (theStyle->ZLayer());
341   }
342   aPresentation->Highlight (theStyle);
343   thePM->AddToImmediateList (aPresentation);
344 }
345
346 //========================================================================
347 //function : HilightSelected
348 //purpose  :
349 //========================================================================
350 void AIS_Trihedron::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
351                                      const SelectMgr_SequenceOfOwner& theOwners)
352 {
353   if (theOwners.IsEmpty() || !HasInteractiveContext())
354   {
355     return;
356   }
357
358   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
359   const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
360
361   const Handle(Prs3d_Drawer)& aContextSelStyle = GetContext()->SelectionStyle();
362   const Quantity_Color& aSelectionColor = aContextSelStyle->Color();
363   for (SelectMgr_SequenceOfOwner::Iterator anIterator (theOwners); anIterator.More(); anIterator.Next())
364   {
365     const Handle(SelectMgr_EntityOwner)& anOwner = anIterator.Value();
366     Handle(AIS_TrihedronOwner) aTrihedronOwner = Handle(AIS_TrihedronOwner)::DownCast(anOwner);
367     if (aTrihedronOwner.IsNull())
368     {
369       thePM->Color (this, aContextSelStyle, 0);
370       continue;
371     }
372       
373     const Prs3d_DatumParts aPart = aTrihedronOwner->DatumPart();
374     Handle(Graphic3d_Group) aGroup;
375     if (mySelectedParts.Contains (aPart)
376     || !myPartToGroup.Find (aPart, aGroup))
377     {
378       continue;
379     }
380
381     if (aPart >= Prs3d_DP_XOYAxis
382      && aPart <= Prs3d_DP_XOZAxis)
383     {
384       getHighlightLineAspect()->SetColor (aSelectionColor);
385       aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
386     }
387     else
388     {
389       if (isShadingMode)
390       {
391         getHighlightAspect()->SetColor (aSelectionColor);
392         aGroup->SetGroupPrimitivesAspect (getHighlightAspect()->Aspect());
393       }
394       else
395       {
396         if (aPart == Prs3d_DP_Origin)
397         {
398           getHighlightPointAspect()->SetColor (aSelectionColor);
399           aGroup->SetGroupPrimitivesAspect (getHighlightPointAspect()->Aspect());
400         }
401         else
402         {
403           getHighlightLineAspect()->SetColor (aSelectionColor);
404           aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
405         }
406       }
407     }
408     mySelectedParts.Append (aPart);
409   }
410 }
411
412 //=======================================================================
413 //function : ClearSelected
414 //purpose  :
415 //=======================================================================
416 void AIS_Trihedron::ClearSelected()
417 {
418   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
419   const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
420   for (NCollection_List<Prs3d_DatumParts>::Iterator anIterator (mySelectedParts); anIterator.More();
421        anIterator.Next())
422   {
423     const Prs3d_DatumParts aPart = anIterator.Value();
424     Handle(Graphic3d_Group) aGroup = myPartToGroup.Find (aPart);
425     if (aPart >= Prs3d_DP_XOYAxis
426      && aPart <= Prs3d_DP_XOZAxis)
427     {
428       aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
429     }
430     if (isShadingMode)
431     {
432       aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
433     }
434     else
435     {
436       if (aPart == Prs3d_DP_Origin)
437       {
438         aGroup->SetGroupPrimitivesAspect (anAspect->PointAspect()->Aspect());
439       }
440       else
441       {
442         aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
443       }
444     }
445   }
446   mySelectedParts.Clear();
447 }
448
449 //=======================================================================
450 //function : computePresentation
451 //purpose  :
452 //=======================================================================
453 void AIS_Trihedron::computePresentation (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
454                                          const Handle(Prs3d_Presentation)& thePrs)
455 {
456   myPartToGroup.Clear();
457   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
458   const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
459   // display origin
460   {
461     // Origin is visualized only in shading mode
462     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
463     const Prs3d_DatumParts aPart = Prs3d_DP_Origin;
464     if (anAspect->DrawDatumPart(aPart))
465     {
466       myPartToGroup.Bind (aPart, aGroup);
467       if (isShadingMode)
468       {
469         aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
470       }
471       else
472       {
473         aGroup->SetGroupPrimitivesAspect (anAspect->PointAspect()->Aspect());
474       }
475       aGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
476     }
477   }
478
479   // display axes
480   {
481     for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
482     {
483       Prs3d_DatumParts aPart = (Prs3d_DatumParts )anAxisIter;
484       if (!anAspect->DrawDatumPart (aPart))
485       {
486         continue;
487       }
488
489       Handle(Graphic3d_Group) anAxisGroup = Prs3d_Root::NewGroup (thePrs);
490       myPartToGroup.Bind (aPart, anAxisGroup);
491       if (isShadingMode)
492       {
493         anAxisGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
494       }
495       else
496       {
497         anAxisGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
498       }
499       anAxisGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
500
501       // draw arrow
502       Prs3d_DatumParts anArrowPart = anAspect->ArrowPartForAxis (aPart);
503       if (!anAspect->DrawDatumPart (anArrowPart))
504       {
505         continue;
506       }
507
508       Handle(Graphic3d_Group) anArrowGroup = Prs3d_Root::NewGroup (thePrs);
509       anArrowGroup->SetGroupPrimitivesAspect (anAspect->ArrowAspect()->Aspect());
510       anArrowGroup->AddPrimitiveArray (arrayOfPrimitives (anArrowPart));
511     }
512   }
513
514   // display labels
515   if (anAspect->ToDrawLabels())
516   {
517     Handle(Geom_Axis2Placement) aComponent = myComponent;
518     const gp_Pnt anOrigin = aComponent->Location();
519     for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
520     {
521       const Prs3d_DatumParts aPart = (Prs3d_DatumParts )anAxisIter;
522       if (!anAspect->DrawDatumPart (aPart))
523       {
524         continue;
525       }
526
527       const Standard_Real anAxisLength = anAspect->AxisLength (aPart);
528       const TCollection_ExtendedString& aLabel = myLabel.Find (aPart);
529       gp_Dir aDir;
530       switch (aPart)
531       {
532         case Prs3d_DP_XAxis: aDir = aComponent->XDirection(); break;
533         case Prs3d_DP_YAxis: aDir = aComponent->YDirection(); break;
534         case Prs3d_DP_ZAxis: aDir = aComponent->Direction();  break;
535         default: break;
536       }
537       Handle(Graphic3d_Group) aLabelGroup = Prs3d_Root::NewGroup (thePrs);
538       const gp_Pnt aPoint = anOrigin.XYZ() + aDir.XYZ() * anAxisLength;
539       Prs3d_Text::Draw (aLabelGroup, anAspect->TextAspect(), aLabel, aPoint);
540     }
541   }
542
543   // planes invisible group for planes selection
544   for (Standard_Integer anAxisIter = Prs3d_DP_XOYAxis; anAxisIter <= Prs3d_DP_XOZAxis; ++anAxisIter)
545   {
546     Prs3d_DatumParts aPart = (Prs3d_DatumParts)anAxisIter;
547     if (!anAspect->DrawDatumPart(aPart))
548     {
549       continue;
550     }
551
552     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
553     myPartToGroup.Bind (aPart, aGroup);
554
555     const Handle(Graphic3d_AspectLine3d)& aLineAspect = anAspect->LineAspect (aPart)->Aspect();
556     aLineAspect->SetType (Aspect_TOL_EMPTY);
557
558     aGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
559     aGroup->SetGroupPrimitivesAspect (aLineAspect);
560   }
561 }
562
563 //=======================================================================
564 //function : LoadRecomputable
565 //purpose  :
566 //=======================================================================
567 void AIS_Trihedron::LoadRecomputable (const Standard_Integer theMode)
568 {
569   myRecomputeEveryPrs = Standard_False;
570   if (!myToRecomputeModes.Contains (theMode))
571   {
572     myToRecomputeModes.Append (theMode);
573   }
574 }
575
576 //=======================================================================
577 //function : SetColor
578 //purpose  :
579 //=======================================================================
580 void AIS_Trihedron::SetDatumPartColor (const Prs3d_DatumParts thePart,
581                                        const Quantity_Color&  theColor)
582 {
583   setOwnDatumAspect();
584
585   myDrawer->DatumAspect()->ShadingAspect (thePart)->SetColor (theColor);
586   if (thePart != Prs3d_DP_Origin)
587   {
588     myDrawer->DatumAspect()->LineAspect (thePart)->SetColor (theColor);
589   }
590 }
591
592 //=======================================================================
593 //function : SetTextColor
594 //purpose  :
595 //=======================================================================
596 void AIS_Trihedron::SetTextColor (const Quantity_Color& theColor)
597 {
598   setOwnDatumAspect();
599   myDrawer->DatumAspect()->TextAspect()->SetColor (theColor);
600 }
601
602 //=======================================================================
603 //function : Color
604 //purpose  :
605 //=======================================================================
606 Quantity_Color AIS_Trihedron::DatumPartColor (Prs3d_DatumParts thePart)
607 {
608   if (myTrihDispMode == Prs3d_DM_Shaded)
609   {
610     return myDrawer->DatumAspect()->ShadingAspect (thePart)->Color();
611   }
612   else
613   {
614     return myDrawer->DatumAspect()->LineAspect (thePart)->Aspect()->Color();
615   }
616 }
617
618 //=======================================================================
619 //function : SetOriginColor
620 //purpose  :
621 //=======================================================================
622 void AIS_Trihedron::SetOriginColor (const Quantity_Color& theColor)
623 {
624   if (myTrihDispMode == Prs3d_DM_Shaded)
625   {
626     SetDatumPartColor (Prs3d_DP_Origin, theColor);
627   }
628 }
629
630 //=======================================================================
631 //function : SetXAxisColor
632 //purpose  :
633 //=======================================================================
634 void AIS_Trihedron::SetXAxisColor (const Quantity_Color& theColor)
635 {
636   SetDatumPartColor (Prs3d_DP_XAxis, theColor);
637 }
638
639 //=======================================================================
640 //function : SetYAxisColor
641 //purpose  :
642 //=======================================================================
643 void AIS_Trihedron::SetYAxisColor (const Quantity_Color& theColor)
644 {
645   SetDatumPartColor (Prs3d_DP_YAxis, theColor);
646 }
647
648 //=======================================================================
649 //function : SetAxisColor
650 //purpose  :
651 //=======================================================================
652 void AIS_Trihedron::SetAxisColor (const Quantity_Color& theColor)
653 {
654   SetDatumPartColor (Prs3d_DP_ZAxis, theColor);
655 }
656
657 //=======================================================================
658 //function : SetColor
659 //purpose  :
660 //=======================================================================
661 void AIS_Trihedron::SetColor (const Quantity_Color& theColor)
662 {
663   hasOwnColor = Standard_True;
664   myDrawer->SetColor (theColor);
665
666   SetDatumPartColor (Prs3d_DP_Origin, theColor);
667   SetDatumPartColor (Prs3d_DP_XAxis,  theColor);
668   SetDatumPartColor (Prs3d_DP_YAxis,  theColor);
669   SetDatumPartColor (Prs3d_DP_ZAxis,  theColor);
670 }
671
672 //=======================================================================
673 //function : SetArrowColor
674 //purpose  :
675 //=======================================================================
676 void AIS_Trihedron::SetArrowColor (const Quantity_Color& theColor)
677 {
678   setOwnDatumAspect();
679
680   myHasOwnArrowColor = Standard_True;
681   myDrawer->DatumAspect()->ArrowAspect()->SetColor (theColor);
682 }
683
684 //=======================================================================
685 //function : TextColor
686 //purpose  :
687 //=======================================================================
688 Quantity_Color AIS_Trihedron::TextColor() const
689 {
690   return myDrawer->DatumAspect()->TextAspect()->Aspect()->Color();
691 }
692
693 //=======================================================================
694 //function : ArrowColor
695 //purpose  :
696 //=======================================================================
697 Quantity_Color AIS_Trihedron::ArrowColor() const
698 {
699   return myDrawer->DatumAspect()->ArrowAspect()->Aspect()->Color();
700 }
701
702 //=======================================================================
703 //function : UnsetColor
704 //purpose  : 
705 //=======================================================================
706 void AIS_Trihedron::UnsetColor()
707 {
708   hasOwnColor = Standard_False;
709   Quantity_Color aDefaultColor (Quantity_NOC_LIGHTSTEELBLUE4);
710   SetColor (aDefaultColor);
711   if (HasTextColor())
712   {
713     SetTextColor (aDefaultColor);
714     myHasOwnTextColor = Standard_False;
715   }
716   if (HasArrowColor())
717   {
718     SetArrowColor (aDefaultColor);
719     myHasOwnArrowColor = Standard_False;
720   }
721 }
722
723 //=======================================================================
724 //function : ToDrawArrows
725 //purpose  :
726 //=======================================================================
727 Standard_Boolean AIS_Trihedron::ToDrawArrows() const
728 {
729   return myDrawer->DatumAspect()->ToDrawArrows();
730 }
731
732 //=======================================================================
733 //function : SetDrawArrows
734 //purpose  :
735 //=======================================================================
736 void AIS_Trihedron::SetDrawArrows (const Standard_Boolean theToDraw)
737 {
738   setOwnDatumAspect();
739   myDrawer->DatumAspect()->SetDrawArrows (theToDraw);
740 }
741
742 //=======================================================================
743 //function : createSensitiveEntity
744 //purpose  :
745 //=======================================================================
746 Handle(SelectBasics_SensitiveEntity) AIS_Trihedron::createSensitiveEntity (const Prs3d_DatumParts thePart,
747                                                    const Handle(SelectBasics_EntityOwner)& theOwner) const
748 {
749   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
750   Handle(Graphic3d_ArrayOfPrimitives) aPrimitives = arrayOfPrimitives (thePart);
751   if (aPrimitives.IsNull())
752   {
753     return Handle(SelectBasics_SensitiveEntity)();
754   }
755
756   if (thePart >= Prs3d_DP_XOYAxis
757    && thePart <= Prs3d_DP_XOZAxis)
758   { // plane
759     const gp_Pnt anXYZ1 = aPrimitives->Vertice (1);
760     const gp_Pnt anXYZ2 = aPrimitives->Vertice (2);
761     const gp_Pnt anXYZ3 = aPrimitives->Vertice (3);
762     return new Select3D_SensitiveTriangle (theOwner, anXYZ1, anXYZ2, anXYZ3);
763   }
764
765   if (myTrihDispMode == Prs3d_DM_Shaded)
766   {
767     Handle(Select3D_SensitivePrimitiveArray) aSelArray = new Select3D_SensitivePrimitiveArray (theOwner);
768     aSelArray->InitTriangulation (aPrimitives->Attributes(), aPrimitives->Indices(), TopLoc_Location());
769     return aSelArray;
770   }
771
772   if (Handle(Graphic3d_ArrayOfPoints) aPoints = Handle(Graphic3d_ArrayOfPoints)::DownCast(aPrimitives))
773   {
774     const gp_Pnt anXYZ1 = aPoints->Vertice (1);
775     return new Select3D_SensitivePoint (theOwner, anXYZ1);
776   }
777   else if (Handle(Graphic3d_ArrayOfSegments) aSegments = Handle(Graphic3d_ArrayOfSegments)::DownCast(aPrimitives))
778   {
779     const gp_Pnt anXYZ1 = aSegments->Vertice (1);
780     const gp_Pnt anXYZ2 = aSegments->Vertice (2);
781     return new Select3D_SensitiveSegment (theOwner, anXYZ1, anXYZ2);
782   }
783   return Handle(SelectBasics_SensitiveEntity)();
784 }
785
786 // =======================================================================
787 // function : arrayOfPrimitives
788 // purpose  :
789 // =======================================================================
790 Handle(Graphic3d_ArrayOfPrimitives) AIS_Trihedron::arrayOfPrimitives(
791                                                Prs3d_DatumParts theDatumPart) const
792 {
793   Handle(Graphic3d_ArrayOfPrimitives) anArray;
794   myPrimitives.Find(theDatumPart, anArray);
795   return anArray;
796 }
797
798 // =======================================================================
799 // function : updatePrimitives
800 // purpose  :
801 // =======================================================================
802 void AIS_Trihedron::updatePrimitives(const Handle(Prs3d_DatumAspect)& theAspect,
803                                      Prs3d_DatumMode theMode,
804                                      const gp_Pnt& theOrigin,
805                                      const gp_Dir& theXDirection,
806                                      const gp_Dir& theYDirection,
807                                      const gp_Dir& theZDirection)
808 {
809   myPrimitives.Clear();
810
811   NCollection_DataMap<Prs3d_DatumParts, gp_Dir> anAxisDirs;
812   anAxisDirs.Bind(Prs3d_DP_XAxis, theXDirection);
813   anAxisDirs.Bind(Prs3d_DP_YAxis, theYDirection);
814   anAxisDirs.Bind(Prs3d_DP_ZAxis, theZDirection);
815
816   NCollection_DataMap<Prs3d_DatumParts, gp_Pnt> anAxisPoints;
817   gp_XYZ anXYZOrigin = theOrigin.XYZ();
818   for (int anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
819   {
820     Prs3d_DatumParts aPart = (Prs3d_DatumParts)anAxisIter;
821     anAxisPoints.Bind(aPart, gp_Pnt(anXYZOrigin + anAxisDirs.Find(aPart).XYZ() *
822                                                    theAspect->AxisLength(aPart)));
823   }
824
825   if (theMode == Prs3d_DM_WireFrame)
826   {
827     // origin
828     if (theAspect->DrawDatumPart(Prs3d_DP_Origin))
829     {
830       Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPoints(1);
831       aPrims->AddVertex(theOrigin);
832       myPrimitives.Bind(Prs3d_DP_Origin, aPrims);
833     }
834     // axes
835     for (int aPartIter = Prs3d_DP_XAxis; aPartIter <= Prs3d_DP_ZAxis; ++aPartIter)
836     {
837       const Prs3d_DatumParts aPart = (Prs3d_DatumParts)aPartIter;
838       if (theAspect->DrawDatumPart(aPart))
839       {
840         Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
841         aPrims->AddVertex(theOrigin);
842         aPrims->AddVertex(anAxisPoints.Find(aPart));
843         myPrimitives.Bind(aPart, aPrims);
844       }
845
846       Prs3d_DatumParts anArrowPart = theAspect->ArrowPartForAxis(aPart);
847       if (theAspect->DrawDatumPart(anArrowPart))
848       {
849         myPrimitives.Bind(anArrowPart,
850             Prs3d_Arrow::DrawSegments(anAxisPoints.Find(aPart), anAxisDirs.Find(aPart),
851             theAspect->ArrowAspect()->Angle(),
852             theAspect->AxisLength(aPart) * theAspect->Attribute(Prs3d_DP_ShadingConeLengthPercent),
853           (Standard_Integer)  theAspect->Attribute(Prs3d_DP_ShadingNumberOfFacettes)));
854       }
855     }
856   }
857   else
858   {
859     // shading mode
860     // origin
861     if (theAspect->DrawDatumPart(Prs3d_DP_Origin))
862     {
863       const Standard_Real aSphereRadius = theAspect->AxisLength(Prs3d_DP_XAxis) *
864                                           theAspect->Attribute(Prs3d_DP_ShadingOriginRadiusPercent);
865       const Standard_Integer aNbOfFacettes =
866                            (Standard_Integer)theAspect->Attribute(Prs3d_DP_ShadingNumberOfFacettes);
867       gp_Trsf aSphereTransform;
868       aSphereTransform.SetTranslationPart(gp_Vec(gp::Origin(), theOrigin));
869       myPrimitives.Bind(Prs3d_DP_Origin, Prs3d_ToolSphere::Create(aSphereRadius, aNbOfFacettes,
870                                                                   aNbOfFacettes, aSphereTransform));
871     }
872     // axes
873     {
874       const Standard_Integer aNbOfFacettes = 
875                                (Standard_Integer)theAspect->Attribute(Prs3d_DP_ShadingNumberOfFacettes);
876       const Standard_Real aTubeRadiusPercent = theAspect->Attribute(Prs3d_DP_ShadingTubeRadiusPercent);
877       const Standard_Real aConeLengthPercent = theAspect->Attribute(Prs3d_DP_ShadingConeLengthPercent);
878       const Standard_Real aConeRadiusPercent = theAspect->Attribute(Prs3d_DP_ShadingConeRadiusPercent);
879       for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
880       {
881         const Prs3d_DatumParts aPart = (Prs3d_DatumParts)anAxisIter;
882         const Prs3d_DatumParts anArrowPart = theAspect->ArrowPartForAxis(aPart);
883         const bool aDrawArrow = theAspect->DrawDatumPart(anArrowPart);
884         const Standard_Real anAxisLength = theAspect->AxisLength(aPart);
885         const gp_Ax1 anAxis(theOrigin, anAxisDirs.Find(aPart));
886
887         if (theAspect->DrawDatumPart(aPart))
888         {
889           // draw cylinder
890           myPrimitives.Bind(aPart,
891                             Prs3d_Arrow::DrawShaded(anAxis, anAxisLength * aTubeRadiusPercent,
892                             aDrawArrow ? anAxisLength - anAxisLength * aConeLengthPercent : anAxisLength,
893                             0.0, 0.0, aNbOfFacettes));
894         }
895
896         // draw arrow
897         if (aDrawArrow)
898         {
899           myPrimitives.Bind(anArrowPart, Prs3d_Arrow::DrawShaded(anAxis, 0.0, anAxisLength,
900                                                      anAxisLength * aConeRadiusPercent,
901                                                      anAxisLength * aConeLengthPercent, aNbOfFacettes));
902         }
903       }
904     }
905   }
906   // planes
907   for (Standard_Integer aPlaneIter = Prs3d_DP_XOYAxis; aPlaneIter <= Prs3d_DP_XOZAxis; ++aPlaneIter)
908   {
909     const Prs3d_DatumParts aPart = (Prs3d_DatumParts)aPlaneIter;
910     if (!theAspect->DrawDatumPart(aPart))
911     {
912       continue;
913     }
914
915     Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPolylines(4);
916     aPrims->AddVertex(theOrigin);
917
918     Prs3d_DatumParts aPart1 = Prs3d_DP_XAxis, aPart2 = Prs3d_DP_XAxis;
919     switch(aPart)
920     {
921       case Prs3d_DP_XOYAxis:
922       {
923         aPart1 = Prs3d_DP_XAxis;
924         aPart2 = Prs3d_DP_YAxis;
925         break;
926       }
927       case Prs3d_DP_YOZAxis:
928       {
929         aPart1 = Prs3d_DP_YAxis;
930         aPart2 = Prs3d_DP_ZAxis;
931         break;
932       }
933       case Prs3d_DP_XOZAxis:
934       {
935         aPart1 = Prs3d_DP_XAxis;
936         aPart2 = Prs3d_DP_ZAxis;
937         break;
938       }
939       default: break;
940     }
941     aPrims->AddVertex(anAxisPoints.Find(aPart1));
942     aPrims->AddVertex(anAxisPoints.Find(aPart2));
943
944     aPrims->AddVertex(theOrigin);
945     myPrimitives.Bind(aPart, aPrims);
946   }
947 }
948
949 // =======================================================================
950 // function : getHighlightAspect
951 // purpose  :
952 // =======================================================================
953 Handle(Prs3d_ShadingAspect) AIS_Trihedron::getHighlightAspect()
954 {
955   if (!myHighlightAspect.IsNull())
956     return myHighlightAspect;
957
958   Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
959   if (!myHilightDrawer.IsNull())
960     aHighlightColor = myHilightDrawer->Color();
961
962   myHighlightAspect = new Prs3d_ShadingAspect();
963   myHighlightAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
964   myHighlightAspect->SetColor (aHighlightColor);
965
966   Graphic3d_MaterialAspect aHighlightMaterial;
967   aHighlightMaterial.SetColor (aHighlightColor);
968   myHighlightAspect->SetMaterial (aHighlightMaterial);
969
970   return myHighlightAspect;
971 }
972
973 // =======================================================================
974 // function : getHighlightLineAspect
975 // purpose  :
976 // =======================================================================
977 Handle(Prs3d_LineAspect) AIS_Trihedron::getHighlightLineAspect()
978 {
979   if (!myHighlightLineAspect.IsNull())
980     return myHighlightLineAspect;
981
982   Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
983   if (!myHilightDrawer.IsNull())
984     aHighlightColor = myHilightDrawer->Color();
985
986   Handle(Prs3d_DatumAspect) aDatumAspect = Attributes()->DatumAspect();
987   Handle(Prs3d_LineAspect) aLineAspect = aDatumAspect->LineAspect(Prs3d_DP_XAxis);
988   myHighlightLineAspect = new Prs3d_LineAspect (aHighlightColor, aLineAspect->Aspect()->Type(),
989                                                 aLineAspect->Aspect()->Width());
990
991   return myHighlightLineAspect;
992 }
993
994 // =======================================================================
995 // function : getHighlightPointAspect
996 // purpose  :
997 // =======================================================================
998 Handle(Prs3d_PointAspect) AIS_Trihedron::getHighlightPointAspect()
999 {
1000   if (!myHighlightPointAspect.IsNull())
1001     return myHighlightPointAspect;
1002
1003   Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
1004   if (!myHilightDrawer.IsNull())
1005     aHighlightColor = myHilightDrawer->Color();
1006   myHighlightPointAspect = new Prs3d_PointAspect (Aspect_TOM_PLUS, aHighlightColor, 1.0);
1007
1008   return myHighlightPointAspect;
1009 }