dd461380914d18e4f8efa3019b8a18b909f7b880
[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 : DisplayBox
164 //purpose  : 
165 //=======================================================================
166
167 static void DisplayBox(const Handle(Prs3d_Presentation)& aPrs,
168                        const Bnd_Box& B,
169                        const Handle(Prs3d_Drawer)& aDrawer)
170 {
171   Standard_Real X[2],Y[2],Z[2];
172   Standard_Integer Indx [16] ;
173   if ( B.IsVoid() )
174     return;
175   
176 #ifdef BUC60577
177   Indx [0]=1;Indx [1]=2;Indx [2]=4;Indx [3]=3;
178   Indx [4]=5;Indx [5]=6;Indx [6]=8;Indx [7]=7;
179   Indx [8]=1;Indx [9]=3;Indx [10]=7;Indx [11]=5;
180   Indx [12]=2;Indx [13]=4;Indx [14]=8;Indx [15]=6;
181   B.Get(X[0], Y[0], Z[0], X[1], Y[1], Z[1]);
182 #else
183   Indx [0]=1;Indx [1]=2;Indx [2]=3;Indx [3]=4;Indx [4]=5;Indx [5]=6;Indx [6]=7;
184   Indx [7]=8;Indx [8]=1;Indx [9]=2;Indx [10]=6;Indx [10]=5;Indx [10]=3;
185   Indx [10]=4;Indx [10]=8;Indx [10]=7;
186   B.Get(X[1], Y[1], Z[1], X[2], Y[2], Z[2]);
187 #endif
188
189   Graphic3d_Array1OfVertex V(1,8);
190   Standard_Integer Rank(0);
191   for(Standard_Integer k=0;k<=1;k++)
192     for(Standard_Integer j=0;j<=1;j++)
193       for(Standard_Integer i=0;i<=1;i++)
194         V(++Rank) = Graphic3d_Vertex(X[i],Y[j],Z[k]);
195   
196   
197   Handle(Graphic3d_Group) G = Prs3d_Root::CurrentGroup(aPrs);
198   Quantity_Color Q;
199   Aspect_TypeOfLine A;
200   Standard_Real W;
201   aDrawer->LineAspect()->Aspect()->Values(Q,A,W);
202   
203
204   G->SetGroupPrimitivesAspect(new Graphic3d_AspectLine3d(Q,Aspect_TOL_DOTDASH,W));
205   
206   G->BeginPrimitives();Standard_Integer I,J;
207   Graphic3d_Array1OfVertex VVV (1,5);
208   for(I=1;I<=4;I++){
209     for(J=1;J<=4;J++){
210       VVV.SetValue(J,V(Indx[J+4*I-5]));
211     }
212     VVV.SetValue(5,VVV(1));
213     G->Polyline(VVV);
214   }
215   G->EndPrimitives();
216 }
217
218 //=======================================================================
219 //function : AddStyledItem
220 //purpose  : 
221 //=======================================================================
222
223 void XCAFPrs_AISObject::AddStyledItem (const XCAFPrs_Style &style, 
224                                        const TopoDS_Shape &shape, 
225                                        const Handle(PrsMgr_PresentationManager3d)&, // aPresentationManager,
226                                        const Handle(Prs3d_Presentation)& aPrs,
227                                        const Standard_Integer aMode)
228
229   // remember current color settings
230   Handle(Graphic3d_AspectFillArea3d) a4bis = myDrawer->ShadingAspect()->Aspect();
231   Aspect_InteriorStyle aStyle;
232   Quantity_Color aIntColor, aEdgeColor;
233   Aspect_TypeOfLine aType;
234   Standard_Real aWidth;
235   a4bis->Values(aStyle,aIntColor,aEdgeColor,aType,aWidth);
236   Graphic3d_MaterialAspect FMAT = a4bis->FrontMaterial();
237   Quantity_Color aFColor = FMAT.Color();
238
239   Quantity_Color aColor1, aColor2;
240   Aspect_TypeOfLine aLine1, aLine2;
241   Standard_Real aWigth1, aWigth2;
242   Handle(Prs3d_LineAspect) waUFB = myDrawer->UnFreeBoundaryAspect();
243   waUFB->Aspect()->Values(aColor1,aLine1,aWigth1);
244   Handle(Prs3d_LineAspect) waFB = myDrawer->FreeBoundaryAspect();
245   waFB->Aspect()->Values(aColor2,aLine2,aWigth2);
246
247   Quantity_Color aColor;
248   Aspect_TypeOfLine aLine;
249   Standard_Real aWigth;
250   Handle(Prs3d_LineAspect) wa = myDrawer->WireAspect();
251   wa->Aspect()->Values(aColor,aLine,aWigth);
252
253   Quantity_Color aColorU, aColorV;
254   Aspect_TypeOfLine aLineU, aLineV;
255   Standard_Real aWigthU, aWigthV;
256   Handle(Prs3d_IsoAspect) UIso = myDrawer->UIsoAspect();
257   Handle(Prs3d_IsoAspect) VIso = myDrawer->VIsoAspect();
258   UIso->Aspect()->Values(aColorU,aLineU,aWigthU);
259   VIso->Aspect()->Values(aColorV,aLineV,aWigthV);
260   
261   // Set colors etc. for current shape according to style
262   if ( style.IsSetColorCurv() ) {
263     Quantity_Color Color = style.GetColorCurv();
264     waUFB->SetColor ( Color.Name() );
265     waFB->SetColor ( Color.Name() );
266     wa->SetColor ( Color.Name() );
267   }
268   if ( style.IsSetColorSurf() ) {
269     Quantity_Color Color = style.GetColorSurf();
270     a4bis->SetInteriorColor(Color);
271     FMAT.SetColor(Color);
272     a4bis->SetFrontMaterial(FMAT);
273     UIso->SetColor ( Color.Name() );
274     VIso->SetColor ( Color.Name() );
275   }
276
277   // force drawing isos on planes
278   Standard_Boolean drawIsosPln = myDrawer->IsoOnPlane();
279   myDrawer->SetIsoOnPlane (Standard_True);
280   
281   // add shape to presentation
282   switch (aMode) {
283   case 0:{
284     try { OCC_CATCH_SIGNALS  StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer); }
285     catch (Standard_Failure) { 
286 #ifdef DEB
287       cout << "AIS_Shape::Compute() failed: exception " <<
288               Standard_Failure::Caught()->DynamicType()->Name() << ": " <<
289               Standard_Failure::Caught()->GetMessageString() << endl;
290 #endif
291 //      cout << "a Shape should be incorrect: No Compute can be maked on it  "<< endl;     
292 // on calcule une presentation de la boite englobante
293 //      Compute(aPresentationManager,aPrs,2);
294     }
295     break;
296   }
297   case 1:
298     {
299       Standard_Real prevangle ;
300       Standard_Real newangle  ; 
301       Standard_Real prevcoeff ;
302       Standard_Real newcoeff  ; 
303       
304       if (OwnDeviationAngle(newangle,prevangle) ||
305           OwnDeviationCoefficient(newcoeff,prevcoeff))
306         if (Abs (newangle - prevangle) > Precision::Angular() ||
307             Abs (newcoeff - prevcoeff) > Precision::Confusion()  ) { 
308 #ifdef DEB
309           cout << "AIS_Shape : compute"<<endl;
310           cout << "newangl   : " << newangle << " # de " << "prevangl  : " << prevangle << " OU "<<endl;
311           cout << "newcoeff  : " << newcoeff << " # de " << "prevcoeff : " << prevcoeff << endl;
312 #endif
313           BRepTools::Clean(shape);
314         }
315     
316       //shading seulement a partir de face...
317       try {
318         OCC_CATCH_SIGNALS
319         if ((Standard_Integer) shape.ShapeType()>4)
320           StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer);
321         else {
322           myDrawer->SetShadingAspectGlobal(Standard_False);
323           if (IsInfinite()) 
324             StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer);
325           else
326             StdPrs_ShadedShape::Add(aPrs,shape,myDrawer);
327         }
328       }
329       catch (Standard_Failure) {
330 #ifdef DEB
331         cout << "AIS_Shape::Compute() in ShadingMode failed: exception " <<
332                 Standard_Failure::Caught()->DynamicType()->Name() << ": " <<
333                 Standard_Failure::Caught()->GetMessageString() << endl;
334 #endif
335         // last resort: try to display as wireframe
336         try {
337           OCC_CATCH_SIGNALS
338           StdPrs_WFShape::Add(aPrs,shape,myDrawer);
339         }
340         catch (Standard_Failure) {
341         }
342       }
343       break;
344     }
345   case 2:
346     {
347       // boite englobante
348       if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer);
349       else DisplayBox(aPrs,BoundingBox(),myDrawer);
350     }
351   }
352
353   // Restore initial settings
354   if ( style.IsSetColorCurv() ) {
355     waUFB->SetColor ( aColor1.Name() );
356     waFB->SetColor ( aColor2.Name() );
357     wa->SetColor ( aColor.Name() );
358   }
359   if ( style.IsSetColorSurf() ) {
360     a4bis->SetInteriorColor(aIntColor);
361     FMAT.SetColor(aFColor);
362     a4bis->SetFrontMaterial(FMAT);
363     UIso->SetColor ( aColorU );
364     VIso->SetColor ( aColorV );
365   }
366   myDrawer->SetIsoOnPlane (drawIsosPln);
367 }
368
369 //=======================================================================
370 //function : DisplayText
371 //purpose  : 
372 //=======================================================================
373
374 static void DisplayText (const TDF_Label& aLabel,
375                          const Handle(Prs3d_Presentation)& aPrs,
376                          const Handle(Prs3d_TextAspect)& anAspect,
377                          const TopLoc_Location& aLocation)
378 {
379   // first label itself
380   Handle (TDataStd_Name) aName;
381   if (aLabel.FindAttribute (TDataStd_Name::GetID(), aName)) {
382     TopoDS_Shape aShape;
383     if (XCAFDoc_ShapeTool::GetShape (aLabel, aShape)) {
384       // find the position to display as middle of the bounding box
385       aShape.Move (aLocation);
386       Bnd_Box aBox;
387       BRepBndLib::Add (aShape, aBox);
388       if ( ! aBox.IsVoid() ) 
389       {
390         Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
391         aBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
392         gp_Pnt aPnt (0.5 * (aXmin + aXmax), 0.5 * (aYmin + aYmax), 0.5 * (aZmin + aZmax));
393         Prs3d_Text::Draw( aPrs, anAspect, aName->Get(), aPnt);
394       }
395     }
396   }
397
398   TDF_LabelSequence seq;
399   
400   // attibutes of subshapes
401   if (XCAFDoc_ShapeTool::GetSubShapes (aLabel, seq)) {
402     Standard_Integer i = 1;
403     for (i = 1; i <= seq.Length(); i++) {
404       TDF_Label aL = seq.Value (i);
405       DisplayText (aL, aPrs, anAspect, aLocation); //suppose that subshapes do not contain locations
406     }
407   }
408   
409   // attibutes of components
410   seq.Clear();
411   if (XCAFDoc_ShapeTool::GetComponents (aLabel, seq)) {
412     Standard_Integer i = 1;
413     for (i = 1; i <= seq.Length(); i++) {
414       TDF_Label aL = seq.Value (i);
415       DisplayText (aL, aPrs, anAspect, aLocation);
416       TDF_Label aRefLabel;
417       
418       // attributes of referrences
419       TopLoc_Location aLoc = XCAFDoc_ShapeTool::GetLocation (aL);
420       if (XCAFDoc_ShapeTool::GetReferredShape (aL, aRefLabel)) {
421         DisplayText (aRefLabel, aPrs, anAspect, aLoc);
422       }
423     }
424   }
425 }
426                          
427 //=======================================================================
428 //function : Compute
429 //purpose  : 
430 //=======================================================================
431 // The Compute() method is copied from AIS_Shape::Compute and enhanced to 
432 // support different color settings for different subshapes of a single shape
433   
434 void XCAFPrs_AISObject::Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
435                                  const Handle(Prs3d_Presentation)& aPrs,
436                                  const Standard_Integer aMode)
437 {  
438 #ifdef DEB
439   //cout << "XCAFPrs_AISObject: Update called" << endl;
440 #endif
441   aPrs->Clear();
442
443   // abv: 06 Mar 00: to have good colors
444   Handle(TPrsStd_AISPresentation) prs = Handle(TPrsStd_AISPresentation)::DownCast ( GetOwner() );
445   if ( prs.IsNull() || !prs->HasOwnMaterial() )
446     AIS_Shape::SetMaterial ( Graphic3d_NOM_PLASTIC );
447
448   TopoDS_Shape shape;
449   if ( ! XCAFDoc_ShapeTool::GetShape ( myLabel, shape ) || shape.IsNull() ) return;
450
451   // wire,edge,vertex -> pas de HLR + priorite display superieure
452   Standard_Integer TheType = (Standard_Integer)shape.ShapeType();
453   if(TheType>4 && TheType<8) {
454     aPrs->SetVisual(Graphic3d_TOS_ALL);
455     aPrs->SetDisplayPriority(TheType+2);
456   }
457   // Shape vide -> Assemblage vide.
458   if (shape.ShapeType() == TopAbs_COMPOUND) {
459     TopoDS_Iterator anExplor (shape);
460     if (!anExplor.More()) {
461       return;
462     }
463   }
464   if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //pas de prise en compte lors du FITALL
465   
466   // collect information on colored subshapes
467   TopLoc_Location L;
468   XCAFPrs_DataMapOfShapeStyle settings;
469   XCAFPrs::CollectStyleSettings ( myLabel, L, settings );
470 #ifdef DEB
471   //cout << "Styles collected" << endl;
472 #endif
473
474   // dispatch (sub)shapes by their styles
475   XCAFPrs_DataMapOfStyleShape items;
476   XCAFPrs_Style DefStyle;
477   Quantity_Color White ( Quantity_NOC_WHITE );
478   DefStyle.SetColorSurf ( White );
479   DefStyle.SetColorCurv ( White );
480   XCAFPrs::DispatchStyles ( shape, settings, items, DefStyle );
481 #ifdef DEB
482   //cout << "Dispatch done" << endl;
483 #endif
484
485   // add subshapes to presentation (one shape per style)
486   XCAFPrs_DataMapIteratorOfDataMapOfStyleShape it ( items );
487 #ifdef DEB
488   //Standard_Integer i=1;
489 #endif
490   for ( ; it.More(); it.Next() ) {
491     XCAFPrs_Style s = it.Key();
492 #ifdef DEB
493     //cout << "Style " << i << ": [" << 
494     //  ( s.IsSetColorSurf() ? Quantity_Color::StringName ( s.GetColorSurf().Name() ) : "" ) << ", " <<
495     //  ( s.IsSetColorCurv() ? Quantity_Color::StringName ( s.GetColorCurv().Name() ) : "" ) << "]" <<
496         //" --> si_" << i << ( s.IsVisible() ? "" : " <invisible>" ) << endl;
497     //i++;
498 #endif
499     if (! s.IsVisible() ) continue;
500     AddStyledItem ( s, it.Value(), aPresentationManager, aPrs, aMode );
501   }
502   
503   if ( XCAFPrs::GetViewNameMode() ) {
504   // Displaying Name attributes
505 #ifdef DEB
506     //cout << "Now display name of shapes" << endl;
507 #endif
508     aPrs->SetDisplayPriority(10);
509     DisplayText (myLabel, aPrs, Attributes()->LengthAspect()->TextAspect(), TopLoc_Location());//no location
510   }
511 #ifdef DEB
512   //cout << "Compute finished" << endl;
513 #endif
514   
515   aPrs->ReCompute(); // for hidden line recomputation if necessary...
516 }