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