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