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