0030686: Visualization, SelectMgr_ViewerSelector - sorting issues of transformation...
[occt.git] / src / VrmlData / VrmlData_Material.cxx
CommitLineData
b311480e 1// Created on: 2007-07-17
2// Created by: Alexander GRIGORIEV
973c2be1 3// Copyright (c) 2007-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
16#include <VrmlData_Material.hxx>
17#include <Precision.hxx>
18#include <VrmlData_InBuffer.hxx>
19#include <VrmlData_Scene.hxx>
20#include <gp_XYZ.hxx>
21
92efcf78 22IMPLEMENT_STANDARD_RTTIEXT(VrmlData_Material,VrmlData_Node)
23
57c28b61 24#ifdef _MSC_VER
7fd59977 25#define _CRT_SECURE_NO_DEPRECATE
26#pragma warning (disable:4996)
27#endif
28
7fd59977 29
30//=======================================================================
31//function : VrmlData_Material()
32//purpose : Empty Constructor
33//=======================================================================
34
35VrmlData_Material::VrmlData_Material ()
36 : myAmbientIntensity (0.2),
37 myShininess (0.2),
38 myTransparency (0.),
39 myDiffuseColor (0.8, 0.8, 0.8, Quantity_TOC_RGB),
40 myEmissiveColor (0., 0., 0., Quantity_TOC_RGB),
41 mySpecularColor (0., 0., 0., Quantity_TOC_RGB)
42{}
43
44//=======================================================================
45//function : VrmlData_Material
46//purpose : Constructor
47//=======================================================================
48
49VrmlData_Material::VrmlData_Material (const VrmlData_Scene& theScene,
50 const char * theName,
51 const Standard_Real theAmbientIntens,
52 const Standard_Real theShininess,
53 const Standard_Real theTransparency)
54 : VrmlData_Node (theScene, theName),
55 myAmbientIntensity (theAmbientIntens < 0. ? 0.2 : theAmbientIntens),
56 myShininess (theShininess < 0. ? 0.2 : theShininess),
57 myTransparency (theTransparency < 0 ? 0. : theTransparency),
58 myDiffuseColor (0.8, 0.8, 0.8, Quantity_TOC_RGB),
59 myEmissiveColor (0., 0., 0., Quantity_TOC_RGB),
60 mySpecularColor (0., 0., 0., Quantity_TOC_RGB)
61{}
62
63
64//=======================================================================
65//function : VrmlData_Material::Clone
66//purpose :
67//=======================================================================
68
69Handle(VrmlData_Node) VrmlData_Material::Clone
70 (const Handle(VrmlData_Node)& theOther) const
71{
72 Handle(VrmlData_Material) aResult =
73 Handle(VrmlData_Material)::DownCast (VrmlData_Node::Clone(theOther));
74 if (aResult.IsNull())
75 aResult =
76 new VrmlData_Material (theOther.IsNull() ? Scene() : theOther->Scene(),
77 Name());
78
79 aResult->SetAmbientIntensity (myAmbientIntensity);
80 aResult->SetShininess (myShininess);
81 aResult->SetTransparency (myTransparency);
82 aResult->SetDiffuseColor (myDiffuseColor);
83 aResult->SetEmissiveColor (myEmissiveColor);
84 aResult->SetSpecularColor (mySpecularColor);
85 return aResult;
86}
87
88//=======================================================================
89//function : VrmlData_Material::Read
90//purpose :
91//=======================================================================
92
93VrmlData_ErrorStatus VrmlData_Material::Read (VrmlData_InBuffer& theBuffer)
94{
95 VrmlData_ErrorStatus aStatus;
96 const Standard_Real aConf = 0.001 * Precision::Confusion();
97 Standard_Real anIntensity[3] = { 0.2, 0.2, 0. };
98 gp_XYZ aColor[3] = {
99 gp_XYZ (0.8, 0.8, 0.8),
100 gp_XYZ (0.0, 0.0, 0.0),
101 gp_XYZ (0.0, 0.0, 0.0)
102 };
103 while (OK(aStatus, VrmlData_Scene::ReadLine(theBuffer))) {
104 if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "ambientIntensity")) {
105 if (OK(aStatus, Scene().ReadReal (theBuffer, anIntensity[0],
106 Standard_False, Standard_False)))
107 if (anIntensity[0] < -aConf || anIntensity[0] > 1.+aConf) {
108 aStatus = VrmlData_IrrelevantNumber;
109 break;
110 }
111 } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "shininess")) {
112 if (OK(aStatus, Scene().ReadReal (theBuffer, anIntensity[1],
113 Standard_False, Standard_False)))
114 if (anIntensity[1] < -aConf || anIntensity[1] > 1.+aConf) {
115 aStatus = VrmlData_IrrelevantNumber;
116 break;
117 }
118 } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "transparency")) {
119 if (OK(aStatus, Scene().ReadReal (theBuffer, anIntensity[2],
120 Standard_False, Standard_False)))
121 if (anIntensity[2] < -aConf || anIntensity[2] > 1.+aConf) {
122 aStatus = VrmlData_IrrelevantNumber;
123 break;
124 }
125 } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "diffuseColor")) {
126 if (OK(aStatus, Scene().ReadXYZ (theBuffer, aColor[0],
127 Standard_False, Standard_False)))
128 if (aColor[0].X() < -aConf || aColor[0].X() > 1.+aConf ||
129 aColor[0].Y() < -aConf || aColor[0].Y() > 1.+aConf ||
130 aColor[0].Z() < -aConf || aColor[0].Z() > 1.+aConf)
131 {
132 aStatus = VrmlData_IrrelevantNumber;
133 break;
134 }
135 } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "emissiveColor")) {
136 if (OK(aStatus, Scene().ReadXYZ (theBuffer, aColor[1],
137 Standard_False, Standard_False)))
138 if (aColor[1].X() < -aConf || aColor[1].X() > 1.+aConf ||
139 aColor[1].Y() < -aConf || aColor[1].Y() > 1.+aConf ||
140 aColor[1].Z() < -aConf || aColor[1].Z() > 1.+aConf)
141 {
142 aStatus = VrmlData_IrrelevantNumber;
143 break;
144 }
145 } else if (VRMLDATA_LCOMPARE (theBuffer.LinePtr, "specularColor")) {
146 if (OK(aStatus, Scene().ReadXYZ (theBuffer, aColor[2],
147 Standard_False, Standard_False)))
148 if (aColor[2].X() < -aConf || aColor[2].X() > 1.+aConf ||
149 aColor[2].Y() < -aConf || aColor[2].Y() > 1.+aConf ||
150 aColor[2].Z() < -aConf || aColor[2].Z() > 1.+aConf)
151 {
152 aStatus = VrmlData_IrrelevantNumber;
153 break;
154 }
155 } else
156 break;
157
158 if (!OK(aStatus))
159 break;
160 }
161
162 // Read the terminating (closing) brace
163 if (OK(aStatus))
164 aStatus = readBrace (theBuffer);
165
166 // Store the values in the Material node instance
167 if (OK(aStatus)) {
168 myAmbientIntensity = anIntensity[0];
169 myShininess = anIntensity[1];
170 myTransparency = anIntensity[2];
171 myDiffuseColor.SetValues (aColor[0].X(), aColor[0].Y(), aColor[0].Z(),
172 Quantity_TOC_RGB);
173 myEmissiveColor.SetValues (aColor[1].X(), aColor[1].Y(), aColor[1].Z(),
174 Quantity_TOC_RGB);
175 mySpecularColor.SetValues (aColor[2].X(), aColor[2].Y(), aColor[2].Z(),
176 Quantity_TOC_RGB);
177 }
178 return aStatus;
179}
180
181//=======================================================================
182//function : VrmlData_Material::Write
183//purpose :
184//=======================================================================
185
186VrmlData_ErrorStatus VrmlData_Material::Write (const char * thePrefix) const
187{
1d47d8d0 188 VrmlData_ErrorStatus aStatus = VrmlData_StatusOK;
7fd59977 189 const VrmlData_Scene& aScene = Scene();
190 static char header[] = "Material {";
191 if (aScene.IsDummyWrite() == Standard_False &&
192 OK (aStatus, aScene.WriteLine (thePrefix, header, GlobalIndent())))
193 {
194 char buf[128];
195 Standard_Real val[3];
196 Quantity_TypeOfColor bidType (Quantity_TOC_RGB);
197 const Standard_Real aConf (0.001 * Precision::Confusion());
198
199 if (OK(aStatus) && fabs(myAmbientIntensity - 0.2) > aConf) {
91322f44 200 Sprintf (buf, "%.6g", myAmbientIntensity);
7fd59977 201 aStatus = aScene.WriteLine ("ambientIntensity ", buf);
202 }
203 if (OK(aStatus)) {
204 myDiffuseColor.Values (val[0], val[1], val[2], bidType);
205 if ((val[0] - 0.8) * (val[0] - 0.8) +
206 (val[1] - 0.8) * (val[1] - 0.8) +
207 (val[2] - 0.8) * (val[2] - 0.8) > 1e-7)
208 {
91322f44 209 Sprintf (buf, "%.6g %.6g %.6g", val[0], val[1], val[2]);
7fd59977 210 aStatus = aScene.WriteLine ("diffuseColor ", buf);
211 }
212 }
213 if (OK(aStatus)) {
214 myEmissiveColor.Values (val[0], val[1], val[2], bidType);
215 if (val[0] * val[0] + val[1] * val[1] + val[2] * val[2] > 1e-7) {
91322f44 216 Sprintf (buf, "%.6g %.6g %.6g", val[0], val[1], val[2]);
7fd59977 217 aStatus = aScene.WriteLine ("emissiveColor ", buf);
218 }
219 }
220 if (OK(aStatus) && fabs(myShininess - 0.2) > aConf) {
91322f44 221 Sprintf (buf, "%.6g", myShininess);
7fd59977 222 aStatus = aScene.WriteLine ("shininess ", buf);
223 }
224 if (OK(aStatus)) {
225 mySpecularColor.Values (val[0], val[1], val[2], bidType);
226 if (val[0] * val[0] + val[1] * val[1] + val[2] * val[2] > 1e-7) {
91322f44 227 Sprintf (buf, "%.6g %.6g %.6g", val[0], val[1], val[2]);
7fd59977 228 aStatus = aScene.WriteLine ("specularColor ", buf);
229 }
230 }
231 if (OK(aStatus) && myTransparency > aConf) {
91322f44 232 Sprintf (buf, "%.6g", myTransparency);
7fd59977 233 aStatus = aScene.WriteLine ("transparency ", buf);
234 }
235
236 aStatus = WriteClosing();
237 }
238 return aStatus;
239}
240
241//=======================================================================
242//function : IsDefault
243//purpose :
244//=======================================================================
245
246Standard_Boolean VrmlData_Material::IsDefault () const
247{
248 const Standard_Real aConf (0.001 * Precision::Confusion());
249 Standard_Boolean aResult (Standard_False);
250 if (fabs(myAmbientIntensity - 0.2) < aConf &&
251 fabs(myShininess - 0.2) < aConf &&
252 myTransparency < aConf)
253 {
254 Standard_Real val[3][3];
255 Quantity_TypeOfColor bidType (Quantity_TOC_RGB);
256 myDiffuseColor.Values (val[0][0], val[0][1], val[0][2], bidType);
257 myEmissiveColor.Values (val[1][0], val[1][1], val[1][2], bidType);
258 mySpecularColor.Values (val[2][0], val[2][1], val[2][2], bidType);
259 aResult = (((val[0][0] - 0.8)*(val[0][0] - 0.8) +
260 (val[0][1] - 0.8)*(val[0][1] - 0.8) +
261 (val[0][2] - 0.8)*(val[0][2] - 0.8) < 1e-7) &&
262 (val[1][0] * val[1][0] +
263 val[1][1] * val[1][0] +
264 val[1][2] * val[1][0] < 1e-7) &&
265 (val[2][0] * val[2][0] +
266 val[2][1] * val[2][0] +
267 val[2][2] * val[2][0] < 1e-7));
268 }
269 return aResult;
270}
271
272