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