1 // Created on: 1996-01-18
2 // Created by: Frederic MAUPAS
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 //abv 17.11.99: renamed from StepPDR_MakeUnitAndToleranceContext and merged with STEPControl_Unit
18 //abv 30.02.00: ability to write file in units other than MM
20 #include <Interface_Static.hxx>
21 #include <StepBasic_ConversionBasedUnitAndAreaUnit.hxx>
22 #include <StepBasic_ConversionBasedUnitAndLengthUnit.hxx>
23 #include <StepBasic_ConversionBasedUnitAndPlaneAngleUnit.hxx>
24 #include <StepBasic_ConversionBasedUnitAndSolidAngleUnit.hxx>
25 #include <StepBasic_ConversionBasedUnitAndVolumeUnit.hxx>
26 #include <StepBasic_DimensionalExponents.hxx>
27 #include <StepBasic_LengthMeasureWithUnit.hxx>
28 #include <StepBasic_MeasureValueMember.hxx>
29 #include <StepBasic_MeasureWithUnit.hxx>
30 #include <StepBasic_NamedUnit.hxx>
31 #include <StepBasic_SiUnitAndAreaUnit.hxx>
32 #include <StepBasic_SiUnitAndLengthUnit.hxx>
33 #include <StepBasic_SiUnitAndPlaneAngleUnit.hxx>
34 #include <StepBasic_SiUnitAndSolidAngleUnit.hxx>
35 #include <StepBasic_SiUnitAndVolumeUnit.hxx>
36 #include <STEPConstruct_UnitContext.hxx>
37 #include <StepData_Factors.hxx>
38 #include <StepData_StepModel.hxx>
39 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
40 #include <StepRepr_GlobalUncertaintyAssignedContext.hxx>
41 #include <StepRepr_GlobalUnitAssignedContext.hxx>
42 #include <TCollection_HAsciiString.hxx>
44 //=======================================================================
45 //function : STEPConstruct_UnitContext
47 //=======================================================================
48 STEPConstruct_UnitContext::STEPConstruct_UnitContext()
49 : done(Standard_False),
51 planeAngleFactor(0.0),
52 solidAngleFactor(0.0),
56 lengthDone = planeAngleDone = solidAngleDone = hasUncertainty =
57 areaDone = volumeDone = Standard_False;
58 //pdn file r_47-sd.stp initialize field.
59 theUncertainty = RealLast();
62 //=======================================================================
65 //=======================================================================
67 void STEPConstruct_UnitContext::Init(const Standard_Real Tol3d,
68 const Handle(StepData_StepModel)& theModel,
69 const StepData_Factors& theLocalFactors)
73 GRC = new StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx;
74 Handle(TCollection_HAsciiString) contextID =
75 new TCollection_HAsciiString("Context #1"); // ?????
77 Handle(TCollection_HAsciiString) contextType =
78 new TCollection_HAsciiString("3D Context with UNIT and UNCERTAINTY");
80 // Units : LengthUnit and PlaneAngleUnit (no SolidAngleUnit applicable)
82 Handle(StepBasic_NamedUnit) lengthUnit;
83 Standard_CString uName = 0;
84 Standard_Boolean hasPref = Standard_True;
85 StepBasic_SiPrefix siPref = StepBasic_spMilli;
86 Standard_Real aScale = 1.;
87 switch (theModel->InternalParameters.WriteUnit)
89 case 1: uName = "INCH"; aScale = 25.4; break;
92 case 4: uName = "FOOT"; aScale = 304.8; break;
93 case 5: uName = "MILE"; aScale = 1609344.0; break;
94 case 6: hasPref = Standard_False; aScale = 1000.0; break;
95 case 7: siPref = StepBasic_spKilo; aScale = 1000000.0; break;
96 case 8: uName = "MIL"; aScale = 0.0254; break;
97 case 9: siPref = StepBasic_spMicro; aScale = 0.001; break;
98 case 10: siPref = StepBasic_spCenti; aScale = 10.0; break;
99 case 11: uName = "MICROINCH"; aScale = 0.0000254; break;
102 Handle(StepBasic_SiUnitAndLengthUnit) siUnit =
103 new StepBasic_SiUnitAndLengthUnit;
104 siUnit->Init(hasPref,siPref,StepBasic_sunMetre);
106 if ( uName ) { // for non-metric units, create conversion_based_unit
107 Handle(StepBasic_MeasureValueMember) val = new StepBasic_MeasureValueMember;
108 val->SetName("LENGTH_UNIT");
109 val->SetReal (aScale);
111 Handle(StepBasic_LengthMeasureWithUnit) measure = new StepBasic_LengthMeasureWithUnit;
113 Unit.SetValue ( siUnit );
114 measure->Init ( val, Unit );
116 Handle(StepBasic_DimensionalExponents) theDimExp = new StepBasic_DimensionalExponents;
117 theDimExp->Init ( 1., 0., 0., 0., 0., 0., 0. );
119 Handle(TCollection_HAsciiString) convName = new TCollection_HAsciiString ( uName );
120 Handle(StepBasic_ConversionBasedUnitAndLengthUnit) convUnit =
121 new StepBasic_ConversionBasedUnitAndLengthUnit;
122 convUnit->Init ( theDimExp, convName, measure );
124 lengthUnit = convUnit;
126 else lengthUnit = siUnit;
128 Handle(StepBasic_SiUnitAndPlaneAngleUnit) radianUnit =
129 new StepBasic_SiUnitAndPlaneAngleUnit;
130 radianUnit ->Init(Standard_False,
131 StepBasic_spMilli, // the unit is radian, no prefix
132 StepBasic_sunRadian);
134 Handle(StepBasic_HArray1OfNamedUnit) units =
135 new StepBasic_HArray1OfNamedUnit(1, 3);
137 Handle(StepBasic_SiUnitAndSolidAngleUnit) sradUnit =
138 new StepBasic_SiUnitAndSolidAngleUnit;
139 sradUnit ->Init(Standard_False,
140 StepBasic_spMilli, // the unit is steradian, no prefix
141 StepBasic_sunSteradian);
143 units->SetValue(1, lengthUnit);
144 units->SetValue(2, radianUnit);
145 units->SetValue(3, sradUnit);
147 // Uncertainty : 3D confusion Tolerance
149 Handle(StepBasic_HArray1OfUncertaintyMeasureWithUnit) Tols =
150 new StepBasic_HArray1OfUncertaintyMeasureWithUnit(1,1);
151 Handle(StepBasic_UncertaintyMeasureWithUnit) theTol3d =
152 new StepBasic_UncertaintyMeasureWithUnit;
154 Handle(TCollection_HAsciiString) TolName =
155 new TCollection_HAsciiString("distance_accuracy_value");
156 Handle(TCollection_HAsciiString) TolDesc =
157 new TCollection_HAsciiString("confusion accuracy");
159 Handle(StepBasic_MeasureValueMember) mvs = new StepBasic_MeasureValueMember;
160 mvs->SetName("LENGTH_MEASURE");
161 mvs->SetReal ( Tol3d / theLocalFactors.LengthFactor() );
163 Unit.SetValue ( lengthUnit );
164 theTol3d->Init(mvs, Unit, TolName, TolDesc);
165 Tols->SetValue(1, theTol3d);
167 GRC->Init(contextID, contextType, 3, units, Tols);
170 //=======================================================================
173 //=======================================================================
175 Standard_Boolean STEPConstruct_UnitContext::IsDone() const
180 //=======================================================================
183 //=======================================================================
185 Handle(StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx) STEPConstruct_UnitContext::Value() const
190 // ==========================================================================
191 // Method : ConvertSiPrefix
192 // Purpose : Computes SiPrefix conversion
193 // ==========================================================================
195 Standard_Real STEPConstruct_UnitContext::ConvertSiPrefix (const StepBasic_SiPrefix aPrefix)
199 case StepBasic_spExa: return 1.E+18;
200 case StepBasic_spPeta: return 1.E+15;
201 case StepBasic_spTera: return 1.E+12;
202 case StepBasic_spGiga: return 1.E+9;
203 case StepBasic_spMega: return 1.E+6;
204 case StepBasic_spKilo: return 1.E+3;
205 case StepBasic_spHecto: return 1.E+2;
206 case StepBasic_spDeca: return 1.E+1;
207 case StepBasic_spDeci: return 1.E-1;
208 case StepBasic_spCenti: return 1.E-2;
209 case StepBasic_spMilli: return 1.E-3;
210 case StepBasic_spMicro: return 1.E-6;
211 case StepBasic_spNano: return 1.E-9;
212 case StepBasic_spPico: return 1.E-12;
213 case StepBasic_spFemto: return 1.E-15;
214 case StepBasic_spAtto: return 1.E-18;
222 // ==========================================================================
223 // Method : STEPConstruct_UnitContext::SiUnitNameFactor
225 // ==========================================================================
227 Standard_Boolean STEPConstruct_UnitContext::SiUnitNameFactor(const Handle(StepBasic_SiUnit)& aSiUnit,
228 Standard_Real& theSIUNFactor) const
231 switch ( aSiUnit->Name() )
233 case StepBasic_sunMetre:
234 case StepBasic_sunRadian:
235 case StepBasic_sunSteradian:
236 return Standard_True;
238 // std::cout << "Unknown SiUnitName : " << aSiUnit->Name() << std::endl;
239 return Standard_False;
243 // ==========================================================================
244 // Method : STEPConstruct_UnitContext::ComputeFactors
246 // ==========================================================================
248 Standard_Integer STEPConstruct_UnitContext::ComputeFactors(const Handle(StepRepr_GlobalUnitAssignedContext)& aContext,
249 const StepData_Factors& theLocalFactors)
251 Standard_Integer status = 0;
253 // Initialise the default value
254 // status : 0 if OK, else 1 2 3
255 lengthFactor = solidAngleFactor = 1.;
256 planeAngleFactor = M_PI/180.;
257 // Standard_Real theLExp = 1.;
258 // Standard_Real thePAExp = 0.;
259 // Standard_Real theSAExp = 0.;
260 lengthDone = planeAngleDone = solidAngleDone = Standard_False;
262 if (aContext.IsNull()) {
264 std::cout<<" -- STEPConstruct_UnitContext:ComputeFactor, Context undefined -> default"<<std::endl;
270 Handle(StepBasic_HArray1OfNamedUnit) theUnits = aContext->Units();
271 Standard_Integer nbU = aContext->NbUnits();
273 for (Standard_Integer i = 1; i <= nbU; i++) {
274 Handle(StepBasic_NamedUnit) theNamedUnit = aContext->UnitsValue(i);
275 status = ComputeFactors(theNamedUnit, theLocalFactors);
278 std::cout << " -- STEPConstruct_UnitContext:ComputeFactor: Unit item no." << i << " is not recognized" << std::endl;
285 Standard_Integer STEPConstruct_UnitContext::ComputeFactors(const Handle(StepBasic_NamedUnit)& aUnit,
286 const StepData_Factors& theLocalFactors)
289 //:f3 abv 8 Apr 98: ProSTEP TR8 tr8_as_sd_sw: the case of unrecognized entity
290 if ( aUnit.IsNull() )
293 Standard_Integer status = 0;
294 Standard_Real theFactor= 0.;
295 Standard_Real theSIUNF = 0.;
297 Standard_Real parameter= 0.;
298 Standard_Boolean parameterDone = Standard_False;
299 if(aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnit))) {
300 Handle(StepBasic_ConversionBasedUnit) theCBU =
301 Handle(StepBasic_ConversionBasedUnit)::DownCast(aUnit);
302 // Handle(StepBasic_DimensionalExponents) theDimExp = theCBU->Dimensions();
303 Handle(StepBasic_MeasureWithUnit) theMWU;
304 if(!theCBU.IsNull()) {
305 theMWU = theCBU->ConversionFactor();
306 // sln 8.10.2001: the case of unrecognized entity
309 //if (!theMWU->IsKind(STANDARD_TYPE(StepBasic_LengthMeasureWithUnit))) { gka
312 Handle(StepBasic_NamedUnit) theTargetUnit = theMWU->UnitComponent().NamedUnit();
313 //StepBasic_Unit theTargetUnit = theMWU->UnitComponent();
314 Standard_Real theSIPFactor = 1.;
316 //:f5 abv 24 Apr 98: ProSTEP TR8 tr8_bv1_tc: INCHES
317 //gka Handle(StepBasic_SiUnitAndLengthUnit) theSUALU =
318 // Handle(StepBasic_SiUnitAndLengthUnit)::DownCast(theTargetUnit);
319 // Handle(StepBasic_SiUnit) theSIU;
320 // if ( ! theSUALU.IsNull() ) theSIU = Handle(StepBasic_SiUnit)::DownCast(theSUALU);
321 Handle(StepBasic_SiUnit) theSIU = //f5
322 Handle(StepBasic_SiUnit)::DownCast(theTargetUnit);//f5
324 if (!theSIU.IsNull()) {
325 if (theSIU->HasPrefix()) {
327 StepBasic_SiPrefix aPrefix = theSIU->Prefix();
328 theSIPFactor = ConvertSiPrefix(aPrefix);
330 // Treat the SiUnitName
331 if (!SiUnitNameFactor(theSIU,theSIUNF)) status = 11; // et continue
332 //std::cout << "The SiUnitNameFactor is :";
333 //std::cout << theSIUNF << std::endl;
336 // std::cout << "Recursive algo required - Aborted" << std::endl;
339 Standard_Real theMVAL = theMWU->ValueComponent();
340 theFactor = theSIPFactor * theMVAL; // * theSIUNF * pow(10.,theLExp)
342 parameter = theFactor;
344 parameterDone = Standard_True;
349 std::cout << "Error in the file : parameter double defined" << std::endl;
353 else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnit))) {
354 Handle(StepBasic_SiUnit) theSIU = Handle(StepBasic_SiUnit)::DownCast(aUnit);
355 Standard_Real theSIPFactor = 1.;
356 if (theSIU->HasPrefix()) {
358 StepBasic_SiPrefix aPrefix = theSIU->Prefix();
359 theSIPFactor = ConvertSiPrefix(aPrefix);
362 // Treat the SiUnitName
363 if (!SiUnitNameFactor(theSIU,theSIUNF)) status = 11;
365 // final computation for lengthFactor
366 theFactor = theSIPFactor * theSIUNF;
367 parameter = theFactor;
368 if (!parameterDone) {
369 parameterDone = Standard_True;
374 std::cout << "Error in the file : parameter double defined" << std::endl;
379 // Defining a type of unit
382 std::cout << "Unit Type not implemented" << std::endl;
387 const Standard_Real aCascadeUnit = theLocalFactors.CascadeUnit();
388 if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndLengthUnit))||
389 aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit))) {
391 lengthFactor = parameter;
393 lengthFactor = parameter * 1000. / aCascadeUnit;
396 lengthDone = Standard_True;
400 std::cout << "Error in the file : LengthFactor double defined" << std::endl;
403 } // end of LengthUnit
404 else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndPlaneAngleUnit))||
405 aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndPlaneAngleUnit))) {
406 planeAngleFactor = parameter;
407 planeAngleDone = Standard_True;
408 } // end of PlaneAngleUnit
409 else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndSolidAngleUnit))||
410 aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndSolidAngleUnit))) {
411 solidAngleFactor = parameter;
412 solidAngleDone = Standard_True;
413 } // end of SolidAngleUnit
414 else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndAreaUnit)) ||
415 aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndAreaUnit))) {
420 af = parameter * 1000. / aCascadeUnit;
422 areaDone = Standard_True;
423 areaFactor = pow(af,2);
425 else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndVolumeUnit)) ||
426 aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndVolumeUnit))) {
431 af = parameter * 1000. / aCascadeUnit;
433 volumeDone = Standard_True;
434 volumeFactor = pow(af,3);
440 // ==========================================================================
441 // Method : STEPConstruct_UnitContext::ComputeTolerance
443 // ==========================================================================
445 Standard_Integer STEPConstruct_UnitContext::ComputeTolerance
446 (const Handle(StepRepr_GlobalUncertaintyAssignedContext)& aContext)
448 Standard_Integer status = 0;
449 // Decode the Uncertainty information (geometric accuracy)
451 hasUncertainty = Standard_False;
452 Standard_Integer nbUncertainty = 0;
454 if (!aContext.IsNull()) nbUncertainty = aContext->NbUncertainty();
457 for (Standard_Integer un = 1 ; un <= nbUncertainty ; un ++) {
458 Handle(StepBasic_UncertaintyMeasureWithUnit) aUMWU = aContext->UncertaintyValue(un);
459 if (aUMWU.IsNull()) {
461 std::cout<<"BAD Uncertainty Measure with Units, n0."<<un<<std::endl;
465 // Decode the associated Unit
466 Handle(StepBasic_SiUnitAndLengthUnit) aUnit =
467 Handle(StepBasic_SiUnitAndLengthUnit)::DownCast(aUMWU->UnitComponent().NamedUnit());
468 if (!aUnit.IsNull()) {
469 // Extract Uncertainty value
470 Standard_Real LengthUncertainty = aUMWU->ValueComponent();
471 // Update it according to the Length Unit Factor
472 //pdn r_47-sd.stp to choose minimal uncertainty
473 if(theUncertainty > LengthUncertainty) theUncertainty = LengthUncertainty;
474 hasUncertainty = Standard_True;
477 Handle(StepBasic_ConversionBasedUnitAndLengthUnit) aCBULU =
478 Handle(StepBasic_ConversionBasedUnitAndLengthUnit)::DownCast(aUMWU->UnitComponent().NamedUnit());
479 if (!aCBULU.IsNull()) {
480 // Extract Uncertainty value
481 Standard_Real LengthUncertainty = aUMWU->ValueComponent();
482 // Update it according to the Length Unit Factor
483 //pdn r_47-sd.stp to choose minimal uncertainty
484 if(theUncertainty > LengthUncertainty) theUncertainty = LengthUncertainty; // *lengthFactor; fait par appelant
485 hasUncertainty = Standard_True;
491 if (hasUncertainty) std::cout << "UNCERTAINTY read as " << theUncertainty << std::endl;
496 // ==========================================================================
497 // Method : STEPConstruct_UnitContext::LengthFactor
499 // ==========================================================================
500 Standard_Real STEPConstruct_UnitContext::LengthFactor() const
501 { return lengthFactor; }
503 // ==========================================================================
504 // Method : STEPConstruct_UnitContext::PlaneAngleFactor
506 // ==========================================================================
507 Standard_Real STEPConstruct_UnitContext::PlaneAngleFactor() const
508 { return planeAngleFactor; }
510 // ==========================================================================
511 // Method : STEPConstruct_UnitContext::SolidAngleFactor
513 // ==========================================================================
514 Standard_Real STEPConstruct_UnitContext::SolidAngleFactor() const
515 { return solidAngleFactor; }
517 // ==========================================================================
518 // Method : STEPConstruct_UnitContext::Uncertainty
520 // ==========================================================================
521 Standard_Real STEPConstruct_UnitContext::Uncertainty () const
522 { return theUncertainty; }
524 // ==========================================================================
525 // Method : STEPConstruct_UnitContext::HasUncertainty
527 // ==========================================================================
528 Standard_Boolean STEPConstruct_UnitContext::HasUncertainty () const
529 { return hasUncertainty; }
531 // ==========================================================================
532 // Method : STEPConstruct_UnitContext::LengthDone
534 // ==========================================================================
535 Standard_Boolean STEPConstruct_UnitContext::LengthDone() const
536 { return lengthDone; }
538 // ==========================================================================
539 // Method : STEPConstruct_UnitContext::PlaneAngleDone
541 // ==========================================================================
542 Standard_Boolean STEPConstruct_UnitContext::PlaneAngleDone() const
543 { return planeAngleDone; }
545 // ==========================================================================
546 // Method : STEPConstruct_UnitContext::SolidAngleDone
548 // ==========================================================================
549 Standard_Boolean STEPConstruct_UnitContext::SolidAngleDone() const
550 { return solidAngleDone; }
552 // ==========================================================================
553 // Method : STEPConstruct_UnitContext::StatusMessage
555 // ==========================================================================
556 Standard_CString STEPConstruct_UnitContext::StatusMessage (const Standard_Integer status) const
560 case 1 : return "No GlobalUnitAssignedContext, default taken";
561 case 2 : return "No LengthMeasureWithUnit, default taken";
562 case 3 : return "No SiUnit for LengthMeasure undefined, default taken";
563 case 4 : return "No PlaneAngleMeasureWithUnit, default taken";
564 case 5 : return "No SiUnit for PlaneAngleMeasure undefined, default taken";
565 case 6 : return "No SolidAngleMeasureWithUnit, default taken";
566 case 7 : return "No SiUnit for SolidAngleMeasure undefined, default taken";
568 case 11 : return "Length Unit not recognized, default taken";
569 case 12 : return "Plane Angle Unit not recognized, default taken";
570 case 13 : return "Solid Angle Unit not recognized, default taken";
571 case 14 : return "At least one unit is twice defined";
573 case 40 : return "Bad GlobalUncertaintyAssignedContext, default unit taken";
578 return "Badly defined units, default taken";
581 Standard_Real STEPConstruct_UnitContext::AreaFactor() const
586 Standard_Real STEPConstruct_UnitContext::VolumeFactor() const
591 Standard_Boolean STEPConstruct_UnitContext::AreaDone() const
596 Standard_Boolean STEPConstruct_UnitContext::VolumeDone() const