0022947: XCAFPrs_AISObject.cxx: array index out of bounds
[occt.git] / src / XCAFPrs / XCAFPrs_AISObject.cxx
1 // File:        XCAFPrs_AISObject.cxx
2 // Created:     Fri Aug 11 16:49:09 2000
3 // Author:      Andrey BETENEV
4
5 #include <XCAFPrs_AISObject.ixx>
6 #include <TCollection_ExtendedString.hxx>
7 #include <gp_Pnt.hxx>
8 #include <Prs3d_Text.hxx>
9 #include <Prs3d_LengthAspect.hxx>
10 #include <XCAFDoc_ShapeTool.hxx>
11
12 #include <Standard_ErrorHandler.hxx>
13 #include <Standard_Failure.hxx>
14
15 #include <Precision.hxx>
16 #include <TopoDS_Shape.hxx>
17 #include <TopoDS_Iterator.hxx>
18 #include <BRepTools.hxx>
19
20 #include <StdPrs_WFDeflectionShape.hxx>
21 #include <StdPrs_ShadedShape.hxx>
22 #include <StdPrs_WFShape.hxx>
23 #include <AIS_Drawer.hxx>
24 #include <Graphic3d_Array1OfVertex.hxx>
25 #include <Graphic3d_Group.hxx>
26 #include <Quantity_Color.hxx>
27 #include <Aspect_TypeOfLine.hxx>
28 #include <Prs3d_LineAspect.hxx>
29 #include <Graphic3d_AspectLine3d.hxx>
30 #include <BRep_Builder.hxx>
31 #include <TopoDS_Compound.hxx>
32 #include <XCAFPrs_Style.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <XCAFPrs_DataMapOfShapeStyle.hxx>
35 #include <TDF_LabelSequence.hxx>
36 #include <XCAFPrs_DataMapOfStyleShape.hxx>
37 #include <TopoDS.hxx>
38 #include <XCAFPrs_DataMapIteratorOfDataMapOfStyleShape.hxx>
39 #include <Graphic3d_AspectFillArea3d.hxx>
40 #include <Aspect_InteriorStyle.hxx>
41 #include <Aspect_TypeOfLine.hxx>
42 #include <Prs3d_ShadingAspect.hxx>
43
44 #include <Prs3d_IsoAspect.hxx>
45 #include <XCAFPrs.hxx>
46
47 #include <TDataStd_Name.hxx>
48 #include <BRepBndLib.hxx>
49
50 #include <TPrsStd_AISPresentation.hxx>
51
52 #ifdef DEBUG
53 #include <DBRep.hxx>
54 #endif
55
56
57 //=======================================================================
58 //function : XCAFPrs_AISObject
59 //purpose  : 
60 //=======================================================================
61
62 XCAFPrs_AISObject::XCAFPrs_AISObject (const TDF_Label &lab) : AIS_Shape(TopoDS_Shape())
63 {
64   myLabel = lab;
65
66   TopoDS_Shape shape;
67   if ( XCAFDoc_ShapeTool::GetShape ( myLabel, shape ) && ! shape.IsNull() ) 
68     Set ( shape );
69 }
70
71 //=======================================================================
72 //function : SetColor
73 //purpose  : 
74 //=======================================================================
75
76 void XCAFPrs_AISObject::SetColor(const Quantity_Color &aCol)
77 {
78   AIS_Shape::SetColor(aCol);
79   LoadRecomputable(1);
80 }
81
82 //=======================================================================
83 //function : UnsetColor
84 //purpose  : 
85 //=======================================================================
86
87 void XCAFPrs_AISObject::UnsetColor()
88 {
89   if (HasColor())
90   {
91     AIS_Shape::UnsetColor();
92     LoadRecomputable(1);
93   }
94   else
95   {
96     myToRecomputeModes.Clear();
97   }
98 }
99
100 //=======================================================================
101 //function : SetMaterial
102 //purpose  : 
103 //=======================================================================
104
105 void XCAFPrs_AISObject::SetMaterial(const Graphic3d_NameOfMaterial aMat)
106 {
107   AIS_Shape::SetMaterial(aMat);
108   LoadRecomputable(1);
109 }
110
111 //=======================================================================
112 //function : SetMaterial
113 //purpose  : 
114 //=======================================================================
115
116 void XCAFPrs_AISObject::SetMaterial(const Graphic3d_MaterialAspect& aMat)
117 {
118   AIS_Shape::SetMaterial(aMat);
119   LoadRecomputable(1);
120 }
121
122 //=======================================================================
123 //function : UnsetMaterial
124 //purpose  : 
125 //=======================================================================
126
127 void XCAFPrs_AISObject::UnsetMaterial()
128 {
129   if (HasMaterial())
130   {
131     AIS_Shape::UnsetMaterial();
132     LoadRecomputable(1);
133   }
134   else
135   {
136     myToRecomputeModes.Clear();
137   }
138 }
139
140 //=======================================================================
141 //function : SetTransparency
142 //purpose  : 
143 //=======================================================================
144
145 void XCAFPrs_AISObject::SetTransparency(const Standard_Real AValue)
146 {
147   AIS_Shape::SetTransparency(AValue);
148   LoadRecomputable(1);
149 }
150
151 //=======================================================================
152 //function : UnsetTransparency
153 //purpose  : 
154 //=======================================================================
155
156 void XCAFPrs_AISObject::UnsetTransparency()
157 {
158   AIS_Shape::UnsetTransparency();
159   LoadRecomputable(1);
160 }
161
162 //=======================================================================
163 //function : AddStyledItem
164 //purpose  : 
165 //=======================================================================
166
167 void XCAFPrs_AISObject::AddStyledItem (const XCAFPrs_Style &style, 
168                                        const TopoDS_Shape &shape, 
169                                        const Handle(PrsMgr_PresentationManager3d)&, // aPresentationManager,
170                                        const Handle(Prs3d_Presentation)& aPrs,
171                                        const Standard_Integer aMode)
172
173   // remember current color settings
174   Handle(Graphic3d_AspectFillArea3d) a4bis = myDrawer->ShadingAspect()->Aspect();
175   Aspect_InteriorStyle aStyle;
176   Quantity_Color aIntColor, aEdgeColor;
177   Aspect_TypeOfLine aType;
178   Standard_Real aWidth;
179   a4bis->Values(aStyle,aIntColor,aEdgeColor,aType,aWidth);
180   Graphic3d_MaterialAspect FMAT = a4bis->FrontMaterial();
181   Quantity_Color aFColor = FMAT.Color();
182
183   Quantity_Color aColor1, aColor2;
184   Aspect_TypeOfLine aLine1, aLine2;
185   Standard_Real aWigth1, aWigth2;
186   Handle(Prs3d_LineAspect) waUFB = myDrawer->UnFreeBoundaryAspect();
187   waUFB->Aspect()->Values(aColor1,aLine1,aWigth1);
188   Handle(Prs3d_LineAspect) waFB = myDrawer->FreeBoundaryAspect();
189   waFB->Aspect()->Values(aColor2,aLine2,aWigth2);
190
191   Quantity_Color aColor;
192   Aspect_TypeOfLine aLine;
193   Standard_Real aWigth;
194   Handle(Prs3d_LineAspect) wa = myDrawer->WireAspect();
195   wa->Aspect()->Values(aColor,aLine,aWigth);
196
197   Quantity_Color aColorU, aColorV;
198   Aspect_TypeOfLine aLineU, aLineV;
199   Standard_Real aWigthU, aWigthV;
200   Handle(Prs3d_IsoAspect) UIso = myDrawer->UIsoAspect();
201   Handle(Prs3d_IsoAspect) VIso = myDrawer->VIsoAspect();
202   UIso->Aspect()->Values(aColorU,aLineU,aWigthU);
203   VIso->Aspect()->Values(aColorV,aLineV,aWigthV);
204   
205   // Set colors etc. for current shape according to style
206   if ( style.IsSetColorCurv() ) {
207     Quantity_Color Color = style.GetColorCurv();
208     waUFB->SetColor ( Color.Name() );
209     waFB->SetColor ( Color.Name() );
210     wa->SetColor ( Color.Name() );
211   }
212   if ( style.IsSetColorSurf() ) {
213     Quantity_Color Color = style.GetColorSurf();
214     a4bis->SetInteriorColor(Color);
215     FMAT.SetColor(Color);
216     a4bis->SetFrontMaterial(FMAT);
217     UIso->SetColor ( Color.Name() );
218     VIso->SetColor ( Color.Name() );
219   }
220
221   // force drawing isos on planes
222   Standard_Boolean drawIsosPln = myDrawer->IsoOnPlane();
223   myDrawer->SetIsoOnPlane (Standard_True);
224   
225   // add shape to presentation
226   switch (aMode) {
227   case 0:{
228     try { OCC_CATCH_SIGNALS  StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer); }
229     catch (Standard_Failure) { 
230 #ifdef DEB
231       cout << "AIS_Shape::Compute() failed: exception " <<
232               Standard_Failure::Caught()->DynamicType()->Name() << ": " <<
233               Standard_Failure::Caught()->GetMessageString() << endl;
234 #endif
235 //      cout << "a Shape should be incorrect: No Compute can be maked on it  "<< endl;     
236 // on calcule une presentation de la boite englobante
237 //      Compute(aPresentationManager,aPrs,2);
238     }
239     break;
240   }
241   case 1:
242     {
243       Standard_Real prevangle ;
244       Standard_Real newangle  ; 
245       Standard_Real prevcoeff ;
246       Standard_Real newcoeff  ; 
247       
248       if (OwnDeviationAngle(newangle,prevangle) ||
249           OwnDeviationCoefficient(newcoeff,prevcoeff))
250         if (Abs (newangle - prevangle) > Precision::Angular() ||
251             Abs (newcoeff - prevcoeff) > Precision::Confusion()  ) { 
252 #ifdef DEB
253           cout << "AIS_Shape : compute"<<endl;
254           cout << "newangl   : " << newangle << " # de " << "prevangl  : " << prevangle << " OU "<<endl;
255           cout << "newcoeff  : " << newcoeff << " # de " << "prevcoeff : " << prevcoeff << endl;
256 #endif
257           BRepTools::Clean(shape);
258         }
259     
260       //shading seulement a partir de face...
261       try {
262         OCC_CATCH_SIGNALS
263         if ((Standard_Integer) shape.ShapeType()>4)
264           StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer);
265         else {
266           myDrawer->SetShadingAspectGlobal(Standard_False);
267           if (IsInfinite()) 
268             StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer);
269           else
270             StdPrs_ShadedShape::Add(aPrs,shape,myDrawer);
271         }
272       }
273       catch (Standard_Failure) {
274 #ifdef DEB
275         cout << "AIS_Shape::Compute() in ShadingMode failed: exception " <<
276                 Standard_Failure::Caught()->DynamicType()->Name() << ": " <<
277                 Standard_Failure::Caught()->GetMessageString() << endl;
278 #endif
279         // last resort: try to display as wireframe
280         try {
281           OCC_CATCH_SIGNALS
282           StdPrs_WFShape::Add(aPrs,shape,myDrawer);
283         }
284         catch (Standard_Failure) {
285         }
286       }
287       break;
288     }
289   case 2:
290     {
291       // boite englobante
292       if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer);
293       else DisplayBox(aPrs,BoundingBox(),myDrawer);
294     }
295   }
296
297   // Restore initial settings
298   if ( style.IsSetColorCurv() ) {
299     waUFB->SetColor ( aColor1.Name() );
300     waFB->SetColor ( aColor2.Name() );
301     wa->SetColor ( aColor.Name() );
302   }
303   if ( style.IsSetColorSurf() ) {
304     a4bis->SetInteriorColor(aIntColor);
305     FMAT.SetColor(aFColor);
306     a4bis->SetFrontMaterial(FMAT);
307     UIso->SetColor ( aColorU );
308     VIso->SetColor ( aColorV );
309   }
310   myDrawer->SetIsoOnPlane (drawIsosPln);
311 }
312
313 //=======================================================================
314 //function : DisplayText
315 //purpose  : 
316 //=======================================================================
317
318 static void DisplayText (const TDF_Label& aLabel,
319                          const Handle(Prs3d_Presentation)& aPrs,
320                          const Handle(Prs3d_TextAspect)& anAspect,
321                          const TopLoc_Location& aLocation)
322 {
323   // first label itself
324   Handle (TDataStd_Name) aName;
325   if (aLabel.FindAttribute (TDataStd_Name::GetID(), aName)) {
326     TopoDS_Shape aShape;
327     if (XCAFDoc_ShapeTool::GetShape (aLabel, aShape)) {
328       // find the position to display as middle of the bounding box
329       aShape.Move (aLocation);
330       Bnd_Box aBox;
331       BRepBndLib::Add (aShape, aBox);
332       if ( ! aBox.IsVoid() ) 
333       {
334         Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
335         aBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
336         gp_Pnt aPnt (0.5 * (aXmin + aXmax), 0.5 * (aYmin + aYmax), 0.5 * (aZmin + aZmax));
337         Prs3d_Text::Draw( aPrs, anAspect, aName->Get(), aPnt);
338       }
339     }
340   }
341
342   TDF_LabelSequence seq;
343   
344   // attibutes of subshapes
345   if (XCAFDoc_ShapeTool::GetSubShapes (aLabel, seq)) {
346     Standard_Integer i = 1;
347     for (i = 1; i <= seq.Length(); i++) {
348       TDF_Label aL = seq.Value (i);
349       DisplayText (aL, aPrs, anAspect, aLocation); //suppose that subshapes do not contain locations
350     }
351   }
352   
353   // attibutes of components
354   seq.Clear();
355   if (XCAFDoc_ShapeTool::GetComponents (aLabel, seq)) {
356     Standard_Integer i = 1;
357     for (i = 1; i <= seq.Length(); i++) {
358       TDF_Label aL = seq.Value (i);
359       DisplayText (aL, aPrs, anAspect, aLocation);
360       TDF_Label aRefLabel;
361       
362       // attributes of referrences
363       TopLoc_Location aLoc = XCAFDoc_ShapeTool::GetLocation (aL);
364       if (XCAFDoc_ShapeTool::GetReferredShape (aL, aRefLabel)) {
365         DisplayText (aRefLabel, aPrs, anAspect, aLoc);
366       }
367     }
368   }
369 }
370                          
371 //=======================================================================
372 //function : Compute
373 //purpose  : 
374 //=======================================================================
375 // The Compute() method is copied from AIS_Shape::Compute and enhanced to 
376 // support different color settings for different subshapes of a single shape
377   
378 void XCAFPrs_AISObject::Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
379                                  const Handle(Prs3d_Presentation)& aPrs,
380                                  const Standard_Integer aMode)
381 {  
382 #ifdef DEB
383   //cout << "XCAFPrs_AISObject: Update called" << endl;
384 #endif
385   aPrs->Clear();
386
387   // abv: 06 Mar 00: to have good colors
388   Handle(TPrsStd_AISPresentation) prs = Handle(TPrsStd_AISPresentation)::DownCast ( GetOwner() );
389   if ( prs.IsNull() || !prs->HasOwnMaterial() )
390     AIS_Shape::SetMaterial ( Graphic3d_NOM_PLASTIC );
391
392   TopoDS_Shape shape;
393   if ( ! XCAFDoc_ShapeTool::GetShape ( myLabel, shape ) || shape.IsNull() ) return;
394
395   // wire,edge,vertex -> pas de HLR + priorite display superieure
396   Standard_Integer TheType = (Standard_Integer)shape.ShapeType();
397   if(TheType>4 && TheType<8) {
398     aPrs->SetVisual(Graphic3d_TOS_ALL);
399     aPrs->SetDisplayPriority(TheType+2);
400   }
401   // Shape vide -> Assemblage vide.
402   if (shape.ShapeType() == TopAbs_COMPOUND) {
403     TopoDS_Iterator anExplor (shape);
404     if (!anExplor.More()) {
405       return;
406     }
407   }
408   if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //pas de prise en compte lors du FITALL
409   
410   // collect information on colored subshapes
411   TopLoc_Location L;
412   XCAFPrs_DataMapOfShapeStyle settings;
413   XCAFPrs::CollectStyleSettings ( myLabel, L, settings );
414 #ifdef DEB
415   //cout << "Styles collected" << endl;
416 #endif
417
418   // dispatch (sub)shapes by their styles
419   XCAFPrs_DataMapOfStyleShape items;
420   XCAFPrs_Style DefStyle;
421   Quantity_Color White ( Quantity_NOC_WHITE );
422   DefStyle.SetColorSurf ( White );
423   DefStyle.SetColorCurv ( White );
424   XCAFPrs::DispatchStyles ( shape, settings, items, DefStyle );
425 #ifdef DEB
426   //cout << "Dispatch done" << endl;
427 #endif
428
429   // add subshapes to presentation (one shape per style)
430   XCAFPrs_DataMapIteratorOfDataMapOfStyleShape it ( items );
431 #ifdef DEB
432   //Standard_Integer i=1;
433 #endif
434   for ( ; it.More(); it.Next() ) {
435     XCAFPrs_Style s = it.Key();
436 #ifdef DEB
437     //cout << "Style " << i << ": [" << 
438     //  ( s.IsSetColorSurf() ? Quantity_Color::StringName ( s.GetColorSurf().Name() ) : "" ) << ", " <<
439     //  ( s.IsSetColorCurv() ? Quantity_Color::StringName ( s.GetColorCurv().Name() ) : "" ) << "]" <<
440         //" --> si_" << i << ( s.IsVisible() ? "" : " <invisible>" ) << endl;
441     //i++;
442 #endif
443     if (! s.IsVisible() ) continue;
444     AddStyledItem ( s, it.Value(), aPresentationManager, aPrs, aMode );
445   }
446   
447   if ( XCAFPrs::GetViewNameMode() ) {
448   // Displaying Name attributes
449 #ifdef DEB
450     //cout << "Now display name of shapes" << endl;
451 #endif
452     aPrs->SetDisplayPriority(10);
453     DisplayText (myLabel, aPrs, Attributes()->LengthAspect()->TextAspect(), TopLoc_Location());//no location
454   }
455 #ifdef DEB
456   //cout << "Compute finished" << endl;
457 #endif
458   
459   aPrs->ReCompute(); // for hidden line recomputation if necessary...
460 }