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