1 // Author: Ilya Khramov
2 // Copyright (c) 2019 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <Graphic3d_CubeMapPacked.hxx>
16
17 #include <Image_AlienPixMap.hxx>
18 #include <Image_DDSParser.hxx>
19
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CubeMapPacked,Graphic3d_CubeMap)20 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CubeMapPacked, Graphic3d_CubeMap)
21
22 // =======================================================================
23 // function : Graphic3d_CubeMapPacked
24 // purpose :
25 // =======================================================================
26 Graphic3d_CubeMapPacked::Graphic3d_CubeMapPacked (const TCollection_AsciiString& theFilePath,
27 const Graphic3d_ValidatedCubeMapOrder theOrder)
28 :
29 Graphic3d_CubeMap (theFilePath),
30 myOrder (theOrder),
31 myTileNumberX (1)
32 {}
33
34 // =======================================================================
35 // function : Graphic3d_CubeMapPacked
36 // purpose :
37 // =======================================================================
Graphic3d_CubeMapPacked(const Handle (Image_PixMap)& theImage,const Graphic3d_ValidatedCubeMapOrder theOrder)38 Graphic3d_CubeMapPacked::Graphic3d_CubeMapPacked (const Handle(Image_PixMap)& theImage,
39 const Graphic3d_ValidatedCubeMapOrder theOrder)
40 :
41 Graphic3d_CubeMap (Handle(Image_PixMap)()),
42 myOrder (theOrder),
43 myTileNumberX (1)
44 {
45 if (checkImage (theImage, myTileNumberX))
46 {
47 myPixMap = theImage;
48 }
49 }
50
51 // =======================================================================
52 // function : CompressedValue
53 // purpose :
54 // =======================================================================
Handle(Image_CompressedPixMap)55 Handle(Image_CompressedPixMap) Graphic3d_CubeMapPacked::CompressedValue (const Handle(Image_SupportedFormats)& theSupported)
56 {
57 if (myTileNumberX == 0
58 || !myPixMap.IsNull())
59 {
60 return Handle(Image_CompressedPixMap)();
61 }
62
63 TCollection_AsciiString aFilePath;
64 myPath.SystemName (aFilePath);
65 if (!aFilePath.IsEmpty())
66 {
67 const unsigned int aTileIndex = myOrder[myCurrentSide];
68 Handle(Image_CompressedPixMap) anImage = Image_DDSParser::Load (theSupported, aFilePath, (Standard_Integer )aTileIndex);
69 if (!anImage.IsNull()
70 && anImage->NbFaces() == 6
71 && anImage->SizeX() == anImage->SizeY())
72 {
73 myIsTopDown = anImage->IsTopDown();
74 return anImage;
75 }
76 }
77 return Handle(Image_CompressedPixMap)();
78 }
79
80 // =======================================================================
81 // function : Value
82 // purpose :
83 // =======================================================================
Handle(Image_PixMap)84 Handle(Image_PixMap) Graphic3d_CubeMapPacked::Value (const Handle(Image_SupportedFormats)& theSupported)
85 {
86 if (myTileNumberX != 0)
87 {
88 if (myPixMap.IsNull())
89 {
90 TCollection_AsciiString aFilePath;
91 myPath.SystemName (aFilePath);
92 if (!aFilePath.IsEmpty())
93 {
94 tryLoadImage (theSupported, aFilePath);
95 }
96 }
97
98 if (!myPixMap.IsNull())
99 {
100 Handle(Image_PixMap) aWrapper = new Image_PixMap();
101
102 Standard_Size aTileSize = myPixMap->SizeX() / myTileNumberX;
103
104 myIsTopDown = myPixMap->IsTopDown();
105
106 Graphic3d_CubeMapOrder anOrder = myOrder;
107
108 if (!myIsTopDown)
109 {
110 myPixMap->SetTopDown (true);
111 anOrder.Swap (Graphic3d_CMS_POS_Y, Graphic3d_CMS_NEG_Y);
112 }
113
114 unsigned int aTileIndexX = anOrder[myCurrentSide] % myTileNumberX;
115 unsigned int aTileIndexY = anOrder[myCurrentSide] / myTileNumberX;
116
117 aTileIndexY = myIsTopDown ? aTileIndexY : (6 / myTileNumberX - 1 - aTileIndexY);
118
119 if (aWrapper->InitWrapper (myPixMap->Format(),
120 myPixMap->ChangeRawValue(aTileIndexY * aTileSize, aTileIndexX * aTileSize),
121 aTileSize,
122 aTileSize,
123 myPixMap->SizeRowBytes()))
124 {
125 myPixMap->SetTopDown (myIsTopDown);
126 return aWrapper;
127 }
128 else
129 {
130 myPixMap->SetTopDown(myIsTopDown);
131 }
132 }
133 }
134
135 return Handle(Image_PixMap)();
136 }
137
138 // =======================================================================
139 // function : checkOrder
140 // purpose :
141 // =======================================================================
checkOrder(const NCollection_Array1<unsigned int> & theOrder)142 Standard_Boolean Graphic3d_CubeMapPacked::checkOrder (const NCollection_Array1<unsigned int>& theOrder)
143 {
144 Standard_Boolean anOrderIsValid = Standard_True;
145
146 if (theOrder.Size() != 6)
147 {
148 anOrderIsValid = Standard_False;
149 }
150 else
151 {
152 for (unsigned int i = 0; i < 6 && anOrderIsValid; ++i)
153 {
154 if (theOrder[i] > 5)
155 {
156 anOrderIsValid = Standard_False;
157 break;
158 }
159
160 for (unsigned int j = i + 1; j < 6; ++j)
161 {
162 if (theOrder[i] == theOrder[j])
163 {
164 anOrderIsValid = Standard_False;
165 break;
166 }
167 }
168 }
169 }
170
171 if (!anOrderIsValid)
172 {
173 throw Standard_Failure ("Ivalid order format in tiles of Graphic3d_CubeMapPacked");
174 }
175
176 return anOrderIsValid;
177 }
178
179 // =======================================================================
180 // function : checkImage
181 // purpose :
182 // =======================================================================
checkImage(const Handle (Image_PixMap)& theImage,unsigned int & theTileNumberX)183 Standard_Boolean Graphic3d_CubeMapPacked::checkImage (const Handle(Image_PixMap)& theImage,
184 unsigned int& theTileNumberX)
185 {
186 Standard_Size aSizeX = theImage->SizeX();
187 Standard_Size aSizeY = theImage->SizeY();
188
189 if ((aSizeY % aSizeX == 0) && (aSizeY / aSizeX == 6))
190 {
191 theTileNumberX = 1;
192 }
193 else if ((aSizeX % aSizeY == 0) && (aSizeX / aSizeY == 6))
194 {
195 theTileNumberX = 6;
196 }
197 else if ((aSizeX % 2 == 0) && (aSizeY % 3 == 0) && (aSizeX / 2 == aSizeY / 3))
198 {
199 theTileNumberX = 2;
200 }
201 else if ((aSizeX % 3 == 0) && (aSizeY % 2 == 0) && (aSizeX / 3 == aSizeY / 2))
202 {
203 theTileNumberX = 3;
204 }
205 else
206 {
207 return Standard_False;
208 }
209
210 return Standard_True;
211 }
212
213 // =======================================================================
214 // function : tryLoadImage
215 // purpose :
216 // =======================================================================
tryLoadImage(const Handle (Image_SupportedFormats)& theSupported,const TCollection_AsciiString & theFilePath)217 void Graphic3d_CubeMapPacked::tryLoadImage (const Handle(Image_SupportedFormats)& theSupported,
218 const TCollection_AsciiString& theFilePath)
219 {
220 Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap;
221 if (anImage->Load (theFilePath))
222 {
223 if (checkImage (anImage, myTileNumberX))
224 {
225 convertToCompatible (theSupported, anImage);
226 myPixMap = anImage;
227 }
228 }
229 }
230