0026076: Visualization - empty bounding box of a shape after closing local context
[occt.git] / src / AIS / AIS_InteractiveObject.cxx
1 // Created on: 1996-12-18
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1996-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 // Modified :   22/03/04 ; SAN : OCC4895 High-level interface for controlling polygon offsets 
18
19 #include <AIS_InteractiveObject.ixx>
20
21 #include <Aspect_PolygonOffsetMode.hxx>
22 #include <Prs3d_ShadingAspect.hxx>
23 #include <Prs3d_LineAspect.hxx>
24 #include <Prs3d_PointAspect.hxx>
25 #include <Prs3d_TextAspect.hxx>
26 #include <Prs3d_Presentation.hxx>
27 #include <Prs3d_Root.hxx>
28 #include <PrsMgr_ModedPresentation.hxx>
29 #include <PrsMgr_PresentationManager3d.hxx>
30 #include <TColStd_ListIteratorOfListOfInteger.hxx>
31 #include <AIS_GraphicTool.hxx>
32 #include <Graphic3d_AspectFillArea3d.hxx>
33 #include <Graphic3d_AspectLine3d.hxx>
34 #include <Graphic3d_AspectMarker3d.hxx>
35 #include <Graphic3d_AspectText3d.hxx>
36 #include <Graphic3d_BndBox4f.hxx>
37 #include <Graphic3d_CStructure.hxx>
38 #include <Graphic3d_Group.hxx>
39 #include <Graphic3d_Structure.hxx>
40
41
42 //=======================================================================
43 //function : AIS_InteractiveObject
44 //purpose  : 
45 //=======================================================================
46
47 AIS_InteractiveObject::
48 AIS_InteractiveObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
49 SelectMgr_SelectableObject(aTypeOfPresentation3d),
50 myTransparency(0.),
51 myOwnColor(Quantity_NOC_WHITE),
52 myOwnMaterial(Graphic3d_NOM_DEFAULT),
53 myHilightMode(-1),
54 myOwnWidth(0.0),
55 myInfiniteState(Standard_False),
56 hasOwnColor(Standard_False),
57 hasOwnMaterial(Standard_False),
58 myCurrentFacingModel(Aspect_TOFM_BOTH_SIDE),
59 myRecomputeEveryPrs(Standard_True),
60 myCTXPtr(NULL),
61 mySelPriority(-1),
62 myDisplayMode (-1),
63 mySelectionMode(0),
64 mystate(0)
65 {
66   Handle (AIS_InteractiveContext) Bid;
67   myCTXPtr = Bid.operator->();
68   SetCurrentFacingModel();
69 }
70
71 //=======================================================================
72 //function : Redisplay
73 //purpose  :
74 //=======================================================================
75 void AIS_InteractiveObject::Redisplay (const Standard_Boolean AllModes)
76 {
77   if (myCTXPtr == NULL)
78     return;
79
80   myCTXPtr->Redisplay (this, Standard_False, AllModes);
81 }
82
83 //=======================================================================
84 //function : Type
85 //purpose  : 
86 //=======================================================================
87
88 AIS_KindOfInteractive AIS_InteractiveObject::Type() const 
89 {return AIS_KOI_None;}
90
91 //=======================================================================
92 //function : Signature
93 //purpose  : 
94 //=======================================================================
95
96 Standard_Integer AIS_InteractiveObject::Signature() const 
97 {return -1;}
98
99 //=======================================================================
100 //function : RecomputeEveryPrs
101 //purpose  : 
102 //=======================================================================
103
104 Standard_Boolean  AIS_InteractiveObject::RecomputeEveryPrs() const 
105 {return myRecomputeEveryPrs;}
106
107 //=======================================================================
108 //function : 
109 //purpose  : 
110 //=======================================================================
111 Standard_Boolean AIS_InteractiveObject::HasInteractiveContext() const 
112 {
113   Handle (AIS_InteractiveContext) aNull;
114   return  (myCTXPtr != aNull.operator->());
115 }
116
117 //=======================================================================
118 //function : 
119 //purpose  : 
120 //=======================================================================
121 Handle(AIS_InteractiveContext) AIS_InteractiveObject::GetContext() const 
122 {
123   return myCTXPtr;
124 }
125
126 //=======================================================================
127 //function : 
128 //purpose  : 
129 //=======================================================================
130 void AIS_InteractiveObject::SetContext(const Handle(AIS_InteractiveContext)& aCtx)
131 {
132   myCTXPtr = aCtx.operator->();
133   if( aCtx.IsNull())
134     return;
135   myDrawer->Link(aCtx->DefaultDrawer());
136 }
137
138 //=======================================================================
139 //function : 
140 //purpose  : 
141 //=======================================================================
142 Standard_Boolean AIS_InteractiveObject::HasOwner() const 
143 {
144   return (!myOwner.IsNull());
145 }
146
147
148
149 //=======================================================================
150 //function : 
151 //purpose  : 
152 //=======================================================================
153 void AIS_InteractiveObject::ClearOwner()
154 {
155   myOwner.Nullify();
156 }
157
158 //=======================================================================
159 //function : 
160 //purpose  : 
161 //=======================================================================
162 Standard_Boolean AIS_InteractiveObject::HasUsers() const 
163 {
164   return (!myUsers.IsEmpty());
165 }
166
167
168 //=======================================================================
169 //function : 
170 //purpose  : 
171 //=======================================================================
172 void AIS_InteractiveObject::AddUser(const Handle(Standard_Transient)& aUser)
173 {
174   myUsers.Append(aUser);
175 }
176
177 //=======================================================================
178 //function : 
179 //purpose  : 
180 //=======================================================================
181 void AIS_InteractiveObject::ClearUsers()
182 {
183   myUsers.Clear();
184 }
185
186
187 //=======================================================================
188 //function : 
189 //purpose  : 
190 //=======================================================================
191 void AIS_InteractiveObject::SetDisplayMode(const Standard_Integer aMode)
192 {
193   if( AcceptDisplayMode(aMode) )
194     myDisplayMode = aMode;
195 }
196   
197
198 //=======================================================================
199 //function : 
200 //purpose  : 
201 //=======================================================================
202 void AIS_InteractiveObject::SetSelectionMode(const Standard_Integer aMode)
203 {
204   mySelectionMode = aMode;
205 }
206
207
208
209 //=======================================================================
210 //function : 
211 //purpose  : 
212 //=======================================================================
213 void AIS_InteractiveObject::SetCurrentFacingModel(const Aspect_TypeOfFacingModel aModel) {
214   myCurrentFacingModel = aModel;
215 }
216
217 //=======================================================================
218 //function : CurrentFacingModel
219 //purpose  : 
220 //=======================================================================
221
222 Aspect_TypeOfFacingModel AIS_InteractiveObject::CurrentFacingModel() const {
223   return myCurrentFacingModel;
224 }
225
226 //=======================================================================
227 //function : SetColor
228 //purpose  : 
229 //=======================================================================
230
231 void AIS_InteractiveObject::SetColor(const Quantity_NameOfColor aColor)
232 {
233   SetColor(Quantity_Color(aColor));
234 }
235
236 //=======================================================================
237 //function : SetColor
238 //purpose  : 
239 //=======================================================================
240
241 void AIS_InteractiveObject::SetColor(const Quantity_Color &aColor)
242 {
243   myOwnColor = aColor;
244   hasOwnColor = Standard_True;
245 }
246
247 //=======================================================================
248 //function : UnsetColor
249 //purpose  : 
250 //=======================================================================
251 void AIS_InteractiveObject::UnsetColor()
252 {
253   hasOwnColor = Standard_False;
254 }
255
256 //=======================================================================
257 //function : 
258 //purpose  : 
259 //=======================================================================
260 void AIS_InteractiveObject::SetWidth(const Standard_Real aValue)
261 {
262   myOwnWidth = aValue;
263 }
264
265 //=======================================================================
266 //function : 
267 //purpose  : 
268 //=======================================================================
269 void AIS_InteractiveObject::UnsetWidth()
270 {
271   myOwnWidth = 0.;
272 }
273
274
275 //=======================================================================
276 //function : 
277 //purpose  : 
278 //=======================================================================
279 //POP pour K4L
280 void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
281 //void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfPhysicalMaterial aName)
282 {
283   if( HasColor() || IsTransparent() || HasMaterial() )
284   {
285     myDrawer->ShadingAspect()->SetMaterial(aName);
286   }
287   else
288   {
289     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
290     myDrawer->ShadingAspect()->SetMaterial(aName);
291   }
292   myOwnMaterial  = aName;
293   hasOwnMaterial = Standard_True;
294 }
295 //=======================================================================
296 //function : SetMaterial
297 //purpose  : 
298 //=======================================================================
299
300 void AIS_InteractiveObject::SetMaterial(const Graphic3d_MaterialAspect& aMat)
301 {
302   if (HasColor() || IsTransparent() || HasMaterial())
303   {
304     myDrawer->ShadingAspect()->SetMaterial(aMat);
305   }
306   else
307   {
308     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
309     myDrawer->ShadingAspect()->SetMaterial(aMat);
310   }
311   hasOwnMaterial = Standard_True;
312 }
313 //=======================================================================
314 //function : 
315 //purpose  : 
316 //=======================================================================
317 void AIS_InteractiveObject::UnsetMaterial()
318 {
319   if( !HasMaterial() ) return;
320   if (HasColor() || IsTransparent())
321   {
322     if(myDrawer->HasLink())
323     {
324       myDrawer->ShadingAspect()->SetMaterial (AIS_GraphicTool::GetMaterial (myDrawer->Link()));
325     }
326     if (HasColor()) SetColor (myOwnColor);
327     if (IsTransparent()) SetTransparency (myTransparency);
328   }
329   else{
330     Handle(Prs3d_ShadingAspect) SA;
331     myDrawer->SetShadingAspect(SA);
332   }
333   hasOwnMaterial = Standard_False;
334 }
335
336 //=======================================================================
337 //function : SetTransparency
338 //purpose  : 
339 //=======================================================================
340 void AIS_InteractiveObject::SetTransparency(const Standard_Real aValue)
341 {
342   if(!HasColor() && !IsTransparent() && !HasMaterial())
343   {
344     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
345     if(myDrawer->HasLink())
346       myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
347   }
348   Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
349   Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
350   FMat.SetTransparency(aValue); BMat.SetTransparency(aValue);
351   myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
352   myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
353   myTransparency = aValue;
354 }
355
356 //=======================================================================
357 //function : UnsetTransparency
358 //purpose  : 
359 //=======================================================================
360 void AIS_InteractiveObject::UnsetTransparency()
361 {
362   if(HasColor() || HasMaterial() )
363   {
364     Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
365     Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
366     FMat.SetTransparency(0.); BMat.SetTransparency(0.);
367     myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
368     myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
369   }
370   else{
371     Handle (Prs3d_ShadingAspect) SA;
372     myDrawer->SetShadingAspect(SA);
373   }
374   myTransparency =0.0;
375 }
376 //=======================================================================
377 //function : Transparency
378 //purpose  : 
379 //=======================================================================
380 Standard_Real AIS_InteractiveObject::Transparency() const 
381 {
382   return (myTransparency<=0.05 ? 0 : myTransparency);
383 // Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
384 // return Mat.Transparency();
385 }
386
387 //=======================================================================
388 //function : UnsetAttributes
389 //purpose  : 
390 //=======================================================================
391 void AIS_InteractiveObject::UnsetAttributes()
392 {
393   SelectMgr_SelectableObject::UnsetAttributes();
394
395   hasOwnColor    = Standard_False;
396   hasOwnMaterial = Standard_False;
397   myOwnWidth     = 0.0;
398   myTransparency = 0.0;
399 }
400
401 //=======================================================================
402 //function : 
403 //purpose  : 
404 //=======================================================================
405 void AIS_InteractiveObject::MustRecomputePrs(const Standard_Integer ) const 
406 {}
407
408 //=======================================================================
409 //function : 
410 //purpose  : 
411 //=======================================================================
412 const TColStd_ListOfInteger& AIS_InteractiveObject::ListOfRecomputeModes() const 
413 {return myToRecomputeModes;}
414
415 //=======================================================================
416 //function : 
417 //purpose  : 
418 //=======================================================================
419 void AIS_InteractiveObject::SetRecomputeOk()
420 {myToRecomputeModes.Clear();}
421
422
423 //=======================================================================
424 //function : AcceptDisplayMode
425 //purpose  : 
426 //=======================================================================
427
428 Standard_Boolean  AIS_InteractiveObject::AcceptDisplayMode(const Standard_Integer ) const
429 {return Standard_True;}
430
431 //=======================================================================
432 //function : DefaultDisplayMode
433 //purpose  : 
434 //=======================================================================
435
436 Standard_Integer AIS_InteractiveObject::DefaultDisplayMode() const
437 {return 0;}
438
439
440 //=======================================================================
441 //function : SetInfiniteState
442 //purpose  : 
443 //=======================================================================
444 void AIS_InteractiveObject::SetInfiniteState(const Standard_Boolean aFlag)
445 {
446   myInfiniteState = aFlag;
447   Handle(Prs3d_Presentation) P;
448
449   for(Standard_Integer i =1; i<=myPresentations.Length();i++)
450   {
451     P = myPresentations(i).Presentation()->Presentation();
452     if(!P.IsNull())
453       P->SetInfiniteState(myInfiniteState);
454   }
455 }
456
457 //=======================================================================
458 //function : HasPresentation
459 //purpose  :
460 //=======================================================================
461 Standard_Boolean AIS_InteractiveObject::HasPresentation() const
462 {
463   return !GetContext().IsNull()
464        && GetContext()->MainPrsMgr()->HasPresentation (this, myDisplayMode);
465 }
466
467 //=======================================================================
468 //function : Presentation
469 //purpose  :
470 //=======================================================================
471 Handle(Prs3d_Presentation) AIS_InteractiveObject::Presentation() const
472 {
473   return HasPresentation()
474        ? GetContext()->MainPrsMgr()->Presentation (this, myDisplayMode)->Presentation()
475        : Handle(Prs3d_Presentation)();
476 }
477
478 //=======================================================================
479 //function : SetAspect 
480 //purpose  : 
481 //=======================================================================
482 void AIS_InteractiveObject::SetAspect(const Handle(Prs3d_BasicAspect)& anAspect,
483                                       const Standard_Boolean globalChange) {
484
485   if( HasPresentation() ) {
486     Handle(Prs3d_Presentation) prs = Presentation();
487     { Handle(Prs3d_ShadingAspect) aspect =
488                         Handle(Prs3d_ShadingAspect)::DownCast(anAspect);
489       if( !aspect.IsNull() ) {
490         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
491         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
492         return;
493       }
494     }
495     { Handle(Prs3d_LineAspect) aspect =
496                         Handle(Prs3d_LineAspect)::DownCast(anAspect);
497       if( !aspect.IsNull() ) {
498         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
499         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
500         return;
501       }
502     }
503     { Handle(Prs3d_PointAspect) aspect =
504                         Handle(Prs3d_PointAspect)::DownCast(anAspect);
505       if( !aspect.IsNull() ) {
506         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
507         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
508         return;
509       }
510     }
511     { Handle(Prs3d_TextAspect) aspect =
512                         Handle(Prs3d_TextAspect)::DownCast(anAspect);
513       if( !aspect.IsNull() ) {
514         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
515         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
516         return;
517       }
518     }
519   }
520 }
521
522 //=======================================================================
523 //function : SetPolygonOffsets 
524 //purpose  : 
525 //======================================================================= 
526 void AIS_InteractiveObject::SetPolygonOffsets(const Standard_Integer    aMode,
527                                               const Standard_ShortReal  aFactor,
528                                               const Standard_ShortReal  aUnits) 
529 {
530   if ( !HasPolygonOffsets() )
531     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
532
533   myDrawer->ShadingAspect()->Aspect()->SetPolygonOffsets( aMode, aFactor, aUnits );
534
535   // Modify existing presentations 
536   for (Standard_Integer aPrsIter = 1, n = myPresentations.Length(); aPrsIter <= n; ++aPrsIter)
537   {
538     const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
539     if ( !aPrs3d.IsNull() ) {
540       const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
541       if( !aStruct.IsNull() ) {
542         aStruct->SetPrimitivesAspect( myDrawer->ShadingAspect()->Aspect() );
543         // Workaround for issue 23115: Need to update also groups, because their
544         // face aspect ALWAYS overrides the structure's.
545         const Graphic3d_SequenceOfGroup& aGroups = aStruct->Groups();
546         for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
547         {
548           Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
549           if (aGrp.IsNull()
550           || !aGrp->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
551           {
552             continue;
553           }
554
555           Handle(Graphic3d_AspectFillArea3d) aFaceAsp = new Graphic3d_AspectFillArea3d();
556           Handle(Graphic3d_AspectLine3d)     aLineAsp = new Graphic3d_AspectLine3d();
557           Handle(Graphic3d_AspectMarker3d)   aPntAsp  = new Graphic3d_AspectMarker3d();
558           Handle(Graphic3d_AspectText3d)     aTextAsp = new Graphic3d_AspectText3d();
559           // TODO: Add methods for retrieving individual aspects from Graphic3d_Group
560           aGrp->GroupPrimitivesAspect(aLineAsp, aTextAsp, aPntAsp, aFaceAsp);
561           aFaceAsp->SetPolygonOffsets(aMode, aFactor, aUnits);
562           aGrp->SetGroupPrimitivesAspect(aFaceAsp);
563         }
564       }
565     }
566   }
567 }
568
569 //=======================================================================
570 //function : HasPolygonOffsets 
571 //purpose  : 
572 //=======================================================================
573 Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets() const
574 {
575   return !( myDrawer->ShadingAspect().IsNull() || 
576           ( myDrawer->HasLink() &&
577           myDrawer->ShadingAspect() == myDrawer->Link()->ShadingAspect() ) );
578 }
579
580 //=======================================================================
581 //function : PolygonOffsets 
582 //purpose  : 
583 //=======================================================================
584 void AIS_InteractiveObject::PolygonOffsets(Standard_Integer&    aMode,
585                                            Standard_ShortReal&  aFactor,
586                                            Standard_ShortReal&  aUnits) const 
587 {
588   if( HasPolygonOffsets() )
589     myDrawer->ShadingAspect()->Aspect()->PolygonOffsets( aMode, aFactor, aUnits );
590 }
591
592 //=======================================================================
593 //function : BoundingBox
594 //purpose  : Returns bounding box of object correspondingly to its
595 //           current display mode
596 //=======================================================================
597 void AIS_InteractiveObject::BoundingBox (Bnd_Box& theBndBox)
598 {
599   if (myDisplayMode == -1)
600   {
601     if (!myPresentations.IsEmpty())
602     {
603       const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations.First().Presentation();
604       const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
605       const Graphic3d_BndBox4f& aBndBox = aStruct->CStructure()->BoundingBox();
606
607       if (!aBndBox.IsValid())
608       {
609         theBndBox.SetVoid();
610         return;
611       }
612
613       theBndBox.Update (static_cast<Standard_Real> (aBndBox.CornerMin().x()),
614                         static_cast<Standard_Real> (aBndBox.CornerMin().y()),
615                         static_cast<Standard_Real> (aBndBox.CornerMin().z()),
616                         static_cast<Standard_Real> (aBndBox.CornerMax().x()),
617                         static_cast<Standard_Real> (aBndBox.CornerMax().y()),
618                         static_cast<Standard_Real> (aBndBox.CornerMax().z()));
619       return;
620     }
621     else
622     {
623       for (PrsMgr_ListOfPresentableObjectsIter aPrsIter (Children()); aPrsIter.More(); aPrsIter.Next())
624       {
625         const Handle(AIS_InteractiveObject)& aChild = Handle(AIS_InteractiveObject)::DownCast (aPrsIter.Value());
626         if (aChild.IsNull())
627         {
628           continue;
629         }
630         Bnd_Box aBox;
631         aChild->BoundingBox (aBox);
632         theBndBox.Add (aBox);
633       }
634       return;
635     }
636   }
637   else
638   {
639     for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
640     {
641       if (myPresentations (aPrsIter).Mode() == myDisplayMode)
642       {
643         const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
644         const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
645         const Graphic3d_BndBox4f& aBndBox = aStruct->CStructure()->BoundingBox();
646
647         if (!aBndBox.IsValid())
648         {
649           theBndBox.SetVoid();
650           return;
651         }
652
653         theBndBox.Update (static_cast<Standard_Real> (aBndBox.CornerMin().x()),
654                           static_cast<Standard_Real> (aBndBox.CornerMin().y()),
655                           static_cast<Standard_Real> (aBndBox.CornerMin().z()),
656                           static_cast<Standard_Real> (aBndBox.CornerMax().x()),
657                           static_cast<Standard_Real> (aBndBox.CornerMax().y()),
658                           static_cast<Standard_Real> (aBndBox.CornerMax().z()));
659         return;
660       }
661     }
662   }
663 }