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