b311480e |
1 | // Created on: 2007-07-17 |
2 | // Created by: Alexander GRIGORIEV |
3 | // Copyright (c) 2007-2012 OPEN CASCADE SAS |
4 | // |
5 | // The content of this file is subject to the Open CASCADE Technology Public |
6 | // License Version 6.5 (the "License"). You may not use the content of this file |
7 | // except in compliance with the License. Please obtain a copy of the License |
8 | // at http://www.opencascade.org and read it completely before using this file. |
9 | // |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
12 | // |
13 | // The Original Code and all software distributed under the License is |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
15 | // Initial Developer hereby disclaims all such warranties, including without |
16 | // limitation, any warranties of merchantability, fitness for a particular |
17 | // purpose or non-infringement. Please see the License for the specific terms |
18 | // and conditions governing the rights and limitations under the License. |
19 | |
7fd59977 |
20 | |
21 | #include <VrmlData_Material.hxx> |
22 | #include <Precision.hxx> |
23 | #include <VrmlData_InBuffer.hxx> |
24 | #include <VrmlData_Scene.hxx> |
25 | #include <gp_XYZ.hxx> |
26 | |
27 | #ifdef WNT |
28 | #define _CRT_SECURE_NO_DEPRECATE |
29 | #pragma warning (disable:4996) |
30 | #endif |
31 | |
32 | IMPLEMENT_STANDARD_HANDLE (VrmlData_Material, VrmlData_Node) |
33 | IMPLEMENT_STANDARD_RTTIEXT (VrmlData_Material, VrmlData_Node) |
34 | |
35 | //======================================================================= |
36 | //function : VrmlData_Material() |
37 | //purpose : Empty Constructor |
38 | //======================================================================= |
39 | |
40 | VrmlData_Material::VrmlData_Material () |
41 | : myAmbientIntensity (0.2), |
42 | myShininess (0.2), |
43 | myTransparency (0.), |
44 | myDiffuseColor (0.8, 0.8, 0.8, Quantity_TOC_RGB), |
45 | myEmissiveColor (0., 0., 0., Quantity_TOC_RGB), |
46 | mySpecularColor (0., 0., 0., Quantity_TOC_RGB) |
47 | {} |
48 | |
49 | //======================================================================= |
50 | //function : VrmlData_Material |
51 | //purpose : Constructor |
52 | //======================================================================= |
53 | |
54 | VrmlData_Material::VrmlData_Material (const VrmlData_Scene& theScene, |
55 | const char * theName, |
56 | const Standard_Real theAmbientIntens, |
57 | const Standard_Real theShininess, |
58 | const Standard_Real theTransparency) |
59 | : VrmlData_Node (theScene, theName), |
60 | myAmbientIntensity (theAmbientIntens < 0. ? 0.2 : theAmbientIntens), |
61 | myShininess (theShininess < 0. ? 0.2 : theShininess), |
62 | myTransparency (theTransparency < 0 ? 0. : theTransparency), |
63 | myDiffuseColor (0.8, 0.8, 0.8, Quantity_TOC_RGB), |
64 | myEmissiveColor (0., 0., 0., Quantity_TOC_RGB), |
65 | mySpecularColor (0., 0., 0., Quantity_TOC_RGB) |
66 | {} |
67 | |
68 | |
69 | //======================================================================= |
70 | //function : VrmlData_Material::Clone |
71 | //purpose : |
72 | //======================================================================= |
73 | |
74 | Handle(VrmlData_Node) VrmlData_Material::Clone |
75 | (const Handle(VrmlData_Node)& theOther) const |
76 | { |
77 | Handle(VrmlData_Material) aResult = |
78 | Handle(VrmlData_Material)::DownCast (VrmlData_Node::Clone(theOther)); |
79 | if (aResult.IsNull()) |
80 | aResult = |
81 | new VrmlData_Material (theOther.IsNull() ? Scene() : theOther->Scene(), |
82 | Name()); |
83 | |
84 | aResult->SetAmbientIntensity (myAmbientIntensity); |
85 | aResult->SetShininess (myShininess); |
86 | aResult->SetTransparency (myTransparency); |
87 | aResult->SetDiffuseColor (myDiffuseColor); |
88 | aResult->SetEmissiveColor (myEmissiveColor); |
89 | aResult->SetSpecularColor (mySpecularColor); |
90 | return aResult; |
91 | } |
92 | |
93 | //======================================================================= |
94 | //function : VrmlData_Material::Read |
95 | //purpose : |
96 | //======================================================================= |
97 | |
98 | VrmlData_ErrorStatus VrmlData_Material::Read (VrmlData_InBuffer& theBuffer) |
99 | { |
100 | VrmlData_ErrorStatus aStatus; |
101 | const Standard_Real aConf = 0.001 * Precision::Confusion(); |
102 | Standard_Real anIntensity[3] = { 0.2, 0.2, 0. }; |
103 | gp_XYZ aColor[3] = { |
104 | gp_XYZ (0.8, 0.8, 0.8), |
105 | gp_XYZ (0.0, 0.0, 0.0), |
106 | gp_XYZ (0.0, 0.0, 0.0) |
107 | }; |
108 | while (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) { |
109 | if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "ambientIntensity")) { |
110 | if (OK(aStatus, Scene().ReadReal (theBuffer, anIntensity[0], |
111 | Standard_False, Standard_False))) |
112 | if (anIntensity[0] < -aConf || anIntensity[0] > 1.+aConf) { |
113 | aStatus = VrmlData_IrrelevantNumber; |
114 | break; |
115 | } |
116 | } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "shininess")) { |
117 | if (OK(aStatus, Scene().ReadReal (theBuffer, anIntensity[1], |
118 | Standard_False, Standard_False))) |
119 | if (anIntensity[1] < -aConf || anIntensity[1] > 1.+aConf) { |
120 | aStatus = VrmlData_IrrelevantNumber; |
121 | break; |
122 | } |
123 | } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "transparency")) { |
124 | if (OK(aStatus, Scene().ReadReal (theBuffer, anIntensity[2], |
125 | Standard_False, Standard_False))) |
126 | if (anIntensity[2] < -aConf || anIntensity[2] > 1.+aConf) { |
127 | aStatus = VrmlData_IrrelevantNumber; |
128 | break; |
129 | } |
130 | } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "diffuseColor")) { |
131 | if (OK(aStatus, Scene().ReadXYZ (theBuffer, aColor[0], |
132 | Standard_False, Standard_False))) |
133 | if (aColor[0].X() < -aConf || aColor[0].X() > 1.+aConf || |
134 | aColor[0].Y() < -aConf || aColor[0].Y() > 1.+aConf || |
135 | aColor[0].Z() < -aConf || aColor[0].Z() > 1.+aConf) |
136 | { |
137 | aStatus = VrmlData_IrrelevantNumber; |
138 | break; |
139 | } |
140 | } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "emissiveColor")) { |
141 | if (OK(aStatus, Scene().ReadXYZ (theBuffer, aColor[1], |
142 | Standard_False, Standard_False))) |
143 | if (aColor[1].X() < -aConf || aColor[1].X() > 1.+aConf || |
144 | aColor[1].Y() < -aConf || aColor[1].Y() > 1.+aConf || |
145 | aColor[1].Z() < -aConf || aColor[1].Z() > 1.+aConf) |
146 | { |
147 | aStatus = VrmlData_IrrelevantNumber; |
148 | break; |
149 | } |
150 | } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "specularColor")) { |
151 | if (OK(aStatus, Scene().ReadXYZ (theBuffer, aColor[2], |
152 | Standard_False, Standard_False))) |
153 | if (aColor[2].X() < -aConf || aColor[2].X() > 1.+aConf || |
154 | aColor[2].Y() < -aConf || aColor[2].Y() > 1.+aConf || |
155 | aColor[2].Z() < -aConf || aColor[2].Z() > 1.+aConf) |
156 | { |
157 | aStatus = VrmlData_IrrelevantNumber; |
158 | break; |
159 | } |
160 | } else |
161 | break; |
162 | |
163 | if (!OK(aStatus)) |
164 | break; |
165 | } |
166 | |
167 | // Read the terminating (closing) brace |
168 | if (OK(aStatus)) |
169 | aStatus = readBrace (theBuffer); |
170 | |
171 | // Store the values in the Material node instance |
172 | if (OK(aStatus)) { |
173 | myAmbientIntensity = anIntensity[0]; |
174 | myShininess = anIntensity[1]; |
175 | myTransparency = anIntensity[2]; |
176 | myDiffuseColor.SetValues (aColor[0].X(), aColor[0].Y(), aColor[0].Z(), |
177 | Quantity_TOC_RGB); |
178 | myEmissiveColor.SetValues (aColor[1].X(), aColor[1].Y(), aColor[1].Z(), |
179 | Quantity_TOC_RGB); |
180 | mySpecularColor.SetValues (aColor[2].X(), aColor[2].Y(), aColor[2].Z(), |
181 | Quantity_TOC_RGB); |
182 | } |
183 | return aStatus; |
184 | } |
185 | |
186 | //======================================================================= |
187 | //function : VrmlData_Material::Write |
188 | //purpose : |
189 | //======================================================================= |
190 | |
191 | VrmlData_ErrorStatus VrmlData_Material::Write (const char * thePrefix) const |
192 | { |
193 | VrmlData_ErrorStatus aStatus; |
194 | const VrmlData_Scene& aScene = Scene(); |
195 | static char header[] = "Material {"; |
196 | if (aScene.IsDummyWrite() == Standard_False && |
197 | OK (aStatus, aScene.WriteLine (thePrefix, header, GlobalIndent()))) |
198 | { |
199 | char buf[128]; |
200 | Standard_Real val[3]; |
201 | Quantity_TypeOfColor bidType (Quantity_TOC_RGB); |
202 | const Standard_Real aConf (0.001 * Precision::Confusion()); |
203 | |
204 | if (OK(aStatus) && fabs(myAmbientIntensity - 0.2) > aConf) { |
91322f44 |
205 | Sprintf (buf, "%.6g", myAmbientIntensity); |
7fd59977 |
206 | aStatus = aScene.WriteLine ("ambientIntensity ", buf); |
207 | } |
208 | if (OK(aStatus)) { |
209 | myDiffuseColor.Values (val[0], val[1], val[2], bidType); |
210 | if ((val[0] - 0.8) * (val[0] - 0.8) + |
211 | (val[1] - 0.8) * (val[1] - 0.8) + |
212 | (val[2] - 0.8) * (val[2] - 0.8) > 1e-7) |
213 | { |
91322f44 |
214 | Sprintf (buf, "%.6g %.6g %.6g", val[0], val[1], val[2]); |
7fd59977 |
215 | aStatus = aScene.WriteLine ("diffuseColor ", buf); |
216 | } |
217 | } |
218 | if (OK(aStatus)) { |
219 | myEmissiveColor.Values (val[0], val[1], val[2], bidType); |
220 | if (val[0] * val[0] + val[1] * val[1] + val[2] * val[2] > 1e-7) { |
91322f44 |
221 | Sprintf (buf, "%.6g %.6g %.6g", val[0], val[1], val[2]); |
7fd59977 |
222 | aStatus = aScene.WriteLine ("emissiveColor ", buf); |
223 | } |
224 | } |
225 | if (OK(aStatus) && fabs(myShininess - 0.2) > aConf) { |
91322f44 |
226 | Sprintf (buf, "%.6g", myShininess); |
7fd59977 |
227 | aStatus = aScene.WriteLine ("shininess ", buf); |
228 | } |
229 | if (OK(aStatus)) { |
230 | mySpecularColor.Values (val[0], val[1], val[2], bidType); |
231 | if (val[0] * val[0] + val[1] * val[1] + val[2] * val[2] > 1e-7) { |
91322f44 |
232 | Sprintf (buf, "%.6g %.6g %.6g", val[0], val[1], val[2]); |
7fd59977 |
233 | aStatus = aScene.WriteLine ("specularColor ", buf); |
234 | } |
235 | } |
236 | if (OK(aStatus) && myTransparency > aConf) { |
91322f44 |
237 | Sprintf (buf, "%.6g", myTransparency); |
7fd59977 |
238 | aStatus = aScene.WriteLine ("transparency ", buf); |
239 | } |
240 | |
241 | aStatus = WriteClosing(); |
242 | } |
243 | return aStatus; |
244 | } |
245 | |
246 | //======================================================================= |
247 | //function : IsDefault |
248 | //purpose : |
249 | //======================================================================= |
250 | |
251 | Standard_Boolean VrmlData_Material::IsDefault () const |
252 | { |
253 | const Standard_Real aConf (0.001 * Precision::Confusion()); |
254 | Standard_Boolean aResult (Standard_False); |
255 | if (fabs(myAmbientIntensity - 0.2) < aConf && |
256 | fabs(myShininess - 0.2) < aConf && |
257 | myTransparency < aConf) |
258 | { |
259 | Standard_Real val[3][3]; |
260 | Quantity_TypeOfColor bidType (Quantity_TOC_RGB); |
261 | myDiffuseColor.Values (val[0][0], val[0][1], val[0][2], bidType); |
262 | myEmissiveColor.Values (val[1][0], val[1][1], val[1][2], bidType); |
263 | mySpecularColor.Values (val[2][0], val[2][1], val[2][2], bidType); |
264 | aResult = (((val[0][0] - 0.8)*(val[0][0] - 0.8) + |
265 | (val[0][1] - 0.8)*(val[0][1] - 0.8) + |
266 | (val[0][2] - 0.8)*(val[0][2] - 0.8) < 1e-7) && |
267 | (val[1][0] * val[1][0] + |
268 | val[1][1] * val[1][0] + |
269 | val[1][2] * val[1][0] < 1e-7) && |
270 | (val[2][0] * val[2][0] + |
271 | val[2][1] * val[2][0] + |
272 | val[2][2] * val[2][0] < 1e-7)); |
273 | } |
274 | return aResult; |
275 | } |
276 | |
277 | |