0024623: Visualization - improve selection mechanism
[occt.git] / src / AIS / AIS_InteractiveObject.cxx
CommitLineData
b311480e 1// Created on: 1996-12-18
2// Created by: Robert COUBLANC
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17// Modified : 22/03/04 ; SAN : OCC4895 High-level interface for controlling polygon offsets
18
7fd59977 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>
3ddebf91 33#include <Graphic3d_AspectLine3d.hxx>
34#include <Graphic3d_AspectMarker3d.hxx>
35#include <Graphic3d_AspectText3d.hxx>
f751596e 36#include <Graphic3d_BndBox4f.hxx>
37#include <Graphic3d_CStructure.hxx>
7fd59977 38#include <Graphic3d_Group.hxx>
39#include <Graphic3d_Structure.hxx>
40
41
42//=======================================================================
43//function : AIS_InteractiveObject
44//purpose :
45//=======================================================================
46
47AIS_InteractiveObject::
48AIS_InteractiveObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
49SelectMgr_SelectableObject(aTypeOfPresentation3d),
7fd59977 50myTransparency(0.),
51myOwnColor(Quantity_NOC_WHITE),
a0ed63ac 52myOwnMaterial(Graphic3d_NOM_DEFAULT),
7fd59977 53myHilightMode(-1),
54myOwnWidth(0.0),
55myInfiniteState(Standard_False),
56hasOwnColor(Standard_False),
57hasOwnMaterial(Standard_False),
a0ed63ac 58myCurrentFacingModel(Aspect_TOFM_BOTH_SIDE),
7fd59977 59myRecomputeEveryPrs(Standard_True),
a0ed63ac 60myCTXPtr(NULL),
7fd59977 61mySelPriority(-1),
62myDisplayMode (-1),
63mySelectionMode(0),
0717ddc1 64mystate(0)
7fd59977 65{
66 Handle (AIS_InteractiveContext) Bid;
67 myCTXPtr = Bid.operator->();
7fd59977 68 SetCurrentFacingModel();
7fd59977 69}
70
71//=======================================================================
72//function : Redisplay
36132a2e 73//purpose :
7fd59977 74//=======================================================================
36132a2e 75void AIS_InteractiveObject::Redisplay (const Standard_Boolean AllModes)
7fd59977 76{
36132a2e 77 if (myCTXPtr == NULL)
78 return;
79
80 myCTXPtr->Redisplay (this, Standard_False, AllModes);
7fd59977 81}
82
83//=======================================================================
84//function : Type
85//purpose :
86//=======================================================================
87
88AIS_KindOfInteractive AIS_InteractiveObject::Type() const
89{return AIS_KOI_None;}
90
91//=======================================================================
92//function : Signature
93//purpose :
94//=======================================================================
95
96Standard_Integer AIS_InteractiveObject::Signature() const
97{return -1;}
98
99//=======================================================================
100//function : RecomputeEveryPrs
101//purpose :
102//=======================================================================
103
104Standard_Boolean AIS_InteractiveObject::RecomputeEveryPrs() const
105{return myRecomputeEveryPrs;}
106
107//=======================================================================
108//function :
109//purpose :
110//=======================================================================
111Standard_Boolean AIS_InteractiveObject::HasInteractiveContext() const
112{
113 Handle (AIS_InteractiveContext) aNull;
114 return (myCTXPtr != aNull.operator->());
115}
116
117//=======================================================================
118//function :
119//purpose :
120//=======================================================================
121Handle(AIS_InteractiveContext) AIS_InteractiveObject::GetContext() const
122{
123 return myCTXPtr;
124}
125
126//=======================================================================
127//function :
128//purpose :
129//=======================================================================
130void AIS_InteractiveObject::SetContext(const Handle(AIS_InteractiveContext)& aCtx)
131{
132 myCTXPtr = aCtx.operator->();
da0e82aa 133 if( aCtx.IsNull())
134 return;
7fd59977 135 myDrawer->Link(aCtx->DefaultDrawer());
136}
137
138//=======================================================================
139//function :
140//purpose :
141//=======================================================================
142Standard_Boolean AIS_InteractiveObject::HasOwner() const
143{
144 return (!myOwner.IsNull());
145}
146
147
148
149//=======================================================================
150//function :
151//purpose :
152//=======================================================================
153void AIS_InteractiveObject::ClearOwner()
154{
155 myOwner.Nullify();
156}
157
158//=======================================================================
159//function :
160//purpose :
161//=======================================================================
162Standard_Boolean AIS_InteractiveObject::HasUsers() const
163{
164 return (!myUsers.IsEmpty());
165}
166
167
168//=======================================================================
169//function :
170//purpose :
171//=======================================================================
172void AIS_InteractiveObject::AddUser(const Handle(Standard_Transient)& aUser)
173{
174 myUsers.Append(aUser);
175}
176
177//=======================================================================
178//function :
179//purpose :
180//=======================================================================
181void AIS_InteractiveObject::ClearUsers()
182{
183 myUsers.Clear();
184}
185
186
187//=======================================================================
188//function :
189//purpose :
190//=======================================================================
191void AIS_InteractiveObject::SetDisplayMode(const Standard_Integer aMode)
192{
7fd59977 193 if( AcceptDisplayMode(aMode) )
7fd59977 194 myDisplayMode = aMode;
195}
196
197
198//=======================================================================
199//function :
200//purpose :
201//=======================================================================
202void AIS_InteractiveObject::SetSelectionMode(const Standard_Integer aMode)
203{
204 mySelectionMode = aMode;
205}
206
207
208
209//=======================================================================
210//function :
211//purpose :
212//=======================================================================
7fd59977 213void AIS_InteractiveObject::SetCurrentFacingModel(const Aspect_TypeOfFacingModel aModel) {
214 myCurrentFacingModel = aModel;
215}
216
217//=======================================================================
218//function : CurrentFacingModel
219//purpose :
220//=======================================================================
221
222Aspect_TypeOfFacingModel AIS_InteractiveObject::CurrentFacingModel() const {
223 return myCurrentFacingModel;
224}
7fd59977 225
226//=======================================================================
227//function : SetColor
228//purpose :
229//=======================================================================
230
231void AIS_InteractiveObject::SetColor(const Quantity_NameOfColor aColor)
7fd59977 232{
233 SetColor(Quantity_Color(aColor));
234}
235
236//=======================================================================
237//function : SetColor
238//purpose :
239//=======================================================================
240
241void AIS_InteractiveObject::SetColor(const Quantity_Color &aColor)
7fd59977 242{
243 myOwnColor = aColor;
244 hasOwnColor = Standard_True;
245}
246
247//=======================================================================
248//function : UnsetColor
249//purpose :
250//=======================================================================
251void AIS_InteractiveObject::UnsetColor()
252{
253 hasOwnColor = Standard_False;
254}
255
256//=======================================================================
257//function :
258//purpose :
259//=======================================================================
260void AIS_InteractiveObject::SetWidth(const Standard_Real aValue)
261{
262 myOwnWidth = aValue;
263}
264
265//=======================================================================
266//function :
267//purpose :
268//=======================================================================
269void AIS_InteractiveObject::UnsetWidth()
270{
271 myOwnWidth = 0.;
272}
273
274
275//=======================================================================
276//function :
277//purpose :
278//=======================================================================
279//POP pour K4L
280void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
281//void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfPhysicalMaterial aName)
282{
283 if( HasColor() || IsTransparent() || HasMaterial() )
6262338c 284 {
285 myDrawer->ShadingAspect()->SetMaterial(aName);
286 }
287 else
288 {
289 myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
290 myDrawer->ShadingAspect()->SetMaterial(aName);
291 }
7fd59977 292 myOwnMaterial = aName;
293 hasOwnMaterial = Standard_True;
294}
295//=======================================================================
296//function : SetMaterial
297//purpose :
298//=======================================================================
299
300void AIS_InteractiveObject::SetMaterial(const Graphic3d_MaterialAspect& aMat)
301{
6262338c 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 }
7fd59977 311 hasOwnMaterial = Standard_True;
7fd59977 312}
313//=======================================================================
314//function :
315//purpose :
316//=======================================================================
317void AIS_InteractiveObject::UnsetMaterial()
318{
7fd59977 319 if( !HasMaterial() ) return;
6262338c 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);
7fd59977 328 }
7fd59977 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//=======================================================================
340void AIS_InteractiveObject::SetTransparency(const Standard_Real aValue)
341{
6262338c 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()));
7fd59977 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);
7fd59977 353 myTransparency = aValue;
354}
355
356//=======================================================================
357//function : UnsetTransparency
358//purpose :
359//=======================================================================
360void AIS_InteractiveObject::UnsetTransparency()
361{
6262338c 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 }
7fd59977 370 else{
371 Handle (Prs3d_ShadingAspect) SA;
372 myDrawer->SetShadingAspect(SA);
373 }
374 myTransparency =0.0;
375}
376//=======================================================================
377//function : Transparency
378//purpose :
379//=======================================================================
380Standard_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
7fd59977 387//=======================================================================
388//function : UnsetAttributes
389//purpose :
390//=======================================================================
391void AIS_InteractiveObject::UnsetAttributes()
392{
6262338c 393 SelectMgr_SelectableObject::UnsetAttributes();
394
7fd59977 395 hasOwnColor = Standard_False;
396 hasOwnMaterial = Standard_False;
397 myOwnWidth = 0.0;
398 myTransparency = 0.0;
399}
400
401//=======================================================================
402//function :
403//purpose :
404//=======================================================================
405void AIS_InteractiveObject::MustRecomputePrs(const Standard_Integer ) const
406{}
407
408//=======================================================================
409//function :
410//purpose :
411//=======================================================================
412const TColStd_ListOfInteger& AIS_InteractiveObject::ListOfRecomputeModes() const
413{return myToRecomputeModes;}
414
415//=======================================================================
416//function :
417//purpose :
418//=======================================================================
419void AIS_InteractiveObject::SetRecomputeOk()
420{myToRecomputeModes.Clear();}
421
422
423//=======================================================================
424//function : AcceptDisplayMode
425//purpose :
426//=======================================================================
427
428Standard_Boolean AIS_InteractiveObject::AcceptDisplayMode(const Standard_Integer ) const
429{return Standard_True;}
430
431//=======================================================================
432//function : DefaultDisplayMode
433//purpose :
434//=======================================================================
435
436Standard_Integer AIS_InteractiveObject::DefaultDisplayMode() const
437{return 0;}
438
439
440//=======================================================================
441//function : SetInfiniteState
442//purpose :
443//=======================================================================
444void AIS_InteractiveObject::SetInfiniteState(const Standard_Boolean aFlag)
445{
446 myInfiniteState = aFlag;
447 Handle(Prs3d_Presentation) P;
448
5e5b6f81 449 for(Standard_Integer i =1; i<=myPresentations.Length();i++)
450 {
451 P = myPresentations(i).Presentation()->Presentation();
7fd59977 452 if(!P.IsNull())
5e5b6f81 453 P->SetInfiniteState(myInfiniteState);
454 }
7fd59977 455}
456
7fd59977 457//=======================================================================
458//function : HasPresentation
af324faa 459//purpose :
7fd59977 460//=======================================================================
af324faa 461Standard_Boolean AIS_InteractiveObject::HasPresentation() const
462{
463 return !GetContext().IsNull()
464 && GetContext()->MainPrsMgr()->HasPresentation (this, myDisplayMode);
7fd59977 465}
466
467//=======================================================================
468//function : Presentation
af324faa 469//purpose :
7fd59977 470//=======================================================================
af324faa 471Handle(Prs3d_Presentation) AIS_InteractiveObject::Presentation() const
472{
473 return HasPresentation()
474 ? GetContext()->MainPrsMgr()->Presentation (this, myDisplayMode)->Presentation()
475 : Handle(Prs3d_Presentation)();
7fd59977 476}
477
478//=======================================================================
479//function : SetAspect
480//purpose :
481//=======================================================================
482void 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}
7fd59977 521
522//=======================================================================
523//function : SetPolygonOffsets
524//purpose :
525//=======================================================================
60be1f9b 526void AIS_InteractiveObject::SetPolygonOffsets(const Standard_Integer aMode,
527 const Standard_ShortReal aFactor,
528 const Standard_ShortReal aUnits)
7fd59977 529{
530 if ( !HasPolygonOffsets() )
531 myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
532
533 myDrawer->ShadingAspect()->Aspect()->SetPolygonOffsets( aMode, aFactor, aUnits );
534
535 // Modify existing presentations
af324faa 536 for (Standard_Integer aPrsIter = 1, n = myPresentations.Length(); aPrsIter <= n; ++aPrsIter)
537 {
538 const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
7fd59977 539 if ( !aPrs3d.IsNull() ) {
af324faa 540 const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
3ddebf91 541 if( !aStruct.IsNull() ) {
7fd59977 542 aStruct->SetPrimitivesAspect( myDrawer->ShadingAspect()->Aspect() );
3ddebf91 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();
b64d84be 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;
3ddebf91 553 }
b64d84be 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);
3ddebf91 563 }
564 }
7fd59977 565 }
566 }
567}
568
7fd59977 569//=======================================================================
570//function : HasPolygonOffsets
571//purpose :
572//=======================================================================
573Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets() const
574{
575 return !( myDrawer->ShadingAspect().IsNull() ||
6262338c 576 ( myDrawer->HasLink() &&
7fd59977 577 myDrawer->ShadingAspect() == myDrawer->Link()->ShadingAspect() ) );
578}
579
580//=======================================================================
581//function : PolygonOffsets
582//purpose :
583//=======================================================================
60be1f9b 584void AIS_InteractiveObject::PolygonOffsets(Standard_Integer& aMode,
585 Standard_ShortReal& aFactor,
586 Standard_ShortReal& aUnits) const
7fd59977 587{
588 if( HasPolygonOffsets() )
589 myDrawer->ShadingAspect()->Aspect()->PolygonOffsets( aMode, aFactor, aUnits );
590}
f751596e 591
592//=======================================================================
593//function : BoundingBox
594//purpose : Returns bounding box of object correspondingly to its
595// current display mode
596//=======================================================================
597void 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 theBndBox.Update (static_cast<Standard_Real> (aBndBox.CornerMin().x()),
607 static_cast<Standard_Real> (aBndBox.CornerMin().y()),
608 static_cast<Standard_Real> (aBndBox.CornerMin().z()),
609 static_cast<Standard_Real> (aBndBox.CornerMax().x()),
610 static_cast<Standard_Real> (aBndBox.CornerMax().y()),
611 static_cast<Standard_Real> (aBndBox.CornerMax().z()));
612 return;
613 }
614 else
615 {
616 for (PrsMgr_ListOfPresentableObjectsIter aPrsIter (Children()); aPrsIter.More(); aPrsIter.Next())
617 {
618 const Handle(AIS_InteractiveObject)& aChild = Handle(AIS_InteractiveObject)::DownCast (aPrsIter.Value());
619 if (aChild.IsNull())
620 {
621 continue;
622 }
623 Bnd_Box aBox;
624 aChild->BoundingBox (aBox);
625 theBndBox.Add (aBox);
626 }
627 return;
628 }
629 }
630 else
631 {
632 for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
633 {
634 if (myPresentations (aPrsIter).Mode() == myDisplayMode)
635 {
636 const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
637 const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
638 const Graphic3d_BndBox4f& aBndBox = aStruct->CStructure()->BoundingBox();
639 theBndBox.Update (static_cast<Standard_Real> (aBndBox.CornerMin().x()),
640 static_cast<Standard_Real> (aBndBox.CornerMin().y()),
641 static_cast<Standard_Real> (aBndBox.CornerMin().z()),
642 static_cast<Standard_Real> (aBndBox.CornerMax().x()),
643 static_cast<Standard_Real> (aBndBox.CornerMax().y()),
644 static_cast<Standard_Real> (aBndBox.CornerMax().z()));
645 return;
646 }
647 }
648 }
649}