0029367: Visualization - simplify interface of V3d_View and V3d_Viewer
[occt.git] / samples / mfc / standard / 04_Viewer3d / src / TexturesExt_Presentation.cpp
1 // TexturesExt_Presentation.cpp: implementation of the TexturesExt_Presentation class.
2 // Creation of textural presentation of shape
3 //////////////////////////////////////////////////////////////////////
4
5 #include "stdafx.h"
6 #include "TexturesExt_Presentation.h"
7 #include "Viewer3dApp.h"
8
9 #include <TopExp.hxx>
10 #include <TopTools_IndexedMapOfShape.hxx>
11 #include <BRepBuilderAPI_MakeFace.hxx>
12 #include <AIS_Shape.hxx>
13 #include <BRepTools.hxx>
14 #include <Graphic3d_Texture2Dmanual.hxx>
15 #include <BRep_Tool.hxx>
16 #include <TopoDS.hxx>
17 #include <BRepBuilderAPI_Transform.hxx>
18 #include <BRep_Builder.hxx>
19 #include <BRepTools.hxx>
20 #include <Geom_Surface.hxx>
21 #include <TopoDS_Face.hxx>
22 #include <V3d_DirectionalLight.hxx>
23
24 #define DISP(OBJ) getAISContext()->Display((OBJ), Standard_False)
25
26 // Initialization of global variable with an instance of this class
27 OCCDemo_Presentation* OCCDemo_Presentation::Current = new TexturesExt_Presentation;
28
29 // Initialization of array of samples
30 const TexturesExt_Presentation::PSampleFuncType TexturesExt_Presentation::SampleFuncs[] =
31 {
32   &TexturesExt_Presentation::sampleBottle,
33   &TexturesExt_Presentation::sampleTerrain,
34   &TexturesExt_Presentation::sampleKitchen
35 };
36
37 #define EOL "\r\n"
38
39 #define ZVIEW_SIZE 100
40
41 //////////////////////////////////////////////////////////////////////
42 // Construction/Destruction
43 //////////////////////////////////////////////////////////////////////
44
45 TexturesExt_Presentation::TexturesExt_Presentation()
46 {
47   myNbSamples = sizeof(SampleFuncs)/sizeof(PSampleFuncType);
48   setName ("Textured Shapes");
49 }
50
51 //////////////////////////////////////////////////////////////////////
52 // Sample execution
53 //////////////////////////////////////////////////////////////////////
54
55 void TexturesExt_Presentation::DoSample()
56 {
57         ((CViewer3dApp*) AfxGetApp())->SetSampleName (L"Viewer3d");
58         ((CViewer3dApp*) AfxGetApp())->SetSamplePath (L"..\\..\\04_Viewer3d");
59         getAISContext()->EraseAll (Standard_True);
60         if (myIndex >=0 && myIndex < myNbSamples)
61         {
62           // turn lights on for terrain sample
63           lightsOnOff(myIndex==1);
64           (this->*SampleFuncs[myIndex])();
65         }
66 }
67
68 void TexturesExt_Presentation::Init()
69 {
70   // initialize v3d_view so it displays TexturesExt well
71   Handle(V3d_View) aView = getViewer()->ActiveViews().First();
72   aView->SetSize(ZVIEW_SIZE);
73
74 //  getDocument()->UpdateResultMessageDlg("Textured Shape", 
75   TCollection_AsciiString Message ("Textured Shape", 
76     "  TopoDS_Shape aShape;" EOL
77     "" EOL
78     "  // initialize aShape" EOL
79     "  // aShape = ..." EOL
80     "" EOL
81     "  // create a textured presentation object for aShape" EOL
82     "  Handle(AIS_Shape) aTShape = new AIS_Shape(aShape);" EOL
83     "" EOL
84     "  TCollection_AsciiString aTFileName;" EOL
85     "" EOL
86     "  // initialize aTFileName with an existing texture file name" EOL
87     "  // (gif, bmp, xwd, rgb, and other formats are supported)" EOL
88     "  // OR with an integer value string (max = Graphic3d_Texture2D::NumberOfTexturesExt())" EOL
89     "  // which will indicate use of predefined texture of this number" EOL
90     "  // aTFileName = ..." EOL
91     "" EOL
92     "  aTShape->Attributes()->SetShadingAspect (new Prs3d_ShadingAspect());" EOL
93     "  Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual (aTFileName);" EOL
94     "  aTShape->Attributes()->ShadingAspect()->Aspect()->SetTextureMap (aTexture);" EOL
95     "  aTShape->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn();" EOL);
96 //      CString text(Message.ToCString());
97         getDocument()->ClearDialog();
98         getDocument()->SetDialogTitle("Change face color");
99         getDocument()->AddTextInDialog(Message);
100 }
101
102 //////////////////////////////////////////////////////////////////////
103 // Sample functions
104 //////////////////////////////////////////////////////////////////////
105 //================================================================
106 // Function : TexturesExt_Presentation::Texturize
107 // display an AIS_Shape based on a given shape with texture with given filename
108 // filename can also be an integer value ("2", "5", etc.), in this case
109 // a predefined texture from Graphic3d_NameOfTexture2D with number = this value
110 // is loaded.
111 //================================================================
112 Handle(AIS_Shape) TexturesExt_Presentation::Texturize(const TopoDS_Shape& aShape,
113                                                         TCollection_AsciiString aTFileName,
114                                                         Standard_Real toScaleU,
115                                                         Standard_Real toScaleV,
116                                                         Standard_Real toRepeatU,
117                                                         Standard_Real toRepeatV,
118                                                         Standard_Real originU,
119                                                         Standard_Real originV)
120 {
121   // create a textured presentation object for aShape
122   Handle(AIS_Shape) aTShape = new AIS_Shape(aShape);
123   TCollection_AsciiString TFileName;
124   // load texture from file if it is not an integer value
125   // integer value indicates a number of texture in predefined TexturesExt enumeration
126   CString anOCCTDataPathValue;
127   anOCCTDataPathValue.GetEnvironmentVariable(L"CSF_OCCTDataPath");
128   CString initfile = (anOCCTDataPathValue + L"\\images\\");
129   if (!aTFileName.IsIntegerValue())
130   {
131     initfile += aTFileName.ToCString();
132   }
133
134   if (!aTShape->Attributes()->HasOwnShadingAspect())
135   {
136     aTShape->Attributes()->SetShadingAspect (new Prs3d_ShadingAspect());
137   }
138   aTShape->Attributes()->ShadingAspect()->Aspect()->SetTextureMap (new Graphic3d_Texture2Dmanual (TCollection_AsciiString ((const wchar_t* )initfile)));
139   aTShape->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn();
140
141   // do other initialization of AIS_Shape
142   aTShape->SetTextureScaleUV (gp_Pnt2d ( toScaleU, toScaleV));
143   aTShape->SetTextureRepeatUV(gp_Pnt2d (toRepeatU, toRepeatV));
144   aTShape->SetTextureOriginUV(gp_Pnt2d (  originU, originV));
145
146   aTShape->SetDisplayMode(AIS_Shaded);
147
148   return aTShape;
149 }
150
151
152 //================================================================
153 // Function : TexturesExt_Presentation::loadShape
154 // loads a shape from a given brep file from data dir into a given TopoDS_Shape object
155 //================================================================
156 Standard_Boolean TexturesExt_Presentation::loadShape(TopoDS_Shape& aShape, 
157                                          TCollection_AsciiString aFileName)
158 {
159   // create a TopoDS_Shape -> read from a brep file
160   CString anOCCTDataPathValue;
161   anOCCTDataPathValue.GetEnvironmentVariable(L"CSF_OCCTDataPath");
162   CString initfile = (anOCCTDataPathValue + L"\\occ\\" + aFileName.ToCString());
163
164   std::filebuf aFileBuf;
165   std::istream aStream (&aFileBuf);
166   if (!aFileBuf.open (initfile, std::ios::in))
167   {
168     initfile += L" was not found. The sample can not be shown.";
169     getDocument()->UpdateResultMessageDlg ("Textured Shape", initfile);
170     return Standard_False;
171   }
172
173   BRep_Builder aBld;
174   BRepTools::Read (aShape, aStream, aBld);
175   if (aShape.IsNull())
176   {
177     initfile += " is invalid. The sample can not be shown.";
178     getDocument()->UpdateResultMessageDlg ("Textured Shape", initfile);
179     return Standard_False;
180   }
181
182   return Standard_True;
183 }
184
185 //================================================================
186 // Function : lightsOnOff
187 // Purpose  : 6 lights are used for a brighter demonstration of textured shapes
188 //            call lightsOnOff(false) before showing normal shape
189 //            call lightsOnOff(true)  before showing textured shape
190 //================================================================
191 void TexturesExt_Presentation::lightsOnOff(Standard_Boolean isOn)
192 {
193   static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(V3d_XnegYposZneg);
194   static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(V3d_XnegYnegZpos);
195   static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(V3d_XposYnegZpos);
196   static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(V3d_XnegYnegZneg);
197   static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(V3d_XnegYposZpos);
198   static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(V3d_XposYposZpos);
199
200   if (isOn)
201   {
202     getViewer()->SetLightOn(aLight1);
203     getViewer()->SetLightOn(aLight2);
204     getViewer()->SetLightOn(aLight3);
205     getViewer()->SetLightOn(aLight4);
206     getViewer()->SetLightOn(aLight5);
207     getViewer()->SetLightOn(aLight6);
208   }
209   else 
210   {
211     getViewer()->SetLightOff(aLight1);
212     getViewer()->SetLightOff(aLight2);
213     getViewer()->SetLightOff(aLight3);
214     getViewer()->SetLightOff(aLight4);
215     getViewer()->SetLightOff(aLight5);
216     getViewer()->SetLightOff(aLight6);
217   }
218 }
219
220 //================================================================
221 // Function : TexturesExt_Presentation::sampleBottle
222 // Purpose  : 
223 //================================================================
224 void TexturesExt_Presentation::sampleBottle()
225 {  
226   TopoDS_Shape aShape;
227   if (!loadShape(aShape, "bottle.brep")) 
228     return;
229
230   // resize and move the shape to the center of the viewer
231 gp_Trsf aTrsf1, aTrsf2;
232 aTrsf1.SetScale(gp_Pnt(0,0,0), 0.8);
233 aTrsf2.SetTranslation(gp_Pnt(0,0,0),gp_Pnt(0,0,-20));
234 aTrsf1.Multiply(aTrsf2);
235 BRepBuilderAPI_Transform Transformer(aTrsf1);
236 Transformer.Perform(aShape);
237 aShape = Transformer.Shape();
238
239   TopTools_IndexedMapOfShape aFaces;
240   TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);
241
242   // display original shape in shaded display mode
243   Handle(AIS_Shape) aShapeIO = drawShape(aShape, Graphic3d_NOM_BRASS, Standard_False);
244   getAISContext()->SetDisplayMode(aShapeIO, AIS_Shaded, Standard_False);
245   // Set increased polygon offset for the main shape to avoid depth collision with textured faces
246   aShapeIO->SetPolygonOffsets(Aspect_POM_Fill, 1.5, 0.5);
247   DISP(aShapeIO);
248
249   Handle(AIS_Shape) aTFace1 = Texturize(aFaces(16), "carrelage1.gif", 1, 1, 3, 2);
250   DISP(aTFace1);
251
252   Handle(AIS_Shape) aTFace2 = Texturize(aFaces(21), "carrelage1.gif", 1, 1, 3, 2);
253   DISP(aTFace2);
254
255   getViewer()->Update();
256 }
257
258
259 //================================================================
260 // Function : TexturesExt_Presentation::sampleLand
261 // Purpose  : 
262 //================================================================
263 void TexturesExt_Presentation::sampleTerrain()
264 {
265   TopoDS_Shape aShape;
266   if (!loadShape(aShape, "terrain.brep"))
267     return;
268
269   // a part of the landscape is textured
270   TopTools_IndexedMapOfShape aFaces;
271   TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);
272
273 //  TopLoc_Location aLoc;
274 //  Handle(Geom_Surface) aSur = BRep_Tool::Surface(TopoDS::Face(aFaces(1)), aLoc);
275 //  Standard_Real u1,u2,v1,v2;
276 //  aSur->Bounds(u1,u2,v1,v2);
277 //  gp_Pnt aPnt = aSur->Value(u1, v1);
278   gp_Pnt aPnt(82100,80300,10940);// point at u1,v1
279   // resize and move the shape to the center of the viewer
280   
281   gp_Trsf aMoveTrsf;
282   gp_Ax3 New(gp_Pnt(-30,-30, 0),gp_Dir(0,0,1));
283   gp_Ax3 aCurrent(aPnt,gp_Dir(0,0,1));
284   aMoveTrsf.SetDisplacement(aCurrent, New);
285
286   gp_Trsf aScaleTrsf;
287   aScaleTrsf.SetScale(aPnt,0.0075);
288
289   BRepBuilderAPI_Transform aTransform(aMoveTrsf*aScaleTrsf);
290
291   aTransform.Perform(aFaces(1));
292   aShape = aTransform;
293
294   getAISContext()->Display (Texturize (aShape, "terrain.gif"), Standard_True);
295 }
296
297
298 //================================================================
299 // Function : moveScale
300 // Purpose  : move a shape a little left and scale it to 15%.
301 //================================================================
302 static void moveScale(TopoDS_Shape& aShape)
303 {
304   gp_Trsf aMoveTrsf;
305   gp_Ax3 New(gp_Pnt(-30,-30, -10),gp_Dir(0,0,1));
306   gp_Ax3 Current(gp_Pnt(0,0,0),gp_Dir(0,0,1));
307   aMoveTrsf.SetDisplacement(Current, New);
308
309   gp_Trsf aScaleTrsf;
310   aScaleTrsf.SetScale(gp_Pnt(0,0,0),0.15);
311
312   BRepBuilderAPI_Transform aTransform(aMoveTrsf*aScaleTrsf);
313
314   aTransform.Perform(aShape);
315   aShape = aTransform;
316 }
317
318 //================================================================
319 // Function : TexturesExt_Presentation::sampleKitchen
320 // Purpose  : kitchen with texturized items in it.
321 //================================================================
322 void TexturesExt_Presentation::sampleKitchen()
323 {
324   TopoDS_Shape aShape;
325
326   if (!loadShape(aShape, "Room.brep"))
327     return;
328
329   gp_Trsf aTrsf;
330   gp_Ax3 NewCoordSystem (gp_Pnt(-1,-1, -1),gp_Dir(0,0,1));
331   gp_Ax3 CurrentCoordSystem(gp_Pnt(0,0,0),gp_Dir(0,0,1));
332   aTrsf.SetDisplacement(CurrentCoordSystem, NewCoordSystem);
333   aShape.Location(TopLoc_Location(aTrsf));
334
335   moveScale(aShape);
336
337   // draw kitchen room whithout one wall (to better see the insides)
338   TopTools_IndexedMapOfShape aFaces;
339   TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);  
340   Standard_Integer nbFaces = aFaces.Extent();
341
342   // create a wooden kitchen floor
343   // the floor's face will be textured with texture from chataignier.gif
344   DISP(Texturize(aFaces(5),"plancher.gif",1,1,2,1));
345
346   // texturize other faces of the room with texture from wallpaper.gif (walls)
347   DISP(Texturize(aFaces(1),"wallpaper.gif",1,1,8,6));
348   DISP(Texturize(aFaces(3),"wallpaper.gif",1,1,8,6));
349   DISP(Texturize(aFaces(4),"wallpaper.gif",1,1,8,6));
350
351 //  DISP(drawShape(aFaces(1), Quantity_NOC_LIGHTPINK, Standard_False));
352 //  DISP(drawShape(aFaces(3), Quantity_NOC_LIGHTPINK, Standard_False));
353 //  DISP(drawShape(aFaces(4), Quantity_NOC_LIGHTPINK, Standard_False));
354
355   // texturize furniture items with "wooden" texture
356   if (loadShape(aShape, "MODERN_Table_1.brep"))
357   {
358     moveScale(aShape);
359     DISP(Texturize(aShape, "chataignier.gif"));
360   }
361   if (loadShape(aShape, "MODERN_Chair_1.brep"))
362   {
363     moveScale(aShape);
364     DISP(Texturize(aShape, "chataignier.gif"));
365   }
366   if (loadShape(aShape, "MODERN_Cooker_1.brep"))
367   {
368     moveScale(aShape);
369
370     aFaces.Clear();
371     TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);  
372     nbFaces = aFaces.Extent();
373
374     for (Standard_Integer i = 1; i <= nbFaces; i++)
375     {
376       if (i >= 59)
377         DISP(drawShape(aFaces(i), Graphic3d_NOM_STEEL, Standard_False));
378       else if (i >= 29)
379         DISP(drawShape(aFaces(i), Graphic3d_NOM_ALUMINIUM, Standard_False));
380       else if (i == 28)
381         DISP(Texturize(aFaces(i), "cookerplate.gif"));
382       else  
383         DISP(Texturize(aFaces(i), "chataignier.gif"));
384     }
385   }
386   if (loadShape(aShape, "MODERN_Cooker_1_opened.brep"))
387   {
388     moveScale(aShape);
389     DISP(Texturize(aShape, "chataignier.gif"));
390   }
391   if (loadShape(aShape, "MODERN_Exhaust_1.brep"))
392   {
393     moveScale(aShape);
394     DISP(drawShape(aShape, Graphic3d_NOM_STONE, Standard_False));
395   }
396   if (loadShape(aShape, "MODERN_MVCooker_1.brep"))
397   {
398     moveScale(aShape);
399     DISP(drawShape(aShape, Graphic3d_NOM_SILVER, Standard_False));
400   }
401   if (loadShape(aShape, "MODERN_MVCooker_1_opened.brep"))
402   {
403     moveScale(aShape);
404     DISP(drawShape(aShape, Graphic3d_NOM_SILVER, Standard_False));
405   }
406   if (loadShape(aShape, "MODERN_Sink_1.brep"))
407   {
408     moveScale(aShape);
409
410     aFaces.Clear();
411     TopExp::MapShapes(aShape, TopAbs_FACE, aFaces);  
412     nbFaces = aFaces.Extent();
413
414     for (Standard_Integer i = 1; i <= nbFaces; i++)
415     {
416       if (i < 145)
417         DISP(drawShape(aFaces(i), Graphic3d_NOM_ALUMINIUM, Standard_False));
418       else if (i == 145)
419         DISP(Texturize(aFaces(i), "cookerplate.gif"));
420       else  
421         DISP(Texturize(aFaces(i), "chataignier.gif"));
422     }
423   }
424   if (loadShape(aShape, "MODERN_Sink_1_opened.brep"))
425   {
426     moveScale(aShape);
427     DISP(Texturize(aShape, "chataignier.gif"));
428   }
429   if (loadShape(aShape, "MODERN_Refrigerator_1.brep"))
430   {
431     moveScale(aShape);
432     DISP(drawShape(aShape, Graphic3d_NOM_CHROME, Standard_False));
433   }
434   if (loadShape(aShape, "MODERN_Refrigerator_1_opened.brep"))
435   {
436     moveScale(aShape);
437     DISP(drawShape(aShape, Graphic3d_NOM_CHROME, Standard_False));
438   }
439
440   getViewer()->Update();
441 }