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