0027015: Sewing returns invalid shape if some faces are nearly plane cones
[occt.git] / src / AIS / AIS_TexturedShape.cxx
1 // Created on: 2001-07-02
2 // Created by: Mathias BOSSHARD
3 // Copyright (c) 2001-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <AIS_TexturedShape.hxx>
17
18 #include <AIS_GraphicTool.hxx>
19 #include <AIS_InteractiveContext.hxx>
20 #include <BRepTools.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <Graphic3d_AspectFillArea3d.hxx>
23 #include <Graphic3d_Group.hxx>
24 #include <Graphic3d_StructureManager.hxx>
25 #include <Graphic3d_Texture2Dmanual.hxx>
26 #include <Message.hxx>
27 #include <Message_Messenger.hxx>
28 #include <Precision.hxx>
29 #include <Prs3d_Drawer.hxx>
30 #include <Prs3d_Presentation.hxx>
31 #include <PrsMgr_ModedPresentation.hxx>
32 #include <Prs3d_Root.hxx>
33 #include <Prs3d_LineAspect.hxx>
34 #include <Prs3d_ShadingAspect.hxx>
35 #include <PrsMgr_PresentationManager3d.hxx>
36 #include <Standard_ErrorHandler.hxx>
37 #include <StdPrs_BndBox.hxx>
38 #include <StdPrs_ShadedShape.hxx>
39 #include <StdPrs_ToolTriangulatedShape.hxx>
40 #include <StdPrs_WFShape.hxx>
41 #include <TopExp_Explorer.hxx>
42
43
44 IMPLEMENT_STANDARD_RTTIEXT(AIS_TexturedShape,AIS_Shape)
45
46 //=======================================================================
47 //function : AIS_TexturedShape
48 //purpose  :
49 //=======================================================================
50 AIS_TexturedShape::AIS_TexturedShape (const TopoDS_Shape& theShape)
51 : AIS_Shape         (theShape),
52   myPredefTexture   (Graphic3d_NameOfTexture2D(0)),
53   myToMapTexture    (Standard_True),
54   myModulate        (Standard_True),
55   myUVOrigin        (0.0, 0.0),
56   myIsCustomOrigin  (Standard_True),
57   myUVRepeat        (1.0, 1.0),
58   myToRepeat        (Standard_True),
59   myUVScale         (1.0, 1.0),
60   myToScale         (Standard_True),
61   myToShowTriangles (Standard_False)
62 {
63 }
64
65 //=======================================================================
66 //function : SetTextureFileName
67 //purpose  :
68 //=======================================================================
69 void AIS_TexturedShape::SetTextureFileName (const TCollection_AsciiString& theTextureFileName)
70 {
71   myTexturePixMap.Nullify();
72
73   if (theTextureFileName.IsIntegerValue())
74   {
75     const Standard_Integer aValue = theTextureFileName.IntegerValue();
76     if (aValue < Graphic3d_Texture2D::NumberOfTextures()
77      && aValue >= 0)
78     {
79       myPredefTexture = Graphic3d_NameOfTexture2D (aValue);
80     }
81     else
82     {
83       Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: texture with ID ") + theTextureFileName
84                                        + " is undefined! Texture 0 will be used instead.", Message_Fail);
85       myPredefTexture = Graphic3d_NameOfTexture2D (0);
86     }
87     myTextureFile = "";
88   }
89   else
90   {
91     myTextureFile   = theTextureFileName;
92     myPredefTexture = Graphic3d_NOT_2D_UNKNOWN;
93   }
94 }
95
96 //=======================================================================
97 //function : SetTexturePixMap
98 //purpose  :
99 //=======================================================================
100 void AIS_TexturedShape::SetTexturePixMap (const Handle(Image_PixMap)& theTexturePixMap)
101 {
102   myTextureFile = "";
103   myPredefTexture = Graphic3d_NOT_2D_UNKNOWN;
104   myTexturePixMap = theTexturePixMap;
105 }
106
107 //=======================================================================
108 //function : SetTextureRepeat
109 //purpose  :
110 //=======================================================================
111
112 void AIS_TexturedShape::SetTextureRepeat (const Standard_Boolean theToRepeat,
113                                           const Standard_Real    theURepeat,
114                                           const Standard_Real    theVRepeat)
115 {
116   myToRepeat = theToRepeat;
117   myUVRepeat.SetCoord (theURepeat, theVRepeat);
118 }
119
120 //=======================================================================
121 //function : SetTextureMapOn
122 //purpose  :
123 //=======================================================================
124
125 void AIS_TexturedShape::SetTextureMapOn()
126 {
127   myToMapTexture = Standard_True;
128 }
129
130 //=======================================================================
131 //function : SetTextureMapOff
132 //purpose  :
133 //=======================================================================
134
135 void AIS_TexturedShape::SetTextureMapOff()
136 {
137   myToMapTexture = Standard_False;
138 }
139
140 //=======================================================================
141 //function : SetTextureOrigin
142 //purpose  :
143 //=======================================================================
144
145 void AIS_TexturedShape::SetTextureOrigin (const Standard_Boolean theToSetTextureOrigin,
146                                           const Standard_Real    theUOrigin,
147                                           const Standard_Real    theVOrigin)
148 {
149   myIsCustomOrigin = theToSetTextureOrigin;
150   myUVOrigin.SetCoord (theUOrigin, theVOrigin);
151 }
152
153 //=======================================================================
154 //function : SetTextureScale
155 //purpose  :
156 //=======================================================================
157
158 void AIS_TexturedShape::SetTextureScale (const Standard_Boolean theToSetTextureScale,
159                                          const Standard_Real    theScaleU,
160                                          const Standard_Real    theScaleV)
161 {
162   myToScale = theToSetTextureScale;
163   myUVScale.SetCoord (theScaleU, theScaleV);
164 }
165
166 //=======================================================================
167 //function : ShowTriangles
168 //purpose  :
169 //=======================================================================
170
171 void AIS_TexturedShape::ShowTriangles (const Standard_Boolean theToShowTriangles)
172 {
173   myToShowTriangles = theToShowTriangles;
174 }
175
176 //=======================================================================
177 //function : EnableTextureModulate
178 //purpose  :
179 //=======================================================================
180
181 void AIS_TexturedShape::EnableTextureModulate()
182 {
183   myModulate = Standard_True;
184 }
185
186 //=======================================================================
187 //function : DisableTextureModulate
188 //purpose  :
189 //=======================================================================
190
191 void AIS_TexturedShape::DisableTextureModulate()
192 {
193   myModulate = Standard_False;
194 }
195
196 //=======================================================================
197 //function : SetColor
198 //purpose  :
199 //=======================================================================
200
201 void AIS_TexturedShape::SetColor (const Quantity_Color& theColor)
202 {
203   AIS_Shape::SetColor (theColor);
204
205   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
206   {
207     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
208
209     if (aPrsModed.Mode() != 3)
210       continue;
211
212     updateAttributes (aPrsModed.Presentation()->Presentation());
213   }
214 }
215
216 //=======================================================================
217 //function : UnsetColor
218 //purpose  :
219 //=======================================================================
220
221 void AIS_TexturedShape::UnsetColor()
222 {
223   AIS_Shape::UnsetColor();
224
225   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
226   {
227     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
228
229     if (aPrsModed.Mode() != 3)
230       continue;
231     
232     Handle(Prs3d_Presentation) aPrs = aPrsModed.Presentation()->Presentation();
233     Handle(Graphic3d_Group)    aGroup = Prs3d_Root::CurrentGroup (aPrs);
234
235     Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect();
236     Handle(Graphic3d_AspectLine3d)     aLineAsp  = myDrawer->Link()->LineAspect()->Aspect();
237     Quantity_Color aColor;
238     AIS_GraphicTool::GetInteriorColor (myDrawer->Link(), aColor);
239     anAreaAsp->SetInteriorColor (aColor);
240     aPrs->SetPrimitivesAspect (anAreaAsp);
241     aPrs->SetPrimitivesAspect (aLineAsp);
242     // Check if aspect of given type is set for the group, 
243     // because setting aspect for group with no already set aspect
244     // can lead to loss of presentation data
245     if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
246     {
247       aGroup->SetGroupPrimitivesAspect (anAreaAsp);
248     }
249     if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
250     {
251       aGroup->SetGroupPrimitivesAspect (aLineAsp);
252     }
253
254     updateAttributes (aPrs);
255   }
256 }
257
258 //=======================================================================
259 //function : SetMaterial
260 //purpose  : 
261 //=======================================================================
262
263 void AIS_TexturedShape::SetMaterial (const Graphic3d_MaterialAspect& theMat)
264 {
265   AIS_Shape::SetMaterial (theMat);
266
267   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
268   {
269     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
270     
271     if (aPrsModed.Mode() != 3)
272       continue;
273     
274     updateAttributes (aPrsModed.Presentation()->Presentation());
275   }
276 }
277
278 //=======================================================================
279 //function : UnsetMaterial
280 //purpose  : 
281 //=======================================================================
282 void AIS_TexturedShape::UnsetMaterial()
283 {
284   AIS_Shape::UnsetMaterial();
285
286   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
287   {
288     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
289
290     if (aPrsModed.Mode() != 3)
291       continue;
292
293     updateAttributes (aPrsModed.Presentation()->Presentation());
294   }
295 }
296
297 //=======================================================================
298 //function : UpdateAttributes
299 //purpose  :
300 //=======================================================================
301
302 void AIS_TexturedShape::UpdateAttributes()
303 {
304   updateAttributes (Presentation());
305 }
306
307 //=======================================================================
308 //function : updateAttributes
309 //purpose  :
310 //=======================================================================
311
312 void AIS_TexturedShape::updateAttributes (const Handle(Prs3d_Presentation)& thePrs)
313 {
314   myAspect = new Graphic3d_AspectFillArea3d (*myDrawer->ShadingAspect()->Aspect());
315   if (HasPolygonOffsets())
316   {
317     Standard_Integer aMode;
318     Standard_ShortReal aFactor, aUnits;
319     PolygonOffsets (aMode, aFactor, aUnits);
320     myAspect->SetPolygonOffsets (aMode, aFactor, aUnits);
321   }
322
323   Standard_Boolean hasTexture = Standard_False;
324   if (myToMapTexture)
325   {
326     TCollection_AsciiString aTextureDesc;
327     if (!myTexturePixMap.IsNull())
328     {
329       myTexture = new Graphic3d_Texture2Dmanual (myTexturePixMap);
330       aTextureDesc = " (custom image)";
331     }
332     else if (myPredefTexture != Graphic3d_NOT_2D_UNKNOWN)
333     {
334       myTexture = new Graphic3d_Texture2Dmanual (myPredefTexture);
335       aTextureDesc = TCollection_AsciiString(" (predefined texture ") + myTexture->GetId() + ")";
336     }
337     else
338     {
339       myTexture = new Graphic3d_Texture2Dmanual (myTextureFile.ToCString());
340       aTextureDesc = TCollection_AsciiString(" (") + myTextureFile + ")";
341     }
342
343     if (myModulate)
344     {
345       myTexture->EnableModulate();
346     }
347     else
348     {
349       myTexture->DisableModulate();
350     }
351
352     if (myTexture->IsDone())
353     {
354       hasTexture = Standard_True;
355     }
356     else
357     {
358       Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: texture can not be loaded ") + aTextureDesc, Message_Fail);
359     }
360   }
361
362   myAspect->SetTextureMap (myTexture);
363   if (hasTexture)
364   {
365     myAspect->SetTextureMapOn();
366   }
367   else
368   {
369     myAspect->SetTextureMapOff();
370   }
371
372   if (myToShowTriangles)
373   {
374     myAspect->SetEdgeOn();
375   }
376   else
377   {
378     myAspect->SetEdgeOff();
379   }
380
381   // Go through all groups to change fill aspect for all primitives
382   for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (thePrs->Groups()); aGroupIt.More(); aGroupIt.Next())
383   {
384     const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
385     if (!aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
386     {
387       continue;
388     }
389
390     if (aGroup->IsClosed())
391     {
392       myAspect->SuppressBackFace();
393     }
394     else
395     {
396       myAspect->AllowBackFace();
397     }
398
399     aGroup->SetGroupPrimitivesAspect (myAspect);
400   }
401 }
402
403 //=======================================================================
404 //function : Compute
405 //purpose  :
406 //=======================================================================
407
408 void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
409                                  const Handle(Prs3d_Presentation)&           thePrs,
410                                  const Standard_Integer                      theMode)
411 {
412   thePrs->Clear();
413
414   if (myshape.IsNull())
415   {
416     return;
417   }
418
419   if (myshape.ShapeType() > TopAbs_FACE && myshape.ShapeType() < TopAbs_SHAPE)
420   {
421     thePrs->SetVisual (Graphic3d_TOS_ALL);
422     thePrs->SetDisplayPriority (myshape.ShapeType() + 2);
423   }
424
425   if (myshape.ShapeType() == TopAbs_COMPOUND)
426   {
427     TopExp_Explorer anExplor (myshape, TopAbs_VERTEX);
428     if (!anExplor.More())
429     {
430       return;
431     }
432   }
433
434   if (IsInfinite())
435   {
436     thePrs->SetInfiniteState (Standard_True);
437   }
438
439   switch (theMode)
440   {
441     case AIS_WireFrame:
442     {
443       StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
444       break;
445     }
446     case AIS_Shaded:
447     case 3: // texture mapping on triangulation
448     {
449       if (myDrawer->IsAutoTriangulation())
450       {
451         Standard_Real aPrevAngle;
452         Standard_Real aNewAngle;
453         Standard_Real aPrevCoeff;
454         Standard_Real aNewCoeff;
455
456         Standard_Boolean isOwnDeviationAngle       = OwnDeviationAngle (aNewAngle, aPrevAngle);
457         Standard_Boolean isOwnDeviationCoefficient = OwnDeviationCoefficient (aNewCoeff,aPrevCoeff);
458         if (((Abs (aNewAngle - aPrevAngle) > Precision::Angular()) && isOwnDeviationAngle) ||
459             ((Abs (aNewCoeff - aPrevCoeff) > Precision::Confusion()) && isOwnDeviationCoefficient))
460         {
461           BRepTools::Clean (myshape);
462         }
463       }
464
465       if (myshape.ShapeType() > TopAbs_FACE)
466       {
467         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
468         break;
469       }
470
471       myDrawer->SetShadingAspectGlobal (Standard_False);
472       if (IsInfinite())
473       {
474         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
475         break;
476       }
477       try
478       {
479         OCC_CATCH_SIGNALS
480         if (theMode == AIS_Shaded)
481         {
482           StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer);
483         }
484         else
485         {
486           StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer,
487                                    Standard_True,
488                                    myIsCustomOrigin ? myUVOrigin : gp_Pnt2d (0.0, 0.0),
489                                    myUVRepeat,
490                                    myToScale        ? myUVScale  : gp_Pnt2d (1.0, 1.0));
491           updateAttributes (thePrs);
492         }
493       }
494       catch (Standard_Failure)
495       {
496 #ifdef OCCT_DEBUG
497         std::cout << "AIS_TexturedShape::Compute() in ShadingMode failed \n";
498 #endif
499         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
500       }
501       break;
502     }
503     case 2: // Bounding box
504     {
505       if (IsInfinite())
506       {
507         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
508       }
509       else
510       {
511         StdPrs_BndBox::Add (thePrs, BoundingBox(), myDrawer);
512       }
513       break;
514     }
515   }
516 }