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