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