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