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