0026146: Visualization, Select3D_ISensitivePointSet - eliminate crash when clearing...
[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.ixx>
18 #include <DsgPrs_DatumPrs.hxx>
19 #include <SelectBasics_EntityOwner.hxx>
20 #include <SelectMgr_EntityOwner.hxx>
21 #include <Select3D_SensitiveSegment.hxx>
22 #include <Select3D_SensitivePoint.hxx>
23 #include <Geom_Axis2Placement.hxx>
24 #include <Geom_Line.hxx>
25 #include <Geom_Point.hxx>
26 #include <Geom_Plane.hxx>
27 #include <Geom_CartesianPoint.hxx>
28 #include <gp_Dir.hxx>
29 #include <gp_Ax1.hxx>
30 #include <gp_Ax2.hxx>
31 #include <gp_Pnt.hxx>
32 #include <gp_Vec.hxx>
33 #include <Prs3d_Drawer.hxx>
34 #include <Prs3d_LineAspect.hxx>
35 #include <Prs3d_TextAspect.hxx>
36 #include <Prs3d_ArrowAspect.hxx>
37 #include <Prs3d_DatumAspect.hxx>
38 #include <Graphic3d_AspectLine3d.hxx>
39 #include <Graphic3d_Structure.hxx>
40 #include <Graphic3d_MaterialAspect.hxx>
41 #include <Graphic3d_AspectFillArea3d.hxx>
42 #include <Aspect_TypeOfLine.hxx>
43 #include <AIS_Plane.hxx>
44 #include <AIS_Axis.hxx>
45 #include <AIS_Point.hxx>
46 #include <UnitsAPI.hxx>
47
48 #include <Select3D_SensitiveBox.hxx>
49 #include <Select3D_SensitiveTriangle.hxx>
50 #include <TColgp_Array1OfPnt.hxx>
51
52
53
54 //=======================================================================
55 //function : AIS_Trihedron
56 //purpose  : 
57 //=======================================================================
58 AIS_Trihedron::AIS_Trihedron(const Handle(Geom_Axis2Placement)& aComponent):
59 myComponent(aComponent),
60 myHasOwnSize(Standard_False),
61 myHasOwnTextColor(Standard_False),
62 myHasOwnArrowColor(Standard_False)
63
64 {  LoadSubObjects();}
65
66
67
68 //=======================================================================
69 //function : SetComponent
70 //purpose  : 
71 //=======================================================================
72
73 void AIS_Trihedron::SetComponent(const Handle(Geom_Axis2Placement)& aComponent)
74 {
75   myComponent = aComponent;
76
77   // Remove from current context and nullify objects to update
78   Handle(AIS_InteractiveContext) anAISContext = GetContext();
79   Standard_Boolean hasContext = (anAISContext.IsNull() == Standard_False);
80   Standard_Integer anIdx;
81   for (anIdx = 0; anIdx < 7; anIdx++)
82   {
83     // Deselect object
84     if (hasContext)
85     {
86       if (anAISContext->IsSelected (myShapes[anIdx]))
87         anAISContext->AddOrRemoveSelected (myShapes[anIdx], Standard_False);
88
89       anAISContext->Remove (myShapes[anIdx], Standard_False);
90     }
91     myShapes[anIdx].Nullify();
92   }
93
94   LoadSubObjects();
95 }
96
97 //=======================================================================
98 //function : SetLocation
99 //purpose  : 
100 //=======================================================================
101
102 void AIS_Trihedron::SetLocalTransformation (const gp_Trsf& theTransformation)
103 {
104   // Update location to the subshapes
105   Standard_Integer anIdx;
106   for (anIdx = 0; anIdx < 7; anIdx++)
107     myShapes[anIdx]->SetLocalTransformation (theTransformation);
108
109   AIS_InteractiveObject::SetLocalTransformation (theTransformation);
110 }
111
112 //=======================================================================
113 //function : SetSize
114 //purpose  : 
115 //=======================================================================
116 void AIS_Trihedron::SetSize(const Standard_Real aValue)
117 {
118   myHasOwnSize = Standard_True;
119   if(!myDrawer->HasOwnDatumAspect()){
120     Handle (Prs3d_DatumAspect) DA = new Prs3d_DatumAspect();
121     myDrawer->SetDatumAspect(DA);
122   }
123   
124   myDrawer->DatumAspect()->SetAxisLength(aValue,aValue,aValue);
125   
126   for(Standard_Integer i=4;i<=6;i++) 
127     (*((Handle(AIS_Plane)*)&myShapes[i]))->SetSize(aValue);
128
129   Update();
130   UpdateSelection();
131 }
132
133
134
135 //=======================================================================
136 //function : UnsetSize
137 //purpose  : if the object has 1 color, the default size of the 
138 //           drawer is reproduced, otherwise DatumAspect becomes null
139 //=======================================================================
140
141 void AIS_Trihedron::UnsetSize()
142 {
143   if(!myHasOwnSize) return;
144   
145   myHasOwnSize = Standard_False;
146   if(hasOwnColor){
147     const Handle(Prs3d_DatumAspect) DA =
148       myDrawer->HasLink() ? myDrawer->Link()->DatumAspect() : new Prs3d_DatumAspect();
149     myDrawer->DatumAspect()->SetAxisLength(DA->FirstAxisLength(),
150                                            DA->SecondAxisLength(),
151                                            DA->ThirdAxisLength());
152   }
153   else
154   {
155     myDrawer->SetDatumAspect (Handle(Prs3d_DatumAspect)());
156   }
157   Update();
158   UpdateSelection();
159
160 }
161
162 //=======================================================================
163 //function : Size
164 //purpose  : 
165 //=======================================================================
166
167 Standard_Real AIS_Trihedron::Size() const 
168 {
169   return myDrawer->DatumAspect()->FirstAxisLength();
170 }
171
172 //=======================================================================
173 //function : XAxis
174 //purpose  : 
175 //=======================================================================
176 Handle(AIS_Axis) AIS_Trihedron::XAxis() const 
177 {
178   Handle(AIS_Axis) anAxis = Handle(AIS_Axis)::DownCast(myShapes[1]);
179   if (anAxis.IsNull()) anAxis = new AIS_Axis (myComponent,AIS_TOAX_XAxis);
180   return anAxis;
181 }
182
183 //=======================================================================
184 //function : YAxis
185 //purpose  : 
186 //=======================================================================
187 Handle(AIS_Axis) AIS_Trihedron::YAxis() const 
188 {
189   Handle(AIS_Axis) anAxis = Handle(AIS_Axis)::DownCast(myShapes[2]);
190   if (anAxis.IsNull()) anAxis = new AIS_Axis (myComponent,AIS_TOAX_YAxis);
191   return anAxis;
192 }
193
194 //=======================================================================
195 //function : Axis
196 //purpose  : 
197 //=======================================================================
198 Handle(AIS_Axis) AIS_Trihedron::Axis() const 
199 {
200   Handle(AIS_Axis) anAxis = Handle(AIS_Axis)::DownCast(myShapes[3]);
201   if (anAxis.IsNull()) anAxis = new AIS_Axis (myComponent,AIS_TOAX_ZAxis);
202   return anAxis;
203 }
204
205 //=======================================================================
206 //function : Position
207 //purpose  : 
208 //=======================================================================
209 Handle(AIS_Point) AIS_Trihedron::Position() const 
210 {
211   Handle(AIS_Point) aPt = Handle(AIS_Point)::DownCast(myShapes[0]);
212   if (aPt.IsNull()) {
213     gp_Pnt aPnt = myComponent->Ax2().Location();
214     Handle(Geom_Point) aPoint = new Geom_CartesianPoint(aPnt);
215     aPt = new AIS_Point (aPoint);
216   }
217   return aPt;
218 }
219
220 //=======================================================================
221 //function : XYPlane
222 //purpose  : 
223 //=======================================================================
224 Handle(AIS_Plane) AIS_Trihedron::XYPlane() const 
225 {
226   Handle(AIS_Plane) aPl = Handle(AIS_Plane)::DownCast(myShapes[4]);
227   if (aPl.IsNull()) aPl = new AIS_Plane (myComponent,AIS_TOPL_XYPlane);
228   return aPl;
229 }
230
231 //=======================================================================
232 //function : XZPlane
233 //purpose  : 
234 //=======================================================================
235 Handle(AIS_Plane) AIS_Trihedron::XZPlane() const 
236 {
237   Handle(AIS_Plane) aPl = Handle(AIS_Plane)::DownCast(myShapes[5]);
238   if (aPl.IsNull()) aPl = new AIS_Plane (myComponent,AIS_TOPL_XZPlane);
239   return aPl;
240 }
241
242 //=======================================================================
243 //function : YZPlane
244 //purpose  : 
245 //=======================================================================
246 Handle(AIS_Plane) AIS_Trihedron::YZPlane() const 
247 {
248   Handle(AIS_Plane) aPl = Handle(AIS_Plane)::DownCast(myShapes[6]);
249   if (aPl.IsNull()) aPl = new AIS_Plane (myComponent,AIS_TOPL_YZPlane);
250   return aPl;
251 }
252
253 //=======================================================================
254 //function : Compute
255 //purpose  : 
256 //=======================================================================
257 void AIS_Trihedron::Compute(
258  const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
259  const Handle(Prs3d_Presentation)& aPresentation, 
260  const Standard_Integer aMode)
261 {
262   aPresentation->Clear();
263
264   aPresentation->SetInfiniteState (Standard_True);
265   switch(aMode){
266   case 0: 
267     DsgPrs_DatumPrs::Add(aPresentation,myComponent->Ax2(),myDrawer);
268     break;
269   case 1:
270     break;
271   case 2:
272     break;
273   }
274 }
275
276 //=======================================================================
277 //function : Compute
278 //purpose  : 
279 //=======================================================================
280
281 void AIS_Trihedron::Compute(const Handle(Prs3d_Projector)& aProjector,
282                             const Handle(Geom_Transformation)& aTransformation,
283                             const Handle(Prs3d_Presentation)& aPresentation)
284 {
285 // Standard_NotImplemented::Raise("AIS_Trihedron::Compute(const Handle(Prs3d_Projector)&, const Handle(Geom_Transformation)&, const Handle(Prs3d_Presentation)&)");
286  PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation) ;
287 }
288
289 //=======================================================================
290 //function : ComputeSelection
291 //purpose  : 
292 //=======================================================================
293
294 void AIS_Trihedron::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
295                                      const Standard_Integer aMode)
296 {
297   // retrieve the tops of the trihedron.
298   Standard_Integer Prior, anIdx;
299   Handle(SelectMgr_EntityOwner) eown;
300   TColgp_Array1OfPnt PP(1,4),PO(1,4);
301   ExtremityPoints(PP);
302
303   // remove shapes from active selections
304   Handle(AIS_InteractiveContext) anAISContext = GetContext();
305   if (!anAISContext.IsNull())
306     for (anIdx = 0; anIdx < 7; anIdx++)
307     {
308       // Deselect object
309       if (anAISContext->IsSelected (myShapes[anIdx]))
310         anAISContext->AddOrRemoveSelected (myShapes[anIdx], Standard_False);
311
312       anAISContext->Remove (myShapes[anIdx], Standard_False);
313     }
314   
315   switch (aMode) {
316   case 0:
317     {   // complete triedron only 1 owner : this... priority 5 (same as faces)
318       Prior = 5;
319       eown = new SelectMgr_EntityOwner(this,Prior);
320       for (Standard_Integer i=1; i<=3;i++)
321         aSelection->Add(new Select3D_SensitiveSegment(eown,PP(1),PP(i+1)));
322       break;
323     }
324   case 1:
325     {  //origin : 
326       Prior = 8;
327       eown= new SelectMgr_EntityOwner(myShapes[0],Prior);
328       
329       aSelection->Add(new Select3D_SensitivePoint (eown,myComponent->Location()));
330       // If the trihedron's shapes display and selection modes are the same
331       // the shapes are still displayed after selection, so we need to
332       // use different presentation and hide it by nullifying
333       if (!anAISContext.IsNull())
334       {
335         anAISContext->Display (myShapes[0], 1, 0, Standard_False);
336         anAISContext->ClearPrs (myShapes[0], 1, Standard_False);
337       }
338       
339       break;
340     }
341   case 2:
342     {  //axes ... priority 7
343       Prior = 7;
344       for (Standard_Integer i=1; i<=3;i++){
345         eown= new SelectMgr_EntityOwner(myShapes[i],Prior);
346         aSelection->Add(new Select3D_SensitiveSegment(eown,PP(1),PP(i+1)));
347
348       }
349
350       // If the trihedron's shapes display and selection modes are the same
351       // the shapes are still displayed after selection, so we need to
352       // use different presentation and hide it by nullifying
353       AIS_TypeOfAxis anAxisType;
354       if (!anAISContext.IsNull())
355         for (anIdx = 1; anIdx <= 3; anIdx++)
356         {
357           // update AIS_Axis for selection
358           Handle(AIS_Axis) anAxis = Handle(AIS_Axis)::DownCast(myShapes[anIdx]);
359           Handle(Prs3d_Drawer) aDrawer = anAxis->Attributes();
360           Handle(Prs3d_DatumAspect) aDatum = myDrawer->DatumAspect();
361           aDrawer->DatumAspect()->SetAxisLength (aDatum->FirstAxisLength(),
362                                                  aDatum->SecondAxisLength(),
363                                                  aDatum->ThirdAxisLength());
364           anAxisType = anAxis->TypeOfAxis();
365           anAxis->SetAxis2Placement (myComponent, anAxisType);
366
367           // display
368           anAISContext->Display (myShapes[anIdx], 1, 0, Standard_False);
369           anAISContext->ClearPrs (myShapes[anIdx], 1, Standard_False);
370         }
371       
372       break;
373     }
374     
375   case 3:
376     {  // main planes priority 6
377 //      PO(1) = PP(1);
378 //      PO(4) = PP(1);
379       Prior =5;
380       
381       
382       eown= new SelectMgr_EntityOwner(myShapes[4],Prior);
383 //      PO(2) = PP(2);PO(3) = PP(3);
384       aSelection->Add(new Select3D_SensitiveTriangle(eown,PP(1),PP(2),PP(3)));
385
386       eown= new SelectMgr_EntityOwner(myShapes[5],Prior);
387 //      PO(2) = PP(3);PO(3) = PP(4);
388       aSelection->Add(new Select3D_SensitiveTriangle(eown,PP(1),PP(2),PP(4)));
389
390       eown= new SelectMgr_EntityOwner(myShapes[6],Prior);
391 //      PO(2) = PP(4);PO(3) = PP(2);
392       aSelection->Add(new Select3D_SensitiveTriangle(eown,PP(1),PP(3),PP(4)));
393       
394       // If the trihedron's shapes display and selection modes are the same
395       // the shapes are still displayed after selection, so we need to
396       // use different presentation and hide it by nullifying
397       if (!anAISContext.IsNull())
398         for (anIdx = 4; anIdx < 7; anIdx++)
399         {
400           anAISContext->Display (myShapes[anIdx], 1, 0, Standard_False);
401           anAISContext->ClearPrs (myShapes[anIdx], 1, Standard_False);
402         }
403     }
404   }
405   
406 }
407
408 //=======================================================================
409 //function : SetColor
410 //purpose  : 
411 //=======================================================================
412
413 void AIS_Trihedron::SetColor(const Quantity_NameOfColor aCol)
414 {
415   SetColor(Quantity_Color(aCol));
416 }
417
418 void AIS_Trihedron::SetColor(const Quantity_Color &aCol)
419 {
420   hasOwnColor=Standard_True;
421   myOwnColor = aCol;
422   
423   if(!myDrawer->HasOwnDatumAspect()){
424     Handle (Prs3d_DatumAspect) DA = new Prs3d_DatumAspect();
425     
426     DA->SetAxisLength(myDrawer->DatumAspect()->FirstAxisLength(),
427                       myDrawer->DatumAspect()->SecondAxisLength(),
428                       myDrawer->DatumAspect()->ThirdAxisLength());
429     myDrawer->SetDatumAspect(DA);
430   }
431   myDrawer->DatumAspect()->FirstAxisAspect()->SetColor(aCol);
432   myDrawer->DatumAspect()->SecondAxisAspect()->SetColor(aCol);
433   myDrawer->DatumAspect()->ThirdAxisAspect()->SetColor(aCol);
434
435 }
436
437 //=======================================================================
438 //function : SetTextColor
439 //purpose  : 
440 //=======================================================================
441
442 void AIS_Trihedron::SetTextColor(const Quantity_NameOfColor aCol)
443 {
444   myHasOwnTextColor = Standard_True;
445   myOwnTextColor = aCol;
446   
447   if(!myDrawer->HasOwnDatumAspect()){
448     Handle (Prs3d_DatumAspect) DA = new Prs3d_DatumAspect();
449     
450     DA->SetAxisLength(myDrawer->DatumAspect()->FirstAxisLength(),
451                       myDrawer->DatumAspect()->SecondAxisLength(),
452                       myDrawer->DatumAspect()->ThirdAxisLength());
453     myDrawer->SetDatumAspect(DA);
454   }
455   Handle(Prs3d_TextAspect) aspect = myDrawer->TextAspect();
456   aspect->SetColor(aCol);
457   myDrawer->SetTextAspect(aspect);
458 }
459
460 void AIS_Trihedron::SetArrowColor(const Quantity_NameOfColor aCol)
461 {
462   myHasOwnArrowColor = Standard_True;
463   myOwnArrowColor = aCol;
464   
465   if(!myDrawer->HasOwnDatumAspect()){
466     Handle (Prs3d_DatumAspect) DA = new Prs3d_DatumAspect();
467     
468     DA->SetAxisLength(myDrawer->DatumAspect()->FirstAxisLength(),
469                       myDrawer->DatumAspect()->SecondAxisLength(),
470                       myDrawer->DatumAspect()->ThirdAxisLength());
471     myDrawer->SetDatumAspect(DA);
472   }
473   Handle(Prs3d_ArrowAspect) aspect = myDrawer->ArrowAspect();
474   aspect->SetColor(aCol);
475   myDrawer->SetArrowAspect(aspect);
476 }
477
478 //=======================================================================
479 Standard_Boolean AIS_Trihedron::HasTextColor() const {
480
481   return myHasOwnTextColor;
482 }
483
484 //=======================================================================
485 Quantity_NameOfColor AIS_Trihedron::TextColor() const {
486
487   return myOwnTextColor;
488 }
489
490 //=======================================================================
491 Standard_Boolean AIS_Trihedron::HasArrowColor() const {
492
493   return myHasOwnArrowColor;
494 }
495
496 //=======================================================================
497 Quantity_NameOfColor AIS_Trihedron::ArrowColor() const {
498
499   return myOwnArrowColor;
500 }
501
502
503 //=======================================================================
504 //function : Compute
505 //purpose  : to avoid warning
506 //=======================================================================
507 void AIS_Trihedron::Compute(const Handle(Prs3d_Projector)&, 
508                                const Handle(Prs3d_Presentation)&)
509 {
510 }
511 //=======================================================================
512 //function : Type
513 //purpose  : 
514 //=======================================================================
515
516 AIS_KindOfInteractive AIS_Trihedron::Type() const 
517 {return AIS_KOI_Datum;}
518
519
520 //=======================================================================
521 //function : Signature
522 //purpose  : 
523 //=======================================================================
524
525  Standard_Integer AIS_Trihedron::Signature() const 
526 {return 3;}
527
528 //=======================================================================
529 //function : ExtremityPoints
530 //purpose  : to avoid warning
531 //=======================================================================
532 void  AIS_Trihedron::ExtremityPoints(TColgp_Array1OfPnt& PP) const 
533 {
534   gp_Ax2 theax(myComponent->Ax2());
535   PP(1) = theax.Location();
536
537   Standard_Real len = myDrawer->DatumAspect()->FirstAxisLength();
538   gp_Vec vec = theax.XDirection();
539   vec *= len;
540   PP(2) = PP(1).Translated(vec);
541   
542   len = myDrawer->DatumAspect()->SecondAxisLength();
543   vec = theax.YDirection();
544   vec *= len;
545   PP(3) = PP(1).Translated(vec);
546
547   len = myDrawer->DatumAspect()->ThirdAxisLength();
548   vec = theax.Direction();
549   vec *= len;
550   PP(4) = PP(1).Translated(vec);
551 }
552
553 //=======================================================================
554 //function : AcceptDisplayMode
555 //purpose  : 
556 //=======================================================================
557
558  Standard_Boolean  AIS_Trihedron::
559 AcceptDisplayMode(const Standard_Integer aMode) const
560 {return aMode == 0;}
561
562
563
564 //=======================================================================
565 //function : UnsetColor
566 //purpose  : 
567 //=======================================================================
568
569 void AIS_Trihedron::UnsetColor()
570 {
571   hasOwnColor=Standard_False;
572   myOwnColor = Quantity_NOC_LIGHTSTEELBLUE4;
573   myDrawer->DatumAspect()->FirstAxisAspect()->SetColor(myOwnColor);
574   myDrawer->DatumAspect()->SecondAxisAspect()->SetColor(myOwnColor);
575   myDrawer->DatumAspect()->ThirdAxisAspect()->SetColor(myOwnColor);
576   if( HasTextColor() ) {
577     SetTextColor(myOwnColor.Name());
578     myHasOwnTextColor = Standard_False;
579   }
580   if( HasArrowColor() ) {
581     SetArrowColor(myOwnColor.Name());
582     myHasOwnArrowColor = Standard_False;
583   }
584   
585 }
586
587 //=======================================================================
588 //function : UnsetWitdth
589 //purpose  : 
590 //=======================================================================
591
592 void AIS_Trihedron::UnsetWidth()
593 {
594   myOwnWidth =0.0;
595   myDrawer->DatumAspect()->FirstAxisAspect()->SetWidth(1.);
596   myDrawer->DatumAspect()->SecondAxisAspect()->SetWidth(1.);
597   myDrawer->DatumAspect()->ThirdAxisAspect()->SetWidth(1.);
598
599 }
600 void AIS_Trihedron::LoadSubObjects()
601 {
602   myShapes[0] = Position();
603   myShapes[1] = XAxis();
604   myShapes[2] = YAxis();
605   myShapes[3] = Axis();
606   myShapes[4] = XYPlane();
607   myShapes[5] = XZPlane();
608   myShapes[6] = YZPlane();
609 }
610
611 //=======================================================================
612 //function : SetContext
613 //purpose  : 
614 //=======================================================================
615
616 void AIS_Trihedron::SetContext(const Handle(AIS_InteractiveContext)& Ctx)
617 {
618 //  Standard_Boolean same_DA = myDrawer->Link() == Ctx->DefaultDrawer();
619    
620    if( Ctx.IsNull())
621    {
622       Standard_Integer anIdx;
623       for (anIdx = 0; anIdx < 7; anIdx++)
624       {
625         myShapes[anIdx]->SetContext(Ctx);
626       }
627      AIS_InteractiveObject::SetContext (Ctx);
628      return;
629    }
630   // Remove subobjects from current context
631   Handle(AIS_InteractiveContext) anAISContext = GetContext();
632   
633   Standard_Boolean hasContext = (anAISContext.IsNull() == Standard_False);
634   Standard_Integer anIdx;
635   for (anIdx = 0; anIdx < 7; anIdx++)
636     {
637       // Deselect object
638       if (hasContext)
639         {
640           if (anAISContext->IsSelected (myShapes[anIdx]))
641             anAISContext->AddOrRemoveSelected (myShapes[anIdx]);
642           
643           anAISContext->Remove (myShapes[anIdx], Standard_False);
644         }
645       myShapes[anIdx].Nullify();
646     }
647  
648   AIS_InteractiveObject::SetContext (Ctx);
649   LoadSubObjects();
650   for(Standard_Integer i= 0;i<=6;i++)
651     myShapes[i]->SetContext (Ctx);
652 }