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