Loading files
// Created on: 1996-01-18
// Created by: Frederic MAUPAS
// Copyright (c) 1996-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// abv 17.11.99: renamed from StepPDR_MakeUnitAndToleranceContext and merged with STEPControl_Unit
// abv 30.02.00: ability to write file in units other than MM
#include <StepBasic_ConversionBasedUnitAndAreaUnit.hxx>
#include <StepBasic_ConversionBasedUnitAndLengthUnit.hxx>
#include <StepBasic_ConversionBasedUnitAndPlaneAngleUnit.hxx>
#include <StepBasic_ConversionBasedUnitAndSolidAngleUnit.hxx>
#include <StepBasic_ConversionBasedUnitAndVolumeUnit.hxx>
#include <StepBasic_DimensionalExponents.hxx>
#include <StepBasic_LengthMeasureWithUnit.hxx>
#include <StepBasic_MeasureValueMember.hxx>
#include <StepBasic_MeasureWithUnit.hxx>
#include <StepBasic_NamedUnit.hxx>
#include <StepBasic_SiUnitAndAreaUnit.hxx>
#include <StepBasic_SiUnitAndLengthUnit.hxx>
#include <StepBasic_SiUnitAndPlaneAngleUnit.hxx>
#include <StepBasic_SiUnitAndSolidAngleUnit.hxx>
#include <StepBasic_SiUnitAndVolumeUnit.hxx>
#include <STEPConstruct_UnitContext.hxx>
#include <StepData_Factors.hxx>
#include <StepData_StepModel.hxx>
#include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
#include <StepRepr_GlobalUncertaintyAssignedContext.hxx>
#include <StepRepr_GlobalUnitAssignedContext.hxx>
#include <StepRepr_ReprItemAndMeasureWithUnit.hxx>
#include <TCollection_HAsciiString.hxx>
//=================================================================================================
STEPConstruct_UnitContext::STEPConstruct_UnitContext()
: done(false),
lengthFactor(0.0),
planeAngleFactor(0.0),
solidAngleFactor(0.0),
areaFactor(0.0),
volumeFactor(0.0)
{
lengthDone = planeAngleDone = solidAngleDone = hasUncertainty = areaDone = volumeDone = false;
// pdn file r_47-sd.stp initialize field.
theUncertainty = RealLast();
}
//=================================================================================================
void STEPConstruct_UnitContext::Init(const double Tol3d,
const occ::handle<StepData_StepModel>& theModel,
const StepData_Factors& theLocalFactors)
{
done = true;
GRC = new StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx;
occ::handle<TCollection_HAsciiString> contextID =
new TCollection_HAsciiString("Context #1"); // ?????
occ::handle<TCollection_HAsciiString> contextType =
new TCollection_HAsciiString("3D Context with UNIT and UNCERTAINTY");
// Units : LengthUnit and PlaneAngleUnit (no SolidAngleUnit applicable)
occ::handle<StepBasic_NamedUnit> lengthUnit;
const char* uName = nullptr;
bool hasPref = true;
StepBasic_SiPrefix siPref = StepBasic_spMilli;
double aScale = 1.;
switch (theModel->InternalParameters.WriteUnit)
{
case 1:
uName = "INCH";
aScale = 25.4;
break;
default:
case 2:
break;
case 4:
uName = "FOOT";
aScale = 304.8;
break;
case 5:
uName = "MILE";
aScale = 1609344.0;
break;
case 6:
hasPref = false;
aScale = 1000.0;
break;
case 7:
siPref = StepBasic_spKilo;
aScale = 1000000.0;
break;
case 8:
uName = "MIL";
aScale = 0.0254;
break;
case 9:
siPref = StepBasic_spMicro;
aScale = 0.001;
break;
case 10:
siPref = StepBasic_spCenti;
aScale = 10.0;
break;
case 11:
uName = "MICROINCH";
aScale = 0.0000254;
break;
}
occ::handle<StepBasic_SiUnitAndLengthUnit> siUnit = new StepBasic_SiUnitAndLengthUnit;
siUnit->Init(hasPref, siPref, StepBasic_sunMetre);
if (uName)
{ // for non-metric units, create conversion_based_unit
occ::handle<StepBasic_MeasureValueMember> val = new StepBasic_MeasureValueMember;
val->SetName("LENGTH_UNIT");
val->SetReal(aScale);
occ::handle<StepBasic_LengthMeasureWithUnit> measure = new StepBasic_LengthMeasureWithUnit;
StepBasic_Unit Unit;
Unit.SetValue(siUnit);
measure->Init(val, Unit);
occ::handle<StepBasic_DimensionalExponents> theDimExp = new StepBasic_DimensionalExponents;
theDimExp->Init(1., 0., 0., 0., 0., 0., 0.);
occ::handle<TCollection_HAsciiString> convName = new TCollection_HAsciiString(uName);
occ::handle<StepBasic_ConversionBasedUnitAndLengthUnit> convUnit =
new StepBasic_ConversionBasedUnitAndLengthUnit;
convUnit->Init(theDimExp, convName, measure);
lengthUnit = convUnit;
}
else
{
lengthUnit = siUnit;
}
occ::handle<StepBasic_SiUnitAndPlaneAngleUnit> radianUnit = new StepBasic_SiUnitAndPlaneAngleUnit;
radianUnit->Init(false,
StepBasic_spMilli, // the unit is radian, no prefix
StepBasic_sunRadian);
occ::handle<NCollection_HArray1<occ::handle<StepBasic_NamedUnit>>> units =
new NCollection_HArray1<occ::handle<StepBasic_NamedUnit>>(1, 3);
occ::handle<StepBasic_SiUnitAndSolidAngleUnit> sradUnit = new StepBasic_SiUnitAndSolidAngleUnit;
sradUnit->Init(false,
StepBasic_spMilli, // the unit is steradian, no prefix
StepBasic_sunSteradian);
units->SetValue(1, lengthUnit);
units->SetValue(2, radianUnit);
units->SetValue(3, sradUnit);
// Uncertainty : 3D confusion Tolerance
occ::handle<NCollection_HArray1<occ::handle<StepBasic_UncertaintyMeasureWithUnit>>> Tols =
new NCollection_HArray1<occ::handle<StepBasic_UncertaintyMeasureWithUnit>>(1, 1);
occ::handle<StepBasic_UncertaintyMeasureWithUnit> theTol3d =
new StepBasic_UncertaintyMeasureWithUnit;
occ::handle<TCollection_HAsciiString> TolName =
new TCollection_HAsciiString("distance_accuracy_value");
occ::handle<TCollection_HAsciiString> TolDesc =
new TCollection_HAsciiString("confusion accuracy");
occ::handle<StepBasic_MeasureValueMember> mvs = new StepBasic_MeasureValueMember;
mvs->SetName("LENGTH_MEASURE");
mvs->SetReal(Tol3d / theLocalFactors.LengthFactor());
StepBasic_Unit Unit;
Unit.SetValue(lengthUnit);
theTol3d->Init(mvs, Unit, TolName, TolDesc);
Tols->SetValue(1, theTol3d);
GRC->Init(contextID, contextType, 3, units, Tols);
}
//=================================================================================================
bool STEPConstruct_UnitContext::IsDone() const
{
return done;
}
//=================================================================================================
occ::handle<StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx>
STEPConstruct_UnitContext::Value() const
{
return GRC;
}
//=================================================================================================
double STEPConstruct_UnitContext::ConvertSiPrefix(const StepBasic_SiPrefix aPrefix)
{
switch (aPrefix)
{
case StepBasic_spExa:
return 1.E+18;
case StepBasic_spPeta:
return 1.E+15;
case StepBasic_spTera:
return 1.E+12;
case StepBasic_spGiga:
return 1.E+9;
case StepBasic_spMega:
return 1.E+6;
case StepBasic_spKilo:
return 1.E+3;
case StepBasic_spHecto:
return 1.E+2;
case StepBasic_spDeca:
return 1.E+1;
case StepBasic_spDeci:
return 1.E-1;
case StepBasic_spCenti:
return 1.E-2;
case StepBasic_spMilli:
return 1.E-3;
case StepBasic_spMicro:
return 1.E-6;
case StepBasic_spNano:
return 1.E-9;
case StepBasic_spPico:
return 1.E-12;
case StepBasic_spFemto:
return 1.E-15;
case StepBasic_spAtto:
return 1.E-18;
default:
break;
}
return 1.;
}
//=================================================================================================
bool STEPConstruct_UnitContext::SiUnitNameFactor(const occ::handle<StepBasic_SiUnit>& aSiUnit,
double& theSIUNFactor) const
{
theSIUNFactor = 1.;
switch (aSiUnit->Name())
{
case StepBasic_sunMetre:
case StepBasic_sunRadian:
case StepBasic_sunSteradian:
return true;
default:
// std::cout << "Unknown SiUnitName : " << aSiUnit->Name() << std::endl;
return false;
}
}
//=================================================================================================
int STEPConstruct_UnitContext::ComputeFactors(
const occ::handle<StepRepr_GlobalUnitAssignedContext>& aContext,
const StepData_Factors& theLocalFactors)
{
int status = 0;
// Initialise the default value
// status : 0 if OK, else 1 2 3
lengthFactor = solidAngleFactor = 1.;
planeAngleFactor = M_PI / 180.;
// double theLExp = 1.;
// double thePAExp = 0.;
// double theSAExp = 0.;
lengthDone = planeAngleDone = solidAngleDone = false;
if (aContext.IsNull())
{
return 1;
}
// Start Computation
occ::handle<NCollection_HArray1<occ::handle<StepBasic_NamedUnit>>> theUnits = aContext->Units();
int nbU = aContext->NbUnits();
for (int i = 1; i <= nbU; i++)
{
occ::handle<StepBasic_NamedUnit> theNamedUnit = aContext->UnitsValue(i);
status = ComputeFactors(theNamedUnit, theLocalFactors);
}
return status;
}
//=================================================================================================
int STEPConstruct_UnitContext::ComputeFactors(const occ::handle<StepBasic_NamedUnit>& aUnit,
const StepData_Factors& theLocalFactors)
{
//: f3 abv 8 Apr 98: ProSTEP TR8 tr8_as_sd_sw: the case of unrecognized entity
if (aUnit.IsNull())
{
return -1;
}
int status = 0;
double theFactor = 0.;
double theSIUNF = 0.;
double parameter = 0.;
bool parameterDone = false;
if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnit)))
{
occ::handle<StepBasic_ConversionBasedUnit> theCBU =
occ::down_cast<StepBasic_ConversionBasedUnit>(aUnit);
occ::handle<StepBasic_MeasureWithUnit> aMWU;
if (!theCBU.IsNull())
{
occ::handle<Standard_Transient> aConvFactor = theCBU->ConversionFactor();
if (aConvFactor->IsKind(STANDARD_TYPE(StepBasic_MeasureWithUnit)))
{
aMWU = occ::down_cast<StepBasic_MeasureWithUnit>(aConvFactor);
}
else if (aConvFactor->IsKind(STANDARD_TYPE(StepRepr_ReprItemAndMeasureWithUnit)))
{
occ::handle<StepRepr_ReprItemAndMeasureWithUnit> aReprMeasureItem =
occ::down_cast<StepRepr_ReprItemAndMeasureWithUnit>(aConvFactor);
aMWU = aReprMeasureItem->GetMeasureWithUnit();
}
// sln 8.10.2001: the case of unrecognized entity
if (aMWU.IsNull())
{
return -1;
}
occ::handle<StepBasic_NamedUnit> theTargetUnit = aMWU->UnitComponent().NamedUnit();
double theSIPFactor = 1.;
//: f5 abv 24 Apr 98: ProSTEP TR8 tr8_bv1_tc: INCHES
occ::handle<StepBasic_SiUnit> theSIU = occ::down_cast<StepBasic_SiUnit>(theTargetUnit);
if (!theSIU.IsNull())
{
if (theSIU->HasPrefix())
{
// Treat the prefix
StepBasic_SiPrefix aPrefix = theSIU->Prefix();
theSIPFactor = ConvertSiPrefix(aPrefix);
}
// Treat the SiUnitName
if (!SiUnitNameFactor(theSIU, theSIUNF))
{
status = 11; // et continue
}
}
else
{
return 3;
}
double theMVAL = aMWU->ValueComponent();
theFactor = theSIPFactor * theMVAL; // * theSIUNF * pow(10.,theLExp)
}
parameter = theFactor;
if (!parameterDone)
{
parameterDone = true;
}
else
{
status = 14;
}
}
else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnit)))
{
occ::handle<StepBasic_SiUnit> theSIU = occ::down_cast<StepBasic_SiUnit>(aUnit);
double theSIPFactor = 1.;
if (theSIU->HasPrefix())
{
// Treat the prefix
StepBasic_SiPrefix aPrefix = theSIU->Prefix();
theSIPFactor = ConvertSiPrefix(aPrefix);
}
// Treat the SiUnitName
if (!SiUnitNameFactor(theSIU, theSIUNF))
{
status = 11;
}
// final computation for lengthFactor
theFactor = theSIPFactor * theSIUNF;
parameter = theFactor;
if (!parameterDone)
{
parameterDone = true;
}
else
{
status = 14;
}
}
// Defining a type of unit
if (!parameterDone)
{
return 0;
}
const double aCascadeUnit = theLocalFactors.CascadeUnit();
if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndLengthUnit))
|| aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit)))
{
#ifdef METER
lengthFactor = parameter;
#else
lengthFactor = parameter * 1000. / aCascadeUnit;
#endif
if (!lengthDone)
{
lengthDone = true;
}
else
{
status = 14;
}
} // end of LengthUnit
else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndPlaneAngleUnit))
|| aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndPlaneAngleUnit)))
{
planeAngleFactor = parameter;
planeAngleDone = true;
} // end of PlaneAngleUnit
else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndSolidAngleUnit))
|| aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndSolidAngleUnit)))
{
solidAngleFactor = parameter;
solidAngleDone = true;
} // end of SolidAngleUnit
else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndAreaUnit))
|| aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndAreaUnit)))
{
double af;
#ifdef METER
af = parameter;
#else
af = parameter * 1000. / aCascadeUnit;
#endif
areaDone = true;
areaFactor = pow(af, 2);
}
else if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndVolumeUnit))
|| aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndVolumeUnit)))
{
double af;
#ifdef METER
af = parameter;
#else
af = parameter * 1000. / aCascadeUnit;
#endif
volumeDone = true;
volumeFactor = pow(af, 3);
}
return status;
}
//=================================================================================================
int STEPConstruct_UnitContext::ComputeTolerance(
const occ::handle<StepRepr_GlobalUncertaintyAssignedContext>& aContext)
{
int status = 0;
// Decode the Uncertainty information (geometric accuracy)
hasUncertainty = false;
int nbUncertainty = 0;
if (!aContext.IsNull())
{
nbUncertainty = aContext->NbUncertainty();
}
else
{
return 40;
}
for (int un = 1; un <= nbUncertainty; un++)
{
occ::handle<StepBasic_UncertaintyMeasureWithUnit> aUMWU = aContext->UncertaintyValue(un);
if (aUMWU.IsNull())
{
continue;
}
// Decode the associated Unit
occ::handle<StepBasic_SiUnitAndLengthUnit> aUnit =
occ::down_cast<StepBasic_SiUnitAndLengthUnit>(aUMWU->UnitComponent().NamedUnit());
if (!aUnit.IsNull())
{
// Extract Uncertainty value
double LengthUncertainty = aUMWU->ValueComponent();
// Update it according to the Length Unit Factor
// pdn r_47-sd.stp to choose minimal uncertainty
if (theUncertainty > LengthUncertainty)
{
theUncertainty = LengthUncertainty;
}
hasUncertainty = true;
}
else
{
occ::handle<StepBasic_ConversionBasedUnitAndLengthUnit> aCBULU =
occ::down_cast<StepBasic_ConversionBasedUnitAndLengthUnit>(
aUMWU->UnitComponent().NamedUnit());
if (!aCBULU.IsNull())
{
// Extract Uncertainty value
double LengthUncertainty = aUMWU->ValueComponent();
// Update it according to the Length Unit Factor
// pdn r_47-sd.stp to choose minimal uncertainty
// clang-format off
if(theUncertainty > LengthUncertainty) { theUncertainty = LengthUncertainty; // *lengthFactor; fait par appelant
}
// clang-format on
hasUncertainty = true;
}
}
}
return status;
}
//=================================================================================================
double STEPConstruct_UnitContext::LengthFactor() const
{
return lengthFactor;
}
//=================================================================================================
double STEPConstruct_UnitContext::PlaneAngleFactor() const
{
return planeAngleFactor;
}
//=================================================================================================
double STEPConstruct_UnitContext::SolidAngleFactor() const
{
return solidAngleFactor;
}
//=================================================================================================
double STEPConstruct_UnitContext::Uncertainty() const
{
return theUncertainty;
}
//=================================================================================================
bool STEPConstruct_UnitContext::HasUncertainty() const
{
return hasUncertainty;
}
//=================================================================================================
bool STEPConstruct_UnitContext::LengthDone() const
{
return lengthDone;
}
//=================================================================================================
bool STEPConstruct_UnitContext::PlaneAngleDone() const
{
return planeAngleDone;
}
//=================================================================================================
bool STEPConstruct_UnitContext::SolidAngleDone() const
{
return solidAngleDone;
}
//=================================================================================================
const char* STEPConstruct_UnitContext::StatusMessage(const int status) const
{
switch (status)
{
case 0:
return "";
case 1:
return "No GlobalUnitAssignedContext, default taken";
case 2:
return "No LengthMeasureWithUnit, default taken";
case 3:
return "No SiUnit for LengthMeasure undefined, default taken";
case 4:
return "No PlaneAngleMeasureWithUnit, default taken";
case 5:
return "No SiUnit for PlaneAngleMeasure undefined, default taken";
case 6:
return "No SolidAngleMeasureWithUnit, default taken";
case 7:
return "No SiUnit for SolidAngleMeasure undefined, default taken";
case 11:
return "Length Unit not recognized, default taken";
case 12:
return "Plane Angle Unit not recognized, default taken";
case 13:
return "Solid Angle Unit not recognized, default taken";
case 14:
return "At least one unit is twice defined";
case 40:
return "Bad GlobalUncertaintyAssignedContext, default unit taken";
default:
break;
}
return "Badly defined units, default taken";
}
double STEPConstruct_UnitContext::AreaFactor() const
{
return areaFactor;
}
double STEPConstruct_UnitContext::VolumeFactor() const
{
return volumeFactor;
}
bool STEPConstruct_UnitContext::AreaDone() const
{
return areaDone;
}
bool STEPConstruct_UnitContext::VolumeDone() const
{
return volumeDone;
}
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.