0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / Units / Units.cxx
1 // Created on: 1992-10-28
2 // Created by: Gilles DEBARBOUILLE
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // Modified     Wed Apr  2 14:10:05 1997 by Gerard GRAS
18 //              Add FirstQuantity access methods
19 // Modified     Mon Apr  7 16:52:40 1997 by Patrick BOSINCO
20 //              Add Dimensions access methods
21
22 //              Convertir correctement les unites translatees
23
24 #include <stdlib.h>
25
26 #include <Units.hxx>
27 #include <Units_Measurement.hxx>
28 #include <Units_Quantity.hxx>
29 #include <Units_Dimensions.hxx>
30 #include <Units_Unit.hxx>
31 #include <Units_Lexicon.hxx>
32 #include <Units_UnitsLexicon.hxx>
33 #include <Units_UnitsDictionary.hxx>
34 #include <Units_UnitsSystem.hxx>
35 #include <Units_UnitSentence.hxx>
36 #include <Units_ShiftedToken.hxx>
37 #include <Standard_NoSuchObject.hxx>
38 #include <TColStd_HSequenceOfHAsciiString.hxx>
39 #include <Units_Operators.hxx>
40
41 static Handle(Units_Dimensions) nulldimensions;
42 static Handle(Units_UnitsLexicon) lexiconunits;
43 static Handle(Units_Lexicon) lexiconformula;
44 static Handle(Units_UnitsDictionary) unitsdictionary;
45 static Handle(Units_UnitsSystem) unitssystem;
46
47 static TCollection_AsciiString unitsfile;
48 static TCollection_AsciiString lexiconfile;
49 static TCollection_AsciiString lastunit;
50 static Handle(Units_Dimensions) lastdimension;
51 static Standard_Real lastvalue,lastmove;
52
53
54 //=======================================================================
55 //function : UnitsFile
56 //purpose  : 
57 //=======================================================================
58
59 void Units::UnitsFile(const Standard_CString afile) {
60   unitsfile = TCollection_AsciiString(afile);
61 }
62
63
64 //=======================================================================
65 //function : LexiconFile
66 //purpose  : 
67 //=======================================================================
68
69 void Units::LexiconFile(const Standard_CString afile) {
70   lexiconfile = TCollection_AsciiString(afile);
71 }
72
73
74 //=======================================================================
75 //function : DictionaryOfUnits
76 //purpose  : 
77 //=======================================================================
78
79 Handle(Units_UnitsDictionary) Units::DictionaryOfUnits(const Standard_Boolean amode)
80 {
81   if(unitsdictionary.IsNull())
82     {
83 //      std::cout<<"Allocation du dictionnaire"<<std::endl;
84       unitsdictionary = new Units_UnitsDictionary();
85 //      std::cout<<"Creation du dictionnaire"<<std::endl;
86       unitsdictionary->Creates();
87     }
88   else if(amode)
89     {
90 //      std::cout<<"Creation du dictionnaire"<<std::endl;
91       unitsdictionary->Creates();
92     }
93   return unitsdictionary;
94 }
95
96
97 //=======================================================================
98 //function : Quantity
99 //purpose  : 
100 //=======================================================================
101
102 Handle(Units_Quantity) Units::Quantity(const Standard_CString aquantity)
103 {
104   Standard_Integer index;
105   Handle(Units_Quantity) quantity;
106   Handle(Units_Quantity) nullquantity;
107   Handle(Units_QuantitiesSequence) quantitiessequence;
108
109   quantitiessequence = Units::DictionaryOfUnits()->Sequence();
110   for(index=1;index<=quantitiessequence->Length();index++)
111     {
112       quantity = quantitiessequence->Value(index);
113       if(quantity->Name() == aquantity) return quantity;
114     }
115
116 #ifdef OCCT_DEBUG
117   std::cout<<"Warning: BAD Quantity = Units::Quantity(quantity('" << aquantity << "'))" << std::endl;
118 #endif
119   return nullquantity;
120 }
121
122
123 //=======================================================================
124 //function : Quantity
125 //purpose  :
126 //=======================================================================
127
128 static TCollection_AsciiString symbol_string,quantity_string;
129 Standard_CString Units::FirstQuantity(const Standard_CString aunit)
130 {
131   Standard_Integer i,j,k;
132   Handle(Units_Quantity) thequantity;
133   Handle(Units_QuantitiesSequence) quantitiessequence;
134   Handle(Units_UnitsSequence) unitssequence;
135   Handle(Units_Unit) unit;
136   Handle(TColStd_HSequenceOfHAsciiString) symbolssequence;
137   TCollection_AsciiString symbol(aunit);
138
139   if( symbol == symbol_string ) return quantity_string.ToCString();
140
141   quantitiessequence = Units::DictionaryOfUnits()->Sequence();
142   for(i=1;i<=quantitiessequence->Length();i++) {
143     thequantity = quantitiessequence->Value(i);
144     unitssequence = thequantity->Sequence();
145     for(j=1;j<=unitssequence->Length();j++) {
146       unit = unitssequence->Value(j);
147       symbolssequence = unit->SymbolsSequence();
148       for( k=1;k<=symbolssequence->Length();k++) {
149         if( symbol == symbolssequence->Value(k)->String() ) {
150           symbol_string = symbol;
151           quantity_string = thequantity->Name();
152           return quantity_string.ToCString();
153         }
154       }
155     }
156   }
157
158 #ifdef OCCT_DEBUG
159   std::cout<<"Warning: BAD Quantity = Units::Quantity(unit('" << symbol << "'))" << std::endl;
160 #endif
161   return NULL;
162 }
163
164
165 //=======================================================================
166 //function : LexiconUnits
167 //purpose  : 
168 //=======================================================================
169
170 Handle(Units_Lexicon) Units::LexiconUnits(const Standard_Boolean amode)
171 {
172   if(lexiconunits.IsNull()) {
173 //      std::cout<<"Allocation du lexique d'unites"<<std::endl;
174     lexiconunits = new Units_UnitsLexicon();
175 //      std::cout<<"Creation du lexique d'unites"<<std::endl;
176     lexiconunits->Creates(amode);
177   }
178   return lexiconunits;
179 }
180
181
182 //=======================================================================
183 //function : LexiconFormula
184 //purpose  : 
185 //=======================================================================
186
187 Handle(Units_Lexicon) Units::LexiconFormula()
188 {
189   if(lexiconformula.IsNull()) {
190 //      std::cout<<"Allocation du lexique d'expression"<<std::endl;
191     lexiconformula = new Units_Lexicon();
192 //      std::cout<<"Creation du lexique d'expression"<<std::endl;
193     lexiconformula->Creates();
194   }
195   return lexiconformula;
196 }
197
198
199 //=======================================================================
200 //function : NullDimensions
201 //purpose  : 
202 //=======================================================================
203
204 Handle(Units_Dimensions) Units::NullDimensions()
205 {
206   if(nulldimensions.IsNull()) nulldimensions = new Units_Dimensions(0.,0.,0.,0.,0.,0.,0.,0.,0.);
207   return nulldimensions;
208 }
209
210
211 //=======================================================================
212 //function : Convert
213 //purpose  : 
214 //=======================================================================
215
216 Standard_Real Units::Convert(const Standard_Real avalue,
217                              const Standard_CString afirstunit,
218                              const Standard_CString asecondunit)
219 {
220   Units_Measurement measurement(avalue,afirstunit);
221   measurement.Convert(asecondunit);
222   return measurement.Measurement();
223 }
224
225
226 //=======================================================================
227 //function : ToSI
228 //purpose  :
229 //=======================================================================
230
231 Standard_Real Units::ToSI(const Standard_Real aData,
232                           const Standard_CString aUnit){
233
234   Handle(Units_Dimensions) aDimBid;
235   return Units::ToSI(aData,aUnit,aDimBid);
236 }
237
238
239 //=======================================================================
240 //function : ToSI
241 //purpose  :
242 //=======================================================================
243
244 Standard_Real Units::ToSI(const Standard_Real aData,
245                           const Standard_CString aUnit,
246                           Handle(Units_Dimensions) &dim)
247 {
248   if(lastunit != aUnit ) {
249
250     lastunit = TCollection_AsciiString(aUnit);
251     Units_UnitSentence unitsentence(aUnit);
252     if(!unitsentence.IsDone()) {
253 #ifdef OCCT_DEBUG
254       std::cout<<"can not convert - incorrect unit => return 0.0"<<std::endl;
255 #endif
256       return 0.0;
257     }
258     Handle(Units_Token) token = unitsentence.Evaluate();
259     lastvalue = token->Value();
260     lastmove = 0.;
261     if( token->IsKind(STANDARD_TYPE(Units_ShiftedToken)) ) {
262       Handle(Units_ShiftedToken) stoken =
263         Handle(Units_ShiftedToken)::DownCast(token) ;
264       lastmove = stoken->Move();
265     }
266     lastdimension = token->Dimensions();
267   }
268   dim = lastdimension;
269   return (aData + lastmove) * lastvalue;
270 }
271
272
273 //=======================================================================
274 //function : FromSI
275 //purpose  :
276 //=======================================================================
277
278 Standard_Real Units::FromSI(const Standard_Real aData,
279                             const Standard_CString aUnit){
280   Handle(Units_Dimensions) aDimBid;
281   return Units::FromSI(aData,aUnit,aDimBid);
282 }
283
284
285 //=======================================================================
286 //function : FromSI
287 //purpose  :
288 //=======================================================================
289
290 Standard_Real Units::FromSI(const Standard_Real aData,
291                             const Standard_CString aUnit,
292                             Handle(Units_Dimensions) &dim)
293 {
294   if(lastunit != aUnit) {
295     lastunit = TCollection_AsciiString(aUnit);
296     Units_UnitSentence unitsentence(aUnit);
297     if(!unitsentence.IsDone()) {
298 #ifdef OCCT_DEBUG
299       std::cout<<"Warning: can not convert - incorrect unit => return 0.0"<<std::endl;
300 #endif
301       return 0.0;
302     }
303     Handle(Units_Token) token = unitsentence.Evaluate();
304     lastvalue = token->Value();
305     lastmove = 0.;
306     if( token->IsKind(STANDARD_TYPE(Units_ShiftedToken)) ) {
307       Handle(Units_ShiftedToken) stoken =
308         Handle(Units_ShiftedToken)::DownCast(token) ;
309       lastmove = stoken->Move();
310     }
311     lastdimension = token->Dimensions();
312   }
313   dim = lastdimension;
314   return (aData / lastvalue) - lastmove;
315 }
316
317
318 //=======================================================================
319 //function : Dimensions
320 //purpose  :
321 //=======================================================================
322
323 Handle(Units_Dimensions) Units::Dimensions(const Standard_CString aType)
324 {
325  if (aType) {
326    Handle(Units_UnitsDictionary) dico=Units::DictionaryOfUnits(Standard_False);
327
328    Handle(Units_QuantitiesSequence) qSeq = dico->Sequence();
329    Handle(Units_Quantity) q;
330    for (Standard_Integer i=1; i <= qSeq->Length(); i++) {
331      if (qSeq->Value(i) == aType) {
332        return qSeq->Value(i)->Dimensions();
333      }
334    }
335    throw Standard_NoSuchObject("Units::Dimensions");
336  }
337  return Units_Dimensions::ALess();
338 }