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