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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified : 22/03/04 ; SAN : OCC4895 High-level interface for controlling polygon offsets
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>
47 //=======================================================================
48 //function : AIS_InteractiveObject
50 //=======================================================================
51 AIS_InteractiveObject::
52 AIS_InteractiveObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
53 SelectMgr_SelectableObject(aTypeOfPresentation3d),
55 myOwnColor(Quantity_NOC_WHITE),
56 myOwnMaterial(Graphic3d_NOM_DEFAULT),
59 myInfiniteState(Standard_False),
60 hasOwnColor(Standard_False),
61 hasOwnMaterial(Standard_False),
62 myCurrentFacingModel(Aspect_TOFM_BOTH_SIDE),
63 myRecomputeEveryPrs(Standard_True),
69 Handle (AIS_InteractiveContext) Bid;
70 myCTXPtr = Bid.operator->();
71 SetCurrentFacingModel();
74 //=======================================================================
75 //function : Redisplay
77 //=======================================================================
78 void AIS_InteractiveObject::Redisplay (const Standard_Boolean AllModes)
83 myCTXPtr->Redisplay (this, Standard_False, AllModes);
86 //=======================================================================
89 //=======================================================================
91 AIS_KindOfInteractive AIS_InteractiveObject::Type() const
92 {return AIS_KOI_None;}
94 //=======================================================================
95 //function : Signature
97 //=======================================================================
99 Standard_Integer AIS_InteractiveObject::Signature() const
102 //=======================================================================
103 //function : RecomputeEveryPrs
105 //=======================================================================
107 Standard_Boolean AIS_InteractiveObject::RecomputeEveryPrs() const
108 {return myRecomputeEveryPrs;}
110 //=======================================================================
113 //=======================================================================
114 Standard_Boolean AIS_InteractiveObject::HasInteractiveContext() const
116 Handle (AIS_InteractiveContext) aNull;
117 return (myCTXPtr != aNull.operator->());
120 //=======================================================================
123 //=======================================================================
124 Handle(AIS_InteractiveContext) AIS_InteractiveObject::GetContext() const
129 //=======================================================================
132 //=======================================================================
133 void AIS_InteractiveObject::SetContext(const Handle(AIS_InteractiveContext)& aCtx)
135 myCTXPtr = aCtx.operator->();
138 myDrawer->Link(aCtx->DefaultDrawer());
141 //=======================================================================
144 //=======================================================================
145 Standard_Boolean AIS_InteractiveObject::HasOwner() const
147 return (!myOwner.IsNull());
152 //=======================================================================
155 //=======================================================================
156 void AIS_InteractiveObject::ClearOwner()
161 //=======================================================================
164 //=======================================================================
165 Standard_Boolean AIS_InteractiveObject::HasUsers() const
167 return (!myUsers.IsEmpty());
171 //=======================================================================
174 //=======================================================================
175 void AIS_InteractiveObject::AddUser(const Handle(Standard_Transient)& aUser)
177 myUsers.Append(aUser);
180 //=======================================================================
183 //=======================================================================
184 void AIS_InteractiveObject::ClearUsers()
190 //=======================================================================
193 //=======================================================================
194 void AIS_InteractiveObject::SetDisplayMode(const Standard_Integer aMode)
196 if( AcceptDisplayMode(aMode) )
197 myDisplayMode = aMode;
200 //=======================================================================
203 //=======================================================================
204 void AIS_InteractiveObject::SetCurrentFacingModel(const Aspect_TypeOfFacingModel aModel) {
205 myCurrentFacingModel = aModel;
208 //=======================================================================
209 //function : CurrentFacingModel
211 //=======================================================================
213 Aspect_TypeOfFacingModel AIS_InteractiveObject::CurrentFacingModel() const {
214 return myCurrentFacingModel;
217 //=======================================================================
218 //function : SetColor
220 //=======================================================================
222 void AIS_InteractiveObject::SetColor(const Quantity_NameOfColor aColor)
224 SetColor(Quantity_Color(aColor));
227 //=======================================================================
228 //function : SetColor
230 //=======================================================================
232 void AIS_InteractiveObject::SetColor(const Quantity_Color &aColor)
235 hasOwnColor = Standard_True;
238 //=======================================================================
239 //function : UnsetColor
241 //=======================================================================
242 void AIS_InteractiveObject::UnsetColor()
244 hasOwnColor = Standard_False;
247 //=======================================================================
250 //=======================================================================
251 void AIS_InteractiveObject::SetWidth(const Standard_Real aValue)
256 //=======================================================================
259 //=======================================================================
260 void AIS_InteractiveObject::UnsetWidth()
266 //=======================================================================
269 //=======================================================================
270 void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
272 if( HasColor() || IsTransparent() || HasMaterial() )
274 myDrawer->ShadingAspect()->SetMaterial(aName);
278 myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
279 myDrawer->ShadingAspect()->SetMaterial(aName);
281 myOwnMaterial = aName;
282 hasOwnMaterial = Standard_True;
285 //=======================================================================
286 //function : SetMaterial
288 //=======================================================================
289 void AIS_InteractiveObject::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
291 if (!HasColor() && !IsTransparent() && !HasMaterial())
293 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect);
296 myDrawer->ShadingAspect()->SetMaterial (theMaterial);
298 hasOwnMaterial = Standard_True;
301 //=======================================================================
302 //function : UnsetMaterial
304 //=======================================================================
305 void AIS_InteractiveObject::UnsetMaterial()
312 if (HasColor() || IsTransparent())
314 if(myDrawer->HasLink())
316 myDrawer->ShadingAspect()->SetMaterial (AIS_GraphicTool::GetMaterial (myDrawer->Link()));
321 SetColor (myOwnColor);
326 SetTransparency (myTransparency);
331 Handle(Prs3d_ShadingAspect) anAspect;
332 myDrawer->SetShadingAspect (anAspect);
335 hasOwnMaterial = Standard_False;
338 //=======================================================================
339 //function : SetTransparency
341 //=======================================================================
342 void AIS_InteractiveObject::SetTransparency(const Standard_Real aValue)
344 if(!HasColor() && !IsTransparent() && !HasMaterial())
346 myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
347 if(myDrawer->HasLink())
348 myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
350 Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
351 Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
352 FMat.SetTransparency(aValue); BMat.SetTransparency(aValue);
353 myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
354 myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
355 myTransparency = aValue;
358 //=======================================================================
359 //function : UnsetTransparency
361 //=======================================================================
362 void AIS_InteractiveObject::UnsetTransparency()
364 if(HasColor() || HasMaterial() )
366 Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
367 Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
368 FMat.SetTransparency(0.); BMat.SetTransparency(0.);
369 myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
370 myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
373 Handle (Prs3d_ShadingAspect) SA;
374 myDrawer->SetShadingAspect(SA);
378 //=======================================================================
379 //function : Transparency
381 //=======================================================================
382 Standard_Real AIS_InteractiveObject::Transparency() const
384 return (myTransparency<=0.05 ? 0 : myTransparency);
385 // Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
386 // return Mat.Transparency();
389 //=======================================================================
390 //function : UnsetAttributes
392 //=======================================================================
393 void AIS_InteractiveObject::UnsetAttributes()
395 SelectMgr_SelectableObject::UnsetAttributes();
397 hasOwnColor = Standard_False;
398 hasOwnMaterial = Standard_False;
400 myTransparency = 0.0;
403 //=======================================================================
406 //=======================================================================
407 void AIS_InteractiveObject::MustRecomputePrs(const Standard_Integer ) const
410 //=======================================================================
413 //=======================================================================
414 const TColStd_ListOfInteger& AIS_InteractiveObject::ListOfRecomputeModes() const
415 {return myToRecomputeModes;}
417 //=======================================================================
420 //=======================================================================
421 void AIS_InteractiveObject::SetRecomputeOk()
422 {myToRecomputeModes.Clear();}
425 //=======================================================================
426 //function : AcceptDisplayMode
428 //=======================================================================
430 Standard_Boolean AIS_InteractiveObject::AcceptDisplayMode(const Standard_Integer ) const
431 {return Standard_True;}
433 //=======================================================================
434 //function : DefaultDisplayMode
436 //=======================================================================
438 Standard_Integer AIS_InteractiveObject::DefaultDisplayMode() const
442 //=======================================================================
443 //function : SetInfiniteState
445 //=======================================================================
446 void AIS_InteractiveObject::SetInfiniteState(const Standard_Boolean aFlag)
448 myInfiniteState = aFlag;
449 Handle(Prs3d_Presentation) P;
451 for(Standard_Integer i =1; i<=myPresentations.Length();i++)
453 P = myPresentations(i).Presentation()->Presentation();
455 P->SetInfiniteState(myInfiniteState);
459 //=======================================================================
460 //function : HasPresentation
462 //=======================================================================
463 Standard_Boolean AIS_InteractiveObject::HasPresentation() const
465 return !GetContext().IsNull()
466 && GetContext()->MainPrsMgr()->HasPresentation (this, myDisplayMode);
469 //=======================================================================
470 //function : Presentation
472 //=======================================================================
473 Handle(Prs3d_Presentation) AIS_InteractiveObject::Presentation() const
475 return HasPresentation()
476 ? GetContext()->MainPrsMgr()->Presentation (this, myDisplayMode)->Presentation()
477 : Handle(Prs3d_Presentation)();
480 //=======================================================================
481 //function : SetAspect
483 //=======================================================================
484 void AIS_InteractiveObject::SetAspect(const Handle(Prs3d_BasicAspect)& anAspect,
485 const Standard_Boolean globalChange) {
487 if( HasPresentation() ) {
488 Handle(Prs3d_Presentation) prs = Presentation();
489 { Handle(Prs3d_ShadingAspect) aspect =
490 Handle(Prs3d_ShadingAspect)::DownCast(anAspect);
491 if( !aspect.IsNull() ) {
492 if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
493 Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
497 { Handle(Prs3d_LineAspect) aspect =
498 Handle(Prs3d_LineAspect)::DownCast(anAspect);
499 if( !aspect.IsNull() ) {
500 if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
501 Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
505 { Handle(Prs3d_PointAspect) aspect =
506 Handle(Prs3d_PointAspect)::DownCast(anAspect);
507 if( !aspect.IsNull() ) {
508 if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
509 Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
513 { Handle(Prs3d_TextAspect) aspect =
514 Handle(Prs3d_TextAspect)::DownCast(anAspect);
515 if( !aspect.IsNull() ) {
516 if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
517 Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
524 //=======================================================================
525 //function : SetPolygonOffsets
527 //=======================================================================
528 void AIS_InteractiveObject::SetPolygonOffsets(const Standard_Integer aMode,
529 const Standard_ShortReal aFactor,
530 const Standard_ShortReal aUnits)
532 if ( !HasPolygonOffsets() )
533 myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
535 myDrawer->ShadingAspect()->Aspect()->SetPolygonOffsets( aMode, aFactor, aUnits );
537 // Modify existing presentations
538 for (Standard_Integer aPrsIter = 1, n = myPresentations.Length(); aPrsIter <= n; ++aPrsIter)
540 const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
541 if ( !aPrs3d.IsNull() ) {
542 const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
543 if( !aStruct.IsNull() ) {
544 aStruct->SetPrimitivesAspect( myDrawer->ShadingAspect()->Aspect() );
545 // Workaround for issue 23115: Need to update also groups, because their
546 // face aspect ALWAYS overrides the structure's.
547 const Graphic3d_SequenceOfGroup& aGroups = aStruct->Groups();
548 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
550 Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
552 || !aGrp->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
557 Handle(Graphic3d_AspectFillArea3d) aFaceAsp = new Graphic3d_AspectFillArea3d();
558 Handle(Graphic3d_AspectLine3d) aLineAsp = new Graphic3d_AspectLine3d();
559 Handle(Graphic3d_AspectMarker3d) aPntAsp = new Graphic3d_AspectMarker3d();
560 Handle(Graphic3d_AspectText3d) aTextAsp = new Graphic3d_AspectText3d();
561 // TODO: Add methods for retrieving individual aspects from Graphic3d_Group
562 aGrp->GroupPrimitivesAspect(aLineAsp, aTextAsp, aPntAsp, aFaceAsp);
563 aFaceAsp->SetPolygonOffsets(aMode, aFactor, aUnits);
564 aGrp->SetGroupPrimitivesAspect(aFaceAsp);
571 //=======================================================================
572 //function : HasPolygonOffsets
574 //=======================================================================
575 Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets() const
577 return !( myDrawer->ShadingAspect().IsNull() ||
578 ( myDrawer->HasLink() &&
579 myDrawer->ShadingAspect() == myDrawer->Link()->ShadingAspect() ) );
582 //=======================================================================
583 //function : PolygonOffsets
585 //=======================================================================
586 void AIS_InteractiveObject::PolygonOffsets(Standard_Integer& aMode,
587 Standard_ShortReal& aFactor,
588 Standard_ShortReal& aUnits) const
590 if( HasPolygonOffsets() )
591 myDrawer->ShadingAspect()->Aspect()->PolygonOffsets( aMode, aFactor, aUnits );
594 //=======================================================================
595 //function : BoundingBox
596 //purpose : Returns bounding box of object correspondingly to its
597 // current display mode
598 //=======================================================================
599 void AIS_InteractiveObject::BoundingBox (Bnd_Box& theBndBox)
601 if (myDisplayMode == -1)
603 if (!myPresentations.IsEmpty())
605 const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations.First().Presentation();
606 const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
607 const Graphic3d_BndBox4f& aBndBox = aStruct->CStructure()->BoundingBox();
609 if (!aBndBox.IsValid())
615 theBndBox.Update (static_cast<Standard_Real> (aBndBox.CornerMin().x()),
616 static_cast<Standard_Real> (aBndBox.CornerMin().y()),
617 static_cast<Standard_Real> (aBndBox.CornerMin().z()),
618 static_cast<Standard_Real> (aBndBox.CornerMax().x()),
619 static_cast<Standard_Real> (aBndBox.CornerMax().y()),
620 static_cast<Standard_Real> (aBndBox.CornerMax().z()));
625 for (PrsMgr_ListOfPresentableObjectsIter aPrsIter (Children()); aPrsIter.More(); aPrsIter.Next())
627 Handle(AIS_InteractiveObject) aChild (Handle(AIS_InteractiveObject)::DownCast (aPrsIter.Value()));
633 aChild->BoundingBox (aBox);
634 theBndBox.Add (aBox);
641 for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
643 if (myPresentations (aPrsIter).Mode() == myDisplayMode)
645 const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
646 const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
647 const Graphic3d_BndBox4f& aBndBox = aStruct->CStructure()->BoundingBox();
649 if (!aBndBox.IsValid())
655 theBndBox.Update (static_cast<Standard_Real> (aBndBox.CornerMin().x()),
656 static_cast<Standard_Real> (aBndBox.CornerMin().y()),
657 static_cast<Standard_Real> (aBndBox.CornerMin().z()),
658 static_cast<Standard_Real> (aBndBox.CornerMax().x()),
659 static_cast<Standard_Real> (aBndBox.CornerMax().y()),
660 static_cast<Standard_Real> (aBndBox.CornerMax().z()));