0626d10dd8fe97f1047455e561f9c7539e4ca506
[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   aPresentation->Highlight (theStyle);
339   thePM->AddToImmediateList (aPresentation);
340 }
341
342 //========================================================================
343 //function : HilightSelected
344 //purpose  :
345 //========================================================================
346 void AIS_Trihedron::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
347                                      const SelectMgr_SequenceOfOwner& theOwners)
348 {
349   if (theOwners.IsEmpty() || !HasInteractiveContext())
350   {
351     return;
352   }
353
354   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
355   const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
356
357   const Handle(Prs3d_Drawer)& aContextSelStyle = GetContext()->SelectionStyle();
358   const Quantity_Color& aSelectionColor = aContextSelStyle->Color();
359   for (SelectMgr_SequenceOfOwner::Iterator anIterator (theOwners); anIterator.More(); anIterator.Next())
360   {
361     const Handle(SelectMgr_EntityOwner)& anOwner = anIterator.Value();
362     Handle(AIS_TrihedronOwner) aTrihedronOwner = Handle(AIS_TrihedronOwner)::DownCast(anOwner);
363     if (aTrihedronOwner.IsNull())
364     {
365       thePM->Color (this, aContextSelStyle, 0);
366       continue;
367     }
368       
369     const Prs3d_DatumParts aPart = aTrihedronOwner->DatumPart();
370     Handle(Graphic3d_Group) aGroup;
371     if (mySelectedParts.Contains (aPart)
372     || !myPartToGroup.Find (aPart, aGroup))
373     {
374       continue;
375     }
376
377     if (aPart >= Prs3d_DP_XOYAxis
378      && aPart <= Prs3d_DP_XOZAxis)
379     {
380       getHighlightLineAspect()->SetColor (aSelectionColor);
381       aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
382     }
383     else
384     {
385       if (isShadingMode)
386       {
387         getHighlightAspect()->SetColor (aSelectionColor);
388         aGroup->SetGroupPrimitivesAspect (getHighlightAspect()->Aspect());
389       }
390       else
391       {
392         if (aPart == Prs3d_DP_Origin)
393         {
394           getHighlightPointAspect()->SetColor (aSelectionColor);
395           aGroup->SetGroupPrimitivesAspect (getHighlightPointAspect()->Aspect());
396         }
397         else
398         {
399           getHighlightLineAspect()->SetColor (aSelectionColor);
400           aGroup->SetGroupPrimitivesAspect (getHighlightLineAspect()->Aspect());
401         }
402       }
403     }
404     mySelectedParts.Append (aPart);
405   }
406 }
407
408 //=======================================================================
409 //function : ClearSelected
410 //purpose  :
411 //=======================================================================
412 void AIS_Trihedron::ClearSelected()
413 {
414   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
415   const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
416   for (NCollection_List<Prs3d_DatumParts>::Iterator anIterator (mySelectedParts); anIterator.More();
417        anIterator.Next())
418   {
419     const Prs3d_DatumParts aPart = anIterator.Value();
420     Handle(Graphic3d_Group) aGroup = myPartToGroup.Find (aPart);
421     if (aPart >= Prs3d_DP_XOYAxis
422      && aPart <= Prs3d_DP_XOZAxis)
423     {
424       aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
425     }
426     if (isShadingMode)
427     {
428       aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
429     }
430     else
431     {
432       if (aPart == Prs3d_DP_Origin)
433       {
434         aGroup->SetGroupPrimitivesAspect (anAspect->PointAspect()->Aspect());
435       }
436       else
437       {
438         aGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
439       }
440     }
441   }
442   mySelectedParts.Clear();
443 }
444
445 //=======================================================================
446 //function : computePresentation
447 //purpose  :
448 //=======================================================================
449 void AIS_Trihedron::computePresentation (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
450                                          const Handle(Prs3d_Presentation)& thePrs)
451 {
452   myPartToGroup.Clear();
453   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
454   const bool isShadingMode = myTrihDispMode == Prs3d_DM_Shaded;
455   // display origin
456   {
457     // Origin is visualized only in shading mode
458     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
459     const Prs3d_DatumParts aPart = Prs3d_DP_Origin;
460     if (anAspect->DrawDatumPart(aPart))
461     {
462       myPartToGroup.Bind (aPart, aGroup);
463       if (isShadingMode)
464       {
465         aGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
466       }
467       else
468       {
469         aGroup->SetGroupPrimitivesAspect (anAspect->PointAspect()->Aspect());
470       }
471       aGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
472     }
473   }
474
475   // display axes
476   {
477     for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
478     {
479       Prs3d_DatumParts aPart = (Prs3d_DatumParts )anAxisIter;
480       if (!anAspect->DrawDatumPart (aPart))
481       {
482         continue;
483       }
484
485       Handle(Graphic3d_Group) anAxisGroup = Prs3d_Root::NewGroup (thePrs);
486       myPartToGroup.Bind (aPart, anAxisGroup);
487       if (isShadingMode)
488       {
489         anAxisGroup->SetGroupPrimitivesAspect (anAspect->ShadingAspect (aPart)->Aspect());
490       }
491       else
492       {
493         anAxisGroup->SetGroupPrimitivesAspect (anAspect->LineAspect (aPart)->Aspect());
494       }
495       anAxisGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
496
497       // draw arrow
498       Prs3d_DatumParts anArrowPart = anAspect->ArrowPartForAxis (aPart);
499       if (!anAspect->DrawDatumPart (anArrowPart))
500       {
501         continue;
502       }
503
504       Handle(Graphic3d_Group) anArrowGroup = Prs3d_Root::NewGroup (thePrs);
505       anArrowGroup->SetGroupPrimitivesAspect (anAspect->ArrowAspect()->Aspect());
506       anArrowGroup->AddPrimitiveArray (arrayOfPrimitives (anArrowPart));
507     }
508   }
509
510   // display labels
511   if (anAspect->ToDrawLabels())
512   {
513     Handle(Geom_Axis2Placement) aComponent = myComponent;
514     const gp_Pnt anOrigin = aComponent->Location();
515     for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
516     {
517       const Prs3d_DatumParts aPart = (Prs3d_DatumParts )anAxisIter;
518       if (!anAspect->DrawDatumPart (aPart))
519       {
520         continue;
521       }
522
523       const Standard_Real anAxisLength = anAspect->AxisLength (aPart);
524       const TCollection_ExtendedString& aLabel = myLabel.Find (aPart);
525       gp_Dir aDir;
526       switch (aPart)
527       {
528         case Prs3d_DP_XAxis: aDir = aComponent->XDirection(); break;
529         case Prs3d_DP_YAxis: aDir = aComponent->YDirection(); break;
530         case Prs3d_DP_ZAxis: aDir = aComponent->Direction();  break;
531         default: break;
532       }
533       Handle(Graphic3d_Group) aLabelGroup = Prs3d_Root::NewGroup (thePrs);
534       const gp_Pnt aPoint = anOrigin.XYZ() + aDir.XYZ() * anAxisLength;
535       Prs3d_Text::Draw (aLabelGroup, anAspect->TextAspect(), aLabel, aPoint);
536     }
537   }
538
539   // planes invisible group for planes selection
540   for (Standard_Integer anAxisIter = Prs3d_DP_XOYAxis; anAxisIter <= Prs3d_DP_XOZAxis; ++anAxisIter)
541   {
542     Prs3d_DatumParts aPart = (Prs3d_DatumParts)anAxisIter;
543     if (!anAspect->DrawDatumPart(aPart))
544     {
545       continue;
546     }
547
548     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
549     myPartToGroup.Bind (aPart, aGroup);
550
551     const Handle(Graphic3d_AspectLine3d)& aLineAspect = anAspect->LineAspect (aPart)->Aspect();
552     aLineAspect->SetType (Aspect_TOL_EMPTY);
553
554     aGroup->AddPrimitiveArray (arrayOfPrimitives (aPart));
555     aGroup->SetGroupPrimitivesAspect (aLineAspect);
556   }
557 }
558
559 //=======================================================================
560 //function : LoadRecomputable
561 //purpose  :
562 //=======================================================================
563 void AIS_Trihedron::LoadRecomputable (const Standard_Integer theMode)
564 {
565   myRecomputeEveryPrs = Standard_False;
566   if (!myToRecomputeModes.Contains (theMode))
567   {
568     myToRecomputeModes.Append (theMode);
569   }
570 }
571
572 //=======================================================================
573 //function : SetColor
574 //purpose  :
575 //=======================================================================
576 void AIS_Trihedron::SetDatumPartColor (const Prs3d_DatumParts thePart,
577                                        const Quantity_Color&  theColor)
578 {
579   setOwnDatumAspect();
580
581   myDrawer->DatumAspect()->ShadingAspect (thePart)->SetColor (theColor);
582   if (thePart != Prs3d_DP_Origin)
583   {
584     myDrawer->DatumAspect()->LineAspect (thePart)->SetColor (theColor);
585   }
586 }
587
588 //=======================================================================
589 //function : SetTextColor
590 //purpose  :
591 //=======================================================================
592 void AIS_Trihedron::SetTextColor (const Quantity_Color& theColor)
593 {
594   setOwnDatumAspect();
595   myDrawer->DatumAspect()->TextAspect()->SetColor (theColor);
596 }
597
598 //=======================================================================
599 //function : Color
600 //purpose  :
601 //=======================================================================
602 Quantity_Color AIS_Trihedron::DatumPartColor (Prs3d_DatumParts thePart)
603 {
604   if (myTrihDispMode == Prs3d_DM_Shaded)
605   {
606     return myDrawer->DatumAspect()->ShadingAspect (thePart)->Color();
607   }
608   else
609   {
610     return myDrawer->DatumAspect()->LineAspect (thePart)->Aspect()->Color();
611   }
612 }
613
614 //=======================================================================
615 //function : SetOriginColor
616 //purpose  :
617 //=======================================================================
618 void AIS_Trihedron::SetOriginColor (const Quantity_Color& theColor)
619 {
620   if (myTrihDispMode == Prs3d_DM_Shaded)
621   {
622     SetDatumPartColor (Prs3d_DP_Origin, theColor);
623   }
624 }
625
626 //=======================================================================
627 //function : SetXAxisColor
628 //purpose  :
629 //=======================================================================
630 void AIS_Trihedron::SetXAxisColor (const Quantity_Color& theColor)
631 {
632   SetDatumPartColor (Prs3d_DP_XAxis, theColor);
633 }
634
635 //=======================================================================
636 //function : SetYAxisColor
637 //purpose  :
638 //=======================================================================
639 void AIS_Trihedron::SetYAxisColor (const Quantity_Color& theColor)
640 {
641   SetDatumPartColor (Prs3d_DP_YAxis, theColor);
642 }
643
644 //=======================================================================
645 //function : SetAxisColor
646 //purpose  :
647 //=======================================================================
648 void AIS_Trihedron::SetAxisColor (const Quantity_Color& theColor)
649 {
650   SetDatumPartColor (Prs3d_DP_ZAxis, theColor);
651 }
652
653 //=======================================================================
654 //function : SetColor
655 //purpose  :
656 //=======================================================================
657 void AIS_Trihedron::SetColor (const Quantity_Color& theColor)
658 {
659   hasOwnColor = Standard_True;
660   myDrawer->SetColor (theColor);
661
662   SetDatumPartColor (Prs3d_DP_Origin, theColor);
663   SetDatumPartColor (Prs3d_DP_XAxis,  theColor);
664   SetDatumPartColor (Prs3d_DP_YAxis,  theColor);
665   SetDatumPartColor (Prs3d_DP_ZAxis,  theColor);
666 }
667
668 //=======================================================================
669 //function : SetArrowColor
670 //purpose  :
671 //=======================================================================
672 void AIS_Trihedron::SetArrowColor (const Quantity_Color& theColor)
673 {
674   setOwnDatumAspect();
675
676   myHasOwnArrowColor = Standard_True;
677   myDrawer->DatumAspect()->ArrowAspect()->SetColor (theColor);
678 }
679
680 //=======================================================================
681 //function : TextColor
682 //purpose  :
683 //=======================================================================
684 Quantity_Color AIS_Trihedron::TextColor() const
685 {
686   return myDrawer->DatumAspect()->TextAspect()->Aspect()->Color();
687 }
688
689 //=======================================================================
690 //function : ArrowColor
691 //purpose  :
692 //=======================================================================
693 Quantity_Color AIS_Trihedron::ArrowColor() const
694 {
695   return myDrawer->DatumAspect()->ArrowAspect()->Aspect()->Color();
696 }
697
698 //=======================================================================
699 //function : UnsetColor
700 //purpose  : 
701 //=======================================================================
702 void AIS_Trihedron::UnsetColor()
703 {
704   hasOwnColor = Standard_False;
705   Quantity_Color aDefaultColor (Quantity_NOC_LIGHTSTEELBLUE4);
706   SetColor (aDefaultColor);
707   if (HasTextColor())
708   {
709     SetTextColor (aDefaultColor);
710     myHasOwnTextColor = Standard_False;
711   }
712   if (HasArrowColor())
713   {
714     SetArrowColor (aDefaultColor);
715     myHasOwnArrowColor = Standard_False;
716   }
717 }
718
719 //=======================================================================
720 //function : ToDrawArrows
721 //purpose  :
722 //=======================================================================
723 Standard_Boolean AIS_Trihedron::ToDrawArrows() const
724 {
725   return myDrawer->DatumAspect()->ToDrawArrows();
726 }
727
728 //=======================================================================
729 //function : SetDrawArrows
730 //purpose  :
731 //=======================================================================
732 void AIS_Trihedron::SetDrawArrows (const Standard_Boolean theToDraw)
733 {
734   setOwnDatumAspect();
735   myDrawer->DatumAspect()->SetDrawArrows (theToDraw);
736 }
737
738 //=======================================================================
739 //function : createSensitiveEntity
740 //purpose  :
741 //=======================================================================
742 Handle(SelectBasics_SensitiveEntity) AIS_Trihedron::createSensitiveEntity (const Prs3d_DatumParts thePart,
743                                                    const Handle(SelectBasics_EntityOwner)& theOwner) const
744 {
745   Handle(Prs3d_DatumAspect) anAspect = myDrawer->DatumAspect();
746   Handle(Graphic3d_ArrayOfPrimitives) aPrimitives = arrayOfPrimitives (thePart);
747   if (aPrimitives.IsNull())
748   {
749     return Handle(SelectBasics_SensitiveEntity)();
750   }
751
752   if (thePart >= Prs3d_DP_XOYAxis
753    && thePart <= Prs3d_DP_XOZAxis)
754   { // plane
755     const gp_Pnt anXYZ1 = aPrimitives->Vertice (1);
756     const gp_Pnt anXYZ2 = aPrimitives->Vertice (2);
757     const gp_Pnt anXYZ3 = aPrimitives->Vertice (3);
758     return new Select3D_SensitiveTriangle (theOwner, anXYZ1, anXYZ2, anXYZ3);
759   }
760
761   if (myTrihDispMode == Prs3d_DM_Shaded)
762   {
763     Handle(Select3D_SensitivePrimitiveArray) aSelArray = new Select3D_SensitivePrimitiveArray (theOwner);
764     aSelArray->InitTriangulation (aPrimitives->Attributes(), aPrimitives->Indices(), TopLoc_Location());
765     return aSelArray;
766   }
767
768   if (Handle(Graphic3d_ArrayOfPoints) aPoints = Handle(Graphic3d_ArrayOfPoints)::DownCast(aPrimitives))
769   {
770     const gp_Pnt anXYZ1 = aPoints->Vertice (1);
771     return new Select3D_SensitivePoint (theOwner, anXYZ1);
772   }
773   else if (Handle(Graphic3d_ArrayOfSegments) aSegments = Handle(Graphic3d_ArrayOfSegments)::DownCast(aPrimitives))
774   {
775     const gp_Pnt anXYZ1 = aSegments->Vertice (1);
776     const gp_Pnt anXYZ2 = aSegments->Vertice (2);
777     return new Select3D_SensitiveSegment (theOwner, anXYZ1, anXYZ2);
778   }
779   return Handle(SelectBasics_SensitiveEntity)();
780 }
781
782 // =======================================================================
783 // function : arrayOfPrimitives
784 // purpose  :
785 // =======================================================================
786 Handle(Graphic3d_ArrayOfPrimitives) AIS_Trihedron::arrayOfPrimitives(
787                                                Prs3d_DatumParts theDatumPart) const
788 {
789   Handle(Graphic3d_ArrayOfPrimitives) anArray;
790   myPrimitives.Find(theDatumPart, anArray);
791   return anArray;
792 }
793
794 // =======================================================================
795 // function : updatePrimitives
796 // purpose  :
797 // =======================================================================
798 void AIS_Trihedron::updatePrimitives(const Handle(Prs3d_DatumAspect)& theAspect,
799                                      Prs3d_DatumMode theMode,
800                                      const gp_Pnt& theOrigin,
801                                      const gp_Dir& theXDirection,
802                                      const gp_Dir& theYDirection,
803                                      const gp_Dir& theZDirection)
804 {
805   myPrimitives.Clear();
806
807   NCollection_DataMap<Prs3d_DatumParts, gp_Dir> anAxisDirs;
808   anAxisDirs.Bind(Prs3d_DP_XAxis, theXDirection);
809   anAxisDirs.Bind(Prs3d_DP_YAxis, theYDirection);
810   anAxisDirs.Bind(Prs3d_DP_ZAxis, theZDirection);
811
812   NCollection_DataMap<Prs3d_DatumParts, gp_Pnt> anAxisPoints;
813   gp_XYZ anXYZOrigin = theOrigin.XYZ();
814   for (int anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
815   {
816     Prs3d_DatumParts aPart = (Prs3d_DatumParts)anAxisIter;
817     anAxisPoints.Bind(aPart, gp_Pnt(anXYZOrigin + anAxisDirs.Find(aPart).XYZ() *
818                                                    theAspect->AxisLength(aPart)));
819   }
820
821   if (theMode == Prs3d_DM_WireFrame)
822   {
823     // origin
824     if (theAspect->DrawDatumPart(Prs3d_DP_Origin))
825     {
826       Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPoints(1);
827       aPrims->AddVertex(theOrigin);
828       myPrimitives.Bind(Prs3d_DP_Origin, aPrims);
829     }
830     // axes
831     for (int aPartIter = Prs3d_DP_XAxis; aPartIter <= Prs3d_DP_ZAxis; ++aPartIter)
832     {
833       const Prs3d_DatumParts aPart = (Prs3d_DatumParts)aPartIter;
834       if (theAspect->DrawDatumPart(aPart))
835       {
836         Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
837         aPrims->AddVertex(theOrigin);
838         aPrims->AddVertex(anAxisPoints.Find(aPart));
839         myPrimitives.Bind(aPart, aPrims);
840       }
841
842       Prs3d_DatumParts anArrowPart = theAspect->ArrowPartForAxis(aPart);
843       if (theAspect->DrawDatumPart(anArrowPart))
844       {
845         myPrimitives.Bind(anArrowPart,
846             Prs3d_Arrow::DrawSegments(anAxisPoints.Find(aPart), anAxisDirs.Find(aPart),
847             theAspect->ArrowAspect()->Angle(),
848             theAspect->AxisLength(aPart) * theAspect->Attribute(Prs3d_DP_ShadingConeLengthPercent),
849           (Standard_Integer)  theAspect->Attribute(Prs3d_DP_ShadingNumberOfFacettes)));
850       }
851     }
852   }
853   else
854   {
855     // shading mode
856     // origin
857     if (theAspect->DrawDatumPart(Prs3d_DP_Origin))
858     {
859       const Standard_Real aSphereRadius = theAspect->AxisLength(Prs3d_DP_XAxis) *
860                                           theAspect->Attribute(Prs3d_DP_ShadingOriginRadiusPercent);
861       const Standard_Integer aNbOfFacettes =
862                            (Standard_Integer)theAspect->Attribute(Prs3d_DP_ShadingNumberOfFacettes);
863       gp_Trsf aSphereTransform;
864       aSphereTransform.SetTranslationPart(gp_Vec(gp::Origin(), theOrigin));
865       myPrimitives.Bind(Prs3d_DP_Origin, Prs3d_ToolSphere::Create(aSphereRadius, aNbOfFacettes,
866                                                                   aNbOfFacettes, aSphereTransform));
867     }
868     // axes
869     {
870       const Standard_Integer aNbOfFacettes = 
871                                (Standard_Integer)theAspect->Attribute(Prs3d_DP_ShadingNumberOfFacettes);
872       const Standard_Real aTubeRadiusPercent = theAspect->Attribute(Prs3d_DP_ShadingTubeRadiusPercent);
873       const Standard_Real aConeLengthPercent = theAspect->Attribute(Prs3d_DP_ShadingConeLengthPercent);
874       const Standard_Real aConeRadiusPercent = theAspect->Attribute(Prs3d_DP_ShadingConeRadiusPercent);
875       for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
876       {
877         const Prs3d_DatumParts aPart = (Prs3d_DatumParts)anAxisIter;
878         const Prs3d_DatumParts anArrowPart = theAspect->ArrowPartForAxis(aPart);
879         const bool aDrawArrow = theAspect->DrawDatumPart(anArrowPart);
880         const Standard_Real anAxisLength = theAspect->AxisLength(aPart);
881         const gp_Ax1 anAxis(theOrigin, anAxisDirs.Find(aPart));
882
883         if (theAspect->DrawDatumPart(aPart))
884         {
885           // draw cylinder
886           myPrimitives.Bind(aPart,
887                             Prs3d_Arrow::DrawShaded(anAxis, anAxisLength * aTubeRadiusPercent,
888                             aDrawArrow ? anAxisLength - anAxisLength * aConeLengthPercent : anAxisLength,
889                             0.0, 0.0, aNbOfFacettes));
890         }
891
892         // draw arrow
893         if (aDrawArrow)
894         {
895           myPrimitives.Bind(anArrowPart, Prs3d_Arrow::DrawShaded(anAxis, 0.0, anAxisLength,
896                                                      anAxisLength * aConeRadiusPercent,
897                                                      anAxisLength * aConeLengthPercent, aNbOfFacettes));
898         }
899       }
900     }
901   }
902   // planes
903   for (Standard_Integer aPlaneIter = Prs3d_DP_XOYAxis; aPlaneIter <= Prs3d_DP_XOZAxis; ++aPlaneIter)
904   {
905     const Prs3d_DatumParts aPart = (Prs3d_DatumParts)aPlaneIter;
906     if (!theAspect->DrawDatumPart(aPart))
907     {
908       continue;
909     }
910
911     Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPolylines(4);
912     aPrims->AddVertex(theOrigin);
913
914     Prs3d_DatumParts aPart1 = Prs3d_DP_XAxis, aPart2 = Prs3d_DP_XAxis;
915     switch(aPart)
916     {
917       case Prs3d_DP_XOYAxis:
918       {
919         aPart1 = Prs3d_DP_XAxis;
920         aPart2 = Prs3d_DP_YAxis;
921         break;
922       }
923       case Prs3d_DP_YOZAxis:
924       {
925         aPart1 = Prs3d_DP_YAxis;
926         aPart2 = Prs3d_DP_ZAxis;
927         break;
928       }
929       case Prs3d_DP_XOZAxis:
930       {
931         aPart1 = Prs3d_DP_XAxis;
932         aPart2 = Prs3d_DP_ZAxis;
933         break;
934       }
935       default: break;
936     }
937     aPrims->AddVertex(anAxisPoints.Find(aPart1));
938     aPrims->AddVertex(anAxisPoints.Find(aPart2));
939
940     aPrims->AddVertex(theOrigin);
941     myPrimitives.Bind(aPart, aPrims);
942   }
943 }
944
945 // =======================================================================
946 // function : getHighlightAspect
947 // purpose  :
948 // =======================================================================
949 Handle(Prs3d_ShadingAspect) AIS_Trihedron::getHighlightAspect()
950 {
951   if (!myHighlightAspect.IsNull())
952     return myHighlightAspect;
953
954   Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
955   if (!myHilightDrawer.IsNull())
956     aHighlightColor = myHilightDrawer->Color();
957
958   myHighlightAspect = new Prs3d_ShadingAspect();
959   myHighlightAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
960   myHighlightAspect->SetColor (aHighlightColor);
961
962   Graphic3d_MaterialAspect aHighlightMaterial;
963   aHighlightMaterial.SetColor (aHighlightColor);
964   myHighlightAspect->SetMaterial (aHighlightMaterial);
965
966   return myHighlightAspect;
967 }
968
969 // =======================================================================
970 // function : getHighlightLineAspect
971 // purpose  :
972 // =======================================================================
973 Handle(Prs3d_LineAspect) AIS_Trihedron::getHighlightLineAspect()
974 {
975   if (!myHighlightLineAspect.IsNull())
976     return myHighlightLineAspect;
977
978   Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
979   if (!myHilightDrawer.IsNull())
980     aHighlightColor = myHilightDrawer->Color();
981
982   Handle(Prs3d_DatumAspect) aDatumAspect = Attributes()->DatumAspect();
983   Handle(Prs3d_LineAspect) aLineAspect = aDatumAspect->LineAspect(Prs3d_DP_XAxis);
984   myHighlightLineAspect = new Prs3d_LineAspect (aHighlightColor, aLineAspect->Aspect()->Type(),
985                                                 aLineAspect->Aspect()->Width());
986
987   return myHighlightLineAspect;
988 }
989
990 // =======================================================================
991 // function : getHighlightPointAspect
992 // purpose  :
993 // =======================================================================
994 Handle(Prs3d_PointAspect) AIS_Trihedron::getHighlightPointAspect()
995 {
996   if (!myHighlightPointAspect.IsNull())
997     return myHighlightPointAspect;
998
999   Quantity_Color aHighlightColor = Quantity_NOC_GRAY80;
1000   if (!myHilightDrawer.IsNull())
1001     aHighlightColor = myHilightDrawer->Color();
1002   myHighlightPointAspect = new Prs3d_PointAspect (Aspect_TOM_PLUS, aHighlightColor, 1.0);
1003
1004   return myHighlightPointAspect;
1005 }