0031382: Data Exchange - BinXCAF should preserve length unit information IR-2021-08-20
authordpasukhi <dpasukhi@opencascade.com>
Tue, 10 Nov 2020 04:52:30 +0000 (07:52 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 20 Aug 2021 17:30:11 +0000 (20:30 +0300)
Possibility for adding LengthUnit info to XCAF document using special class XCAFDoc_LenghtUnit and XCAFDoc_LenghtUnitTool is implemented.
Package UnitsMethods is split: geom methods were placed to new file GeomConvert_Units which is in the toolkit TKXSBase, internal step scale factors was placed to StepData.
Updated UnitMethods to convert scale factor to different unit types.
Now, XSAlgo::XSAlgo_AlgoContainer is used to update unit info from static interface values.
New Draw command "XSetLengthUnit" and "XGetLengthUnit" for set or get XDE attribute.
Upgraded tests for STEP, IGES, OBJ, glTF, VRML formats to check area regressing with used unit.
Upgraded tests\de test cases to use any units in the "loop back" algorithms.

106 files changed:
src/AIS/AIS_Plane.cxx
src/BinMXCAFDoc/BinMXCAFDoc.cxx
src/BinMXCAFDoc/BinMXCAFDoc.hxx
src/BinMXCAFDoc/BinMXCAFDoc_LengthUnitDriver.cxx [new file with mode: 0644]
src/BinMXCAFDoc/BinMXCAFDoc_LengthUnitDriver.hxx [new file with mode: 0644]
src/BinMXCAFDoc/FILES
src/GeomConvert/FILES
src/GeomConvert/GeomConvert_Units.cxx [new file with mode: 0644]
src/GeomConvert/GeomConvert_Units.hxx [new file with mode: 0644]
src/GeomToStep/GeomToStep_MakeCartesianPoint.cxx
src/GeomToStep/GeomToStep_MakeCircle.cxx
src/GeomToStep/GeomToStep_MakeCircle_gen.pxx
src/GeomToStep/GeomToStep_MakeConicalSurface.cxx
src/GeomToStep/GeomToStep_MakeCylindricalSurface.cxx
src/GeomToStep/GeomToStep_MakeEllipse.cxx
src/GeomToStep/GeomToStep_MakeEllipse_gen.pxx
src/GeomToStep/GeomToStep_MakeHyperbola.cxx
src/GeomToStep/GeomToStep_MakeParabola.cxx
src/GeomToStep/GeomToStep_MakeRectangularTrimmedSurface.cxx
src/GeomToStep/GeomToStep_MakeSphericalSurface.cxx
src/GeomToStep/GeomToStep_MakeSurface.cxx
src/GeomToStep/GeomToStep_MakeToroidalSurface.cxx
src/GeomToStep/GeomToStep_MakeVector.cxx
src/IGESCAFControl/IGESCAFControl_Reader.cxx
src/IGESCAFControl/IGESCAFControl_Writer.cxx
src/IGESCAFControl/IGESCAFControl_Writer.hxx
src/IGESData/IGESData_BasicEditor.cxx
src/IGESData/IGESData_GlobalSection.cxx
src/IGESData/IGESData_GlobalSection.hxx
src/IGESData/IGESData_IGESModel.cxx
src/IGESData/IGESData_IGESModel.hxx
src/PrsDim/PrsDim_AngleDimension.cxx
src/PrsDim/PrsDim_Dimension.cxx
src/RWGltf/RWGltf_CafWriter.cxx
src/RWMesh/RWMesh_CafReader.cxx
src/RWMesh/RWMesh_CafReader.hxx
src/RWObj/RWObj_CafWriter.cxx
src/STEPCAFControl/STEPCAFControl_Reader.cxx
src/STEPCAFControl/STEPCAFControl_Reader.hxx
src/STEPCAFControl/STEPCAFControl_Writer.cxx
src/STEPCAFControl/STEPCAFControl_Writer.hxx
src/STEPConstruct/STEPConstruct_UnitContext.cxx
src/STEPControl/STEPControl_ActorRead.cxx
src/STEPControl/STEPControl_ActorWrite.cxx
src/STEPControl/STEPControl_Reader.cxx
src/STEPControl/STEPControl_Reader.hxx
src/STEPControl/STEPControl_Writer.cxx
src/ShapeAnalysis/ShapeAnalysis_Edge.cxx
src/StepData/FILES
src/StepData/StepData_GlobalFactors.cxx [new file with mode: 0644]
src/StepData/StepData_GlobalFactors.hxx [new file with mode: 0644]
src/StepData/StepData_StepModel.cxx
src/StepData/StepData_StepModel.hxx
src/StepFile/StepFile_ReadData.cxx
src/StepToGeom/StepToGeom.cxx
src/StepToTopoDS/StepToTopoDS_TranslateEdge.cxx
src/TKXSBase/PACKAGES
src/TKernel/PACKAGES
src/TopoDSToStep/TopoDSToStep_MakeStepFace.cxx
src/UnitsMethods/FILES
src/UnitsMethods/UnitsMethods.cxx
src/UnitsMethods/UnitsMethods.hxx
src/UnitsMethods/UnitsMethods_LengthUnit.hxx [new file with mode: 0644]
src/XCAFDoc/FILES
src/XCAFDoc/GUID.txt
src/XCAFDoc/XCAFDoc.cxx
src/XCAFDoc/XCAFDoc_DocumentTool.cxx
src/XCAFDoc/XCAFDoc_DocumentTool.hxx
src/XCAFDoc/XCAFDoc_LengthUnit.cxx [new file with mode: 0644]
src/XCAFDoc/XCAFDoc_LengthUnit.hxx [new file with mode: 0644]
src/XDEDRAW/XDEDRAW.cxx
src/XDEDRAW/XDEDRAW_Common.cxx
src/XDEDRAW/XDEDRAW_Shapes.cxx
src/XSAlgo/XSAlgo_AlgoContainer.cxx
src/XSDRAWSTEP/XSDRAWSTEP.cxx
src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx
src/XmlMXCAFDoc/FILES
src/XmlMXCAFDoc/XmlMXCAFDoc.cxx
src/XmlMXCAFDoc/XmlMXCAFDoc.hxx
src/XmlMXCAFDoc/XmlMXCAFDoc_LengthUnitDriver.cxx [new file with mode: 0644]
src/XmlMXCAFDoc/XmlMXCAFDoc_LengthUnitDriver.hxx [new file with mode: 0644]
tests/bugs/xde/bug22962
tests/bugs/xde/bug31382 [new file with mode: 0644]
tests/de/begin
tests/de/end
tests/de/iges_1/A2
tests/de/iges_1/B4
tests/de/iges_1/M9
tests/de/iges_2/H1
tests/de/step_1/E4
tests/de/step_1/J5
tests/de/step_1/O7
tests/de/step_2/A3
tests/de/step_2/M3
tests/de/step_2/Q2
tests/de/step_2/X1
tests/de/step_3/A5
tests/de/step_3/F2
tests/de/step_4/A5
tests/de/step_4/C9
tests/de/step_4/E3
tests/de/step_4/G6
tests/de/step_5/B2
tests/de_mesh/gltf_write/helmet
tests/de_mesh/obj_read/ship_boat
tests/de_mesh/obj_write/mustang

index fc1ac42..0a754b3 100644 (file)
@@ -50,7 +50,6 @@
 #include <TColgp_Array1OfPnt.hxx>
 #include <TColgp_HArray1OfPnt.hxx>
 #include <TCollection_AsciiString.hxx>
-#include <UnitsAPI.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(AIS_Plane,AIS_InteractiveObject)
 
index 3a2bac5..df49106 100644 (file)
@@ -23,6 +23,7 @@
 #include <BinMXCAFDoc_DatumDriver.hxx>
 #include <BinMXCAFDoc_DimTolDriver.hxx>
 #include <BinMXCAFDoc_GraphNodeDriver.hxx>
+#include <BinMXCAFDoc_LengthUnitDriver.hxx>
 #include <BinMXCAFDoc_LocationDriver.hxx>
 #include <BinMXCAFDoc_MaterialDriver.hxx>
 #include <BinMXCAFDoc_NoteDriver.hxx>
@@ -57,6 +58,7 @@ void BinMXCAFDoc::AddDrivers(const Handle(BinMDF_ADriverTable)& theDriverTable,
   }
   
   theDriverTable->AddDriver( aLocationDriver);
+  theDriverTable->AddDriver(new BinMXCAFDoc_LengthUnitDriver   (theMsgDrv));
   theDriverTable->AddDriver( new BinMXCAFDoc_AssemblyItemRefDriver(theMsgDrv));
   theDriverTable->AddDriver( new BinMXCAFDoc_DatumDriver       (theMsgDrv));
   theDriverTable->AddDriver( new BinMXCAFDoc_DimTolDriver      (theMsgDrv));
index 503c243..c72f853 100644 (file)
@@ -25,6 +25,7 @@ class Message_Messenger;
 class BinMXCAFDoc_CentroidDriver;
 class BinMXCAFDoc_ColorDriver;
 class BinMXCAFDoc_GraphNodeDriver;
+class BinMXCAFDoc_LengthUnitDriver;
 class BinMXCAFDoc_LocationDriver;
 class BinMXCAFDoc_DatumDriver;
 class BinMXCAFDoc_DimTolDriver;
@@ -59,6 +60,7 @@ private:
 friend class BinMXCAFDoc_CentroidDriver;
 friend class BinMXCAFDoc_ColorDriver;
 friend class BinMXCAFDoc_GraphNodeDriver;
+friend class BinMXCAFDoc_LengthUnitDriver;
 friend class BinMXCAFDoc_LocationDriver;
 friend class BinMXCAFDoc_DatumDriver;
 friend class BinMXCAFDoc_DimTolDriver;
diff --git a/src/BinMXCAFDoc/BinMXCAFDoc_LengthUnitDriver.cxx b/src/BinMXCAFDoc/BinMXCAFDoc_LengthUnitDriver.cxx
new file mode 100644 (file)
index 0000000..cff1481
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (c) 2021 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.
+
+#include <BinMXCAFDoc_LengthUnitDriver.hxx>
+#include <BinObjMgt_Persistent.hxx>
+#include <Message_Messenger.hxx>
+#include <Standard_Type.hxx>
+#include <TDF_Attribute.hxx>
+#include <XCAFDoc_LengthUnit.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(BinMXCAFDoc_LengthUnitDriver, BinMDF_ADriver)
+
+//=======================================================================
+//function : BinMXCAFDoc_LengthUnitDriver
+//purpose  : Constructor
+//=======================================================================
+BinMXCAFDoc_LengthUnitDriver::BinMXCAFDoc_LengthUnitDriver(const Handle(Message_Messenger)& theMsgDriver)
+     : BinMDF_ADriver(theMsgDriver, STANDARD_TYPE(XCAFDoc_LengthUnit)->Name()) {
+}
+
+//=======================================================================
+//function : NewEmpty
+//purpose  :
+//=======================================================================
+Handle(TDF_Attribute) BinMXCAFDoc_LengthUnitDriver::NewEmpty() const {
+  return new XCAFDoc_LengthUnit();
+}
+
+//=======================================================================
+//function : Paste
+//purpose  :
+//=======================================================================
+Standard_Boolean BinMXCAFDoc_LengthUnitDriver::Paste(const BinObjMgt_Persistent& theSource,
+                                                     const Handle(TDF_Attribute)& theTarget,
+                                                     BinObjMgt_RRelocationTable& theRelocTable) const 
+{
+  (void)theRelocTable;
+  Handle(XCAFDoc_LengthUnit) anAtt = Handle(XCAFDoc_LengthUnit)::DownCast(theTarget);
+  TCollection_AsciiString aName;
+  Standard_Real aScaleFactor = 1.;
+  Standard_Boolean isOk = theSource >> aName >> aScaleFactor;
+  if(isOk) {
+    anAtt->Set(aName, aScaleFactor);
+  }
+  return isOk;
+}
+
+//=======================================================================
+//function : Paste
+//purpose  :
+//=======================================================================
+void BinMXCAFDoc_LengthUnitDriver::Paste(const Handle(TDF_Attribute)& theSource,
+                                         BinObjMgt_Persistent& theTarget,
+                                         BinObjMgt_SRelocationTable& theRelocTable) const
+{
+  (void)theRelocTable;
+  Handle(XCAFDoc_LengthUnit) anAtt = Handle(XCAFDoc_LengthUnit)::DownCast(theSource);
+  theTarget << anAtt->GetUnitName() << anAtt->GetUnitValue();
+}
diff --git a/src/BinMXCAFDoc/BinMXCAFDoc_LengthUnitDriver.hxx b/src/BinMXCAFDoc/BinMXCAFDoc_LengthUnitDriver.hxx
new file mode 100644 (file)
index 0000000..9f1bd4d
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (c) 2021 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.
+
+#ifndef _BinMXCAFDoc_LengthUnitDriver_HeaderFile
+#define _BinMXCAFDoc_LengthUnitDriver_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+
+#include <BinMDF_ADriver.hxx>
+#include <Standard_Boolean.hxx>
+#include <BinObjMgt_RRelocationTable.hxx>
+#include <BinObjMgt_SRelocationTable.hxx>
+class Message_Messenger;
+class TDF_Attribute;
+class BinObjMgt_Persistent;
+
+
+class BinMXCAFDoc_LengthUnitDriver;
+DEFINE_STANDARD_HANDLE(BinMXCAFDoc_LengthUnitDriver, BinMDF_ADriver)
+
+//! Attribute Driver.
+class BinMXCAFDoc_LengthUnitDriver : public BinMDF_ADriver
+{
+
+public:
+
+  Standard_EXPORT BinMXCAFDoc_LengthUnitDriver(const Handle(Message_Messenger)& theMsgDriver);
+
+  Standard_EXPORT virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual Standard_Boolean Paste(const BinObjMgt_Persistent& theSource,
+                                                 const Handle(TDF_Attribute)& theTarget,
+                                                 BinObjMgt_RRelocationTable& theRelocTable) const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual void Paste(const Handle(TDF_Attribute)& theSource,
+                                     BinObjMgt_Persistent& theTarget,
+                                     BinObjMgt_SRelocationTable& theRelocTable) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT(BinMXCAFDoc_LengthUnitDriver, BinMDF_ADriver)
+
+};
+
+#endif // _BinMXCAFDoc_LengthUnitDriver_HeaderFile
index 93026d7..19026cc 100644 (file)
@@ -12,6 +12,8 @@ BinMXCAFDoc_DimTolDriver.cxx
 BinMXCAFDoc_DimTolDriver.hxx
 BinMXCAFDoc_GraphNodeDriver.cxx
 BinMXCAFDoc_GraphNodeDriver.hxx
+BinMXCAFDoc_LengthUnitDriver.cxx
+BinMXCAFDoc_LengthUnitDriver.hxx
 BinMXCAFDoc_LocationDriver.cxx
 BinMXCAFDoc_LocationDriver.hxx
 BinMXCAFDoc_MaterialDriver.cxx
index 0c583e2..029d1cb 100755 (executable)
@@ -18,3 +18,5 @@ GeomConvert_CompBezierSurfacesToBSplineSurface.hxx
 GeomConvert_CompBezierSurfacesToBSplineSurface.lxx
 GeomConvert_CompCurveToBSplineCurve.cxx
 GeomConvert_CompCurveToBSplineCurve.hxx
+GeomConvert_Units.cxx
+GeomConvert_Units.hxx
diff --git a/src/GeomConvert/GeomConvert_Units.cxx b/src/GeomConvert/GeomConvert_Units.cxx
new file mode 100644 (file)
index 0000000..a36ddcb
--- /dev/null
@@ -0,0 +1,317 @@
+// Copyright (c) 2021 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.
+
+#include <GeomConvert_Units.hxx>
+#include <Geom2d_BoundedCurve.hxx>
+#include <Geom2d_BSplineCurve.hxx>
+#include <Geom2d_Circle.hxx>
+#include <Geom2d_Conic.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2d_Ellipse.hxx>
+#include <Geom2d_Hyperbola.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_Parabola.hxx>
+#include <Geom2dConvert.hxx>
+#include <Geom_ConicalSurface.hxx>
+#include <Geom_CylindricalSurface.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_SurfaceOfRevolution.hxx>
+#include <Geom_ToroidalSurface.hxx>
+#include <gp.hxx>
+#include <gp_Dir2d.hxx>
+#include <gp_GTrsf2d.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Trsf2d.hxx>
+
+// ============================================================================
+// Method : RadianToDegree
+// Purpose:
+// ============================================================================
+Handle(Geom2d_Curve) GeomConvert_Units::RadianToDegree(
+  const Handle(Geom2d_Curve)  & theCurve2d,
+  const Handle(Geom_Surface)  & theSurf,
+  const Standard_Real theLengthFactor,
+  const Standard_Real theFactorRadianDegree)
+{
+  Handle(Geom2d_Curve) aCurve2d = Handle(Geom2d_Curve)::DownCast(theCurve2d->Copy());
+  Standard_Real uFact = 1.;
+  Standard_Real vFact = 1.;
+  Standard_Real LengthFact = 1. / theLengthFactor;
+  Standard_Real AngleFact = theFactorRadianDegree;    // 180./PI;  pilotable
+
+  gp_Pnt2d    Pt1;
+  gp_XY       pXY;
+  gp_GTrsf2d  tMatu, tMatv;
+
+  //  theSurf is a CylindricalSurface or a ConicalSurface or
+  //             a ToroidalSurface or a SphericalSurface or
+  //             a SurfaceOfRevolution
+  if (theSurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) || theSurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))
+  {
+    uFact = vFact = AngleFact;
+  }
+  else if (theSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
+  {
+    uFact = AngleFact;
+    vFact = LengthFact;
+  }
+  else if (theSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)))
+  {
+    uFact = AngleFact;
+  }
+  else if (theSurf->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))
+  {
+    Handle(Geom_ConicalSurface) conicS = Handle(Geom_ConicalSurface)::DownCast(theSurf);
+    Standard_Real semAng = conicS->SemiAngle();
+    uFact = AngleFact;
+    vFact = LengthFact * Cos(semAng);
+  }
+  else if (theSurf->IsKind(STANDARD_TYPE(Geom_Plane)))
+  {
+    uFact = vFact = LengthFact;
+    if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) || aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse)))
+    {
+      gp_Trsf2d aT;
+      aT.SetScale(gp::Origin2d(), LengthFact);
+      aCurve2d->Transform(aT);
+      return aCurve2d;
+    }
+  }
+  else {
+    return aCurve2d;
+  }
+
+  if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line)))
+  {
+    Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aCurve2d);
+    gp_Pnt2d myLoc = aLine2d->Location();
+    gp_Dir2d myDir = aLine2d->Direction();
+    gp_Pnt2d myNewLoc;
+    myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
+    gp_Dir2d myNewDir;
+    myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
+    Handle(Geom2d_Line) myNewLine2d = Handle(Geom2d_Line)::DownCast(aLine2d->Copy());
+    myNewLine2d->SetLocation(myNewLoc);
+    myNewLine2d->SetDirection(myNewDir);
+    return myNewLine2d;
+  }
+  else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Conic)))
+  {
+    if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) || aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse)))
+    {
+      Handle(Geom2d_BSplineCurve) aBSpline2d = Geom2dConvert::CurveToBSplineCurve(aCurve2d);
+      aCurve2d = aBSpline2d;
+    }
+    else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Parabola)))
+    {
+#ifdef OCCT_DEBUG
+      std::cout << "PCURVE of Parabola type in U or V Periodic Surface" << std::endl;
+      std::cout << "Parameters Not transformed to Degree" << std::endl;
+#endif
+    }
+    else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Hyperbola)))
+    {
+#ifdef OCCT_DEBUG
+      std::cout << "PCURVE of Hyperbola type in U or V Periodic Surface" << std::endl;
+      std::cout << "Parameters Not transformed to Degree" << std::endl;
+#endif
+    }
+  }
+
+  // Compute affinity
+  tMatu.SetAffinity(gp::OY2d(), uFact);
+  tMatv.SetAffinity(gp::OX2d(), vFact);
+  if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)))
+  {
+    if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)))
+    {
+      Handle(Geom2d_BSplineCurve) aBSpline2d =
+        Handle(Geom2d_BSplineCurve)::DownCast(aCurve2d);
+      Handle(Geom2d_BSplineCurve) myNewBSpline2d =
+        Handle(Geom2d_BSplineCurve)::DownCast(aBSpline2d->Copy());
+      Standard_Integer nbPol = aBSpline2d->NbPoles();
+      for (Standard_Integer i = 1; i <= nbPol; i++)
+      {
+        pXY = aBSpline2d->Pole(i).XY();
+        tMatu.Transforms(pXY);
+        tMatv.Transforms(pXY);
+        Pt1.SetXY(pXY);
+        myNewBSpline2d->SetPole(i, Pt1);
+      }
+      return myNewBSpline2d;
+    }
+    else {
+#ifdef OCCT_DEBUG
+      std::cout << "PCURVE of Other Types of Bounded Curve in U or V Periodic Surface" << std::endl;
+      std::cout << "Parameters Not transformed to Degree" << std::endl;
+#endif
+    }
+  }
+  return aCurve2d;
+}
+
+// ============================================================================
+// Method : DegreeToRadian
+// Purpose: 1. Change definition of the pcurves according to LengthFactor                  
+//          2. STEP cylinder, torus, cone and sphere are parametrized
+//             from 0 to 360 degree
+//             Then pcurves parameter have to be transformed 
+//             from DEGREE to RADIAN
+// ============================================================================
+Handle(Geom2d_Curve) GeomConvert_Units::DegreeToRadian(
+  const Handle(Geom2d_Curve) & thePcurve,
+  const Handle(Geom_Surface) & theSurface,
+  const Standard_Real theLengthFactor,
+  const Standard_Real theFactorRadianDegree)
+{
+  Handle(Geom2d_Curve)  aPcurve = Handle(Geom2d_Curve)::DownCast(thePcurve->Copy());
+  Standard_Real uFact = 1.;
+  Standard_Real vFact = 1.;
+  Standard_Real LengthFact = theLengthFactor;
+  Standard_Real AngleFact = theFactorRadianDegree;  // PI/180.;  pilotable
+
+  gp_Pnt2d    Pt1;
+  gp_XY       pXY;
+  gp_GTrsf2d  tMatu, tMatv;
+
+  // What to change ??
+
+  if (theSurface->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
+    theSurface->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))
+  {
+    uFact = vFact = AngleFact;
+  }
+  else if (theSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
+  {
+    uFact = AngleFact;
+    vFact = LengthFact;
+  }
+  else if (theSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)))
+  {
+    uFact = AngleFact;
+  }
+  else if (theSurface->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))
+  {
+    Handle(Geom_ConicalSurface) conicS = Handle(Geom_ConicalSurface)::DownCast(theSurface);
+    Standard_Real semAng = conicS->SemiAngle();
+    uFact = AngleFact;
+    vFact = LengthFact / Cos(semAng);
+  }
+  else if (theSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
+  {
+    uFact = vFact = LengthFact;
+    if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) || aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse)))
+    {
+      gp_Trsf2d aT;
+      aT.SetScale(gp::Origin2d(), LengthFact);
+      aPcurve->Transform(aT);
+      return aPcurve;
+    }
+  }
+  else
+  {
+    return aPcurve;
+  }
+
+  if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Conic)))
+  {
+    if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) || aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse)))
+    {
+      Handle(Geom2d_BSplineCurve) aBSpline2d = Geom2dConvert::CurveToBSplineCurve(aPcurve);
+      aPcurve = aBSpline2d;
+    }
+    else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Parabola)))
+    {
+#ifdef OCCT_DEBUG
+      std::cout << "PCURVE of Parabola type" << std::endl;
+      std::cout << "Parameters Not Yet transformed according to LengthUnit" << std::endl;
+#endif
+      return aPcurve;
+    }
+    else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Hyperbola)))
+    {
+#ifdef OCCT_DEBUG
+      std::cout << "PCURVE of Hyperbola type" << std::endl;
+      std::cout << "Parameters Not Yet transformed according to LengthUnit" << std::endl;
+#endif
+      return aPcurve;
+    }
+  }
+
+  // Compute affinity
+
+  tMatu.SetAffinity(gp::OY2d(), uFact);
+  tMatv.SetAffinity(gp::OX2d(), vFact);
+
+  if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Line)))
+  {
+    Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aPcurve);
+
+    gp_Pnt2d myLoc = aLine2d->Location();
+    gp_Dir2d myDir = aLine2d->Direction();
+
+    gp_Pnt2d myNewLoc;
+    myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
+
+    gp_Dir2d myNewDir;
+    myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
+
+    aLine2d->SetLocation(myNewLoc);
+    aLine2d->SetDirection(myNewDir);
+
+    aPcurve = aLine2d;
+  }
+  else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)))
+  {
+    Handle(Geom2d_BSplineCurve) aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(aPcurve);
+
+    // transform the Poles of the BSplineCurve according to AngleFact and LengthFact
+
+    Standard_Integer nbPol = aBSpline2d->NbPoles();
+    for (Standard_Integer i = 1; i <= nbPol; i++)
+    {
+      pXY = aBSpline2d->Pole(i).XY();
+      tMatu.Transforms(pXY);
+      tMatv.Transforms(pXY);
+      Pt1.SetXY(pXY);
+      aBSpline2d->SetPole(i, Pt1);
+    }
+    aPcurve = aBSpline2d;
+  }
+  else
+  {
+#ifdef OCCT_DEBUG
+    std::cout << "DegreeToRadian : Type " << aPcurve->DynamicType();
+    std::cout << " not yet implemented" << std::endl;
+#endif
+  }
+  return aPcurve;
+}
+
+// ============================================================================
+// Method : MirrorPCurve
+// Purpose:
+// ============================================================================
+Handle(Geom2d_Curve) GeomConvert_Units::MirrorPCurve(const Handle(Geom2d_Curve) & theCurve)
+{
+  Handle(Geom2d_Curve) theMirrored = Handle(Geom2d_Curve)::DownCast(theCurve->Copy());
+  gp_Trsf2d T;
+  gp_Pnt2d  Loc(0., 0.);
+  gp_Dir2d  Dir(1., 0.);
+  gp_Ax2d   ax2(Loc, Dir);
+  T.SetMirror(ax2);
+  theMirrored->Transform(T);
+  return theMirrored;
+}
diff --git a/src/GeomConvert/GeomConvert_Units.hxx b/src/GeomConvert/GeomConvert_Units.hxx
new file mode 100644 (file)
index 0000000..49e7296
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (c) 2021 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.
+
+#ifndef _GeomConvert_Units_HeaderFile
+#define _GeomConvert_Units_HeaderFile
+
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+class Geom2d_Curve;
+class Geom_Surface;
+
+//! Class contains conversion methods for 2d geom objects
+class GeomConvert_Units
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  //! Convert 2d curve for change angle unit from radian to degree 
+  Standard_EXPORT static Handle(Geom2d_Curve) RadianToDegree(
+    const Handle(Geom2d_Curve)& theCurve,
+    const Handle(Geom_Surface)& theSurface,
+    const Standard_Real theLengthFactor,
+    const Standard_Real theFactorRadianDegree);
+  
+  //! Convert 2d curve for change angle unit from degree to radian
+  Standard_EXPORT static Handle(Geom2d_Curve) DegreeToRadian(
+    const Handle(Geom2d_Curve)& theCurve,
+    const Handle(Geom_Surface)& theSurface,
+    const Standard_Real theLengthFactor,
+    const Standard_Real theFactorRadianDegree);
+  
+  //! return 2d curve as 'mirror' for given
+  Standard_EXPORT static Handle(Geom2d_Curve) MirrorPCurve(const Handle(Geom2d_Curve)& theCurve);
+  
+};
+
+#endif // _GeomConvert_Units_HeaderFile
index b6a34ee..10f3f94 100644 (file)
 #include <gp_Pnt.hxx>
 #include <gp_Pnt2d.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_CartesianPoint.hxx>
 #include <TCollection_HAsciiString.hxx>
 #include <TColStd_HArray1OfReal.hxx>
-#include <UnitsMethods.hxx>
 
 //=============================================================================
 // Creation d' un cartesian_point de prostep a partir d' un point3d de gp
@@ -42,7 +42,7 @@ GeomToStep_MakeCartesianPoint::GeomToStep_MakeCartesianPoint( const gp_Pnt& P)
 //  Pstep->SetCoordinates(Acoord);
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
 //  Pstep->SetName(name);
-  Standard_Real fact = UnitsMethods::LengthFactor();
+  Standard_Real fact = StepData_GlobalFactors::Intance().LengthFactor();
   Pstep->Init3D (name,X/fact,Y/fact,Z/fact);
   theCartesianPoint = Pstep;
   done = Standard_True;
@@ -87,7 +87,7 @@ GeomToStep_MakeCartesianPoint::
 //  Pstep->SetCoordinates(Acoord);
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
 //  Pstep->SetName(name);
-  Standard_Real fact = UnitsMethods::LengthFactor();
+  Standard_Real fact = StepData_GlobalFactors::Intance().LengthFactor();
   Pstep->Init3D (name,X/fact,Y/fact,Z/fact);
   theCartesianPoint = Pstep;
   done = Standard_True;
index fbd842f..d76adaf 100644 (file)
 #include <gp_Circ.hxx>
 #include <gp_Circ2d.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_Axis2Placement2d.hxx>
 #include <StepGeom_Axis2Placement3d.hxx>
 #include <StepGeom_Circle.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
 
 //=============================================================================
 // Creation d' un cercle de prostep a partir d' un cercle 3d de gp
index a067669..5c22197 100644 (file)
@@ -24,7 +24,7 @@ Handle(StepGeom_Circle) CStep = new StepGeom_Circle;
   Rayon = C.Radius();
   Ax2.SetValue(Ax2Step);
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
-  CStep->Init(name, Ax2, Rayon / UnitsMethods::LengthFactor());
+  CStep->Init(name, Ax2, Rayon / StepData_GlobalFactors::Intance().LengthFactor());
   theCircle = CStep;
   done = Standard_True;
 
index 5f006cf..a8c42bf 100644 (file)
 #include <GeomToStep_MakeConicalSurface.hxx>
 #include <Standard_DomainError.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_Axis2Placement3d.hxx>
 #include <StepGeom_ConicalSurface.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
 
 //=============================================================================
 // Creation d' une conical_surface de prostep a partir d' une ConicalSurface
@@ -46,7 +46,7 @@ GeomToStep_MakeConicalSurface::GeomToStep_MakeConicalSurface
   }
   
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
-  CSstep->Init(name, aPosition, aRadius / UnitsMethods::LengthFactor(), aSemiAngle);
+  CSstep->Init(name, aPosition, aRadius / StepData_GlobalFactors::Intance().LengthFactor(), aSemiAngle);
   theConicalSurface = CSstep;
   done = Standard_True;
 }
index df3c1a2..08c4fb0 100644 (file)
 #include <GeomToStep_MakeAxis2Placement3d.hxx>
 #include <GeomToStep_MakeCylindricalSurface.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_Axis2Placement3d.hxx>
 #include <StepGeom_CylindricalSurface.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
 
 //=============================================================================
 // Creation d' une conical_surface de prostep a partir d' une 
@@ -41,7 +41,7 @@ GeomToStep_MakeCylindricalSurface::GeomToStep_MakeCylindricalSurface
   aRadius = CS->Radius();
   CSstep = new StepGeom_CylindricalSurface;
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
-  CSstep->Init(name, aPosition, aRadius / UnitsMethods::LengthFactor());
+  CSstep->Init(name, aPosition, aRadius / StepData_GlobalFactors::Intance().LengthFactor());
   theCylindricalSurface = CSstep;
   done = Standard_True;
 }
index 9344121..34794fa 100644 (file)
 #include <gp_Elips.hxx>
 #include <gp_Elips2d.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_Axis2Placement2d.hxx>
 #include <StepGeom_Axis2Placement3d.hxx>
 #include <StepGeom_Ellipse.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
 
 //=============================================================================
 // Creation d'une ellipse de prostep a partir d'une ellipse 3d de gp
index 883e58e..38adf96 100644 (file)
@@ -25,7 +25,7 @@ Handle(StepGeom_Ellipse) EStep = new StepGeom_Ellipse;
   minorR = E.MinorRadius();
   Ax2.SetValue(Ax2Step);
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
-  Standard_Real fact = UnitsMethods::LengthFactor();
+  Standard_Real fact = StepData_GlobalFactors::Intance().LengthFactor();
   EStep->Init(name, Ax2,majorR/fact,minorR/fact);
   theEllipse = EStep;
   done = Standard_True;
index e5a431a..b0247d8 100644 (file)
 #include <gp_Hypr.hxx>
 #include <gp_Hypr2d.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_Axis2Placement2d.hxx>
 #include <StepGeom_Axis2Placement3d.hxx>
 #include <StepGeom_Hyperbola.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
 
 //=============================================================================
 // Creation d'une hyperbola de prostep a partir d'une hyperbola de
@@ -72,7 +72,7 @@ GeomToStep_MakeHyperbola::GeomToStep_MakeHyperbola(const Handle(Geom2d_Hyperbola
   minorR = gpHyp.MinorRadius();
   Ax2.SetValue(Ax2Step);
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
-  Standard_Real fact = UnitsMethods::LengthFactor();
+  Standard_Real fact = StepData_GlobalFactors::Intance().LengthFactor();
   HStep->Init(name, Ax2,majorR/fact,minorR/fact);
   theHyperbola = HStep;
   done = Standard_True;
index a1053d0..3650201 100644 (file)
 #include <gp_Parab.hxx>
 #include <gp_Parab2d.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_Axis2Placement2d.hxx>
 #include <StepGeom_Axis2Placement3d.hxx>
 #include <StepGeom_Parabola.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
 
 //=============================================================================
 // Creation d'une Parabola de prostep a partir d'une Parabola de
@@ -70,7 +70,7 @@ GeomToStep_MakeParabola::GeomToStep_MakeParabola(const Handle(Geom2d_Parabola)&
   focal = gpPar.Focal();
   Ax2.SetValue(Ax2Step);
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
-  PStep->Init(name, Ax2, focal / UnitsMethods::LengthFactor());
+  PStep->Init(name, Ax2, focal / StepData_GlobalFactors::Intance().LengthFactor());
   theParabola = PStep;
   done = Standard_True;
 }
index 2f708a2..9d7bca0 100644 (file)
 #include <GeomToStep_MakeRectangularTrimmedSurface.hxx>
 #include <GeomToStep_MakeSurface.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_RectangularTrimmedSurface.hxx>
 #include <StepGeom_Surface.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
 
 //=============================================================================
 // Creation d' une rectangular_trimmed_surface de STEP
@@ -61,7 +61,7 @@ GeomToStep_MakeRectangularTrimmedSurface::
   Standard_Real AngleFact = 180./M_PI;
   Standard_Real uFact = 1.;
   Standard_Real vFact = 1.;
-  Standard_Real LengthFact  = UnitsMethods::LengthFactor();
+  Standard_Real LengthFact  = StepData_GlobalFactors::Intance().LengthFactor();
   Handle(Geom_Surface) theSurf = RTSurf->BasisSurface();
   if (theSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
     uFact = AngleFact;
index d1bcc26..404b5e4 100644 (file)
@@ -22,7 +22,7 @@
 #include <StepGeom_Axis2Placement3d.hxx>
 #include <StepGeom_SphericalSurface.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
+#include <StepData_GlobalFactors.hxx>
 
 //=============================================================================
 // Creation d' une conical_surface de prostep a partir d' une SphericalSurface
@@ -41,7 +41,7 @@ GeomToStep_MakeSphericalSurface::GeomToStep_MakeSphericalSurface
   aRadius = S->Radius();
   Surf = new StepGeom_SphericalSurface;
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
-  Surf->Init(name, aPosition, aRadius/UnitsMethods::LengthFactor());
+  Surf->Init(name, aPosition, aRadius/ StepData_GlobalFactors::Intance().LengthFactor());
   theSphericalSurface = Surf;
   done = Standard_True;
 }
index 5400de3..30477d7 100644 (file)
@@ -32,7 +32,7 @@
 #include <StepGeom_Surface.hxx>
 #include <StepGeom_SweptSurface.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
+#include <StepData_GlobalFactors.hxx>
 
 //=============================================================================
 // Creation d' une Surface de prostep a partir d' une Surface de Geom
@@ -66,7 +66,7 @@ GeomToStep_MakeSurface::GeomToStep_MakeSurface ( const Handle(Geom_Surface)& S)
     if (!done) return;
     Handle(StepGeom_OffsetSurface) Surf = new StepGeom_OffsetSurface;
     Surf->Init (new TCollection_HAsciiString(""),
-                    MkBasis.Value(),S1->Offset()/UnitsMethods::LengthFactor(),StepData_LFalse);
+                    MkBasis.Value(),S1->Offset()/ StepData_GlobalFactors::Intance().LengthFactor(),StepData_LFalse);
     theSurface = Surf;
   }
   else {
index 8809d9e..08d6466 100644 (file)
@@ -21,7 +21,7 @@
 #include <StdFail_NotDone.hxx>
 #include <StepGeom_ToroidalSurface.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
+#include <StepData_GlobalFactors.hxx>
 
 //=============================================================================
 // Creation d' une toroidal_surface de prostep a partir d' une ToroidalSurface
@@ -41,7 +41,7 @@ GeomToStep_MakeToroidalSurface::GeomToStep_MakeToroidalSurface
   aMinorRadius = S->MinorRadius();
   Surf = new StepGeom_ToroidalSurface;
   Handle(TCollection_HAsciiString) name = new TCollection_HAsciiString("");
-  Standard_Real fact = UnitsMethods::LengthFactor();
+  Standard_Real fact = StepData_GlobalFactors::Intance().LengthFactor();
   Surf->Init(name, aPosition, aMajorRadius/fact, aMinorRadius/fact);
   theToroidalSurface = Surf;
   done = Standard_True;
index 6ee9376..85729b1 100644 (file)
@@ -24,9 +24,9 @@
 #include <gp_Vec.hxx>
 #include <gp_Vec2d.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_Vector.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
 
 //=============================================================================
 // Creation d' un vector de prostep a partir d' un Vec de gp
@@ -34,7 +34,7 @@
 GeomToStep_MakeVector::GeomToStep_MakeVector( const gp_Vec& V)
 {
   gp_Dir D = gp_Dir(V);
-  Standard_Real lFactor = UnitsMethods::LengthFactor();
+  Standard_Real lFactor = StepData_GlobalFactors::Intance().LengthFactor();
 #include "GeomToStep_MakeVector_gen.pxx"
 }
 //=============================================================================
@@ -58,7 +58,7 @@ GeomToStep_MakeVector::GeomToStep_MakeVector ( const Handle(Geom_Vector)&
   gp_Vec V;
   V = GVector->Vec();
   gp_Dir D = gp_Dir(V);
-  Standard_Real lFactor = UnitsMethods::LengthFactor();
+  Standard_Real lFactor = StepData_GlobalFactors::Intance().LengthFactor();
 #include "GeomToStep_MakeVector_gen.pxx"
 }
 
index 86e71e6..649fdfa 100644 (file)
@@ -19,6 +19,7 @@
 #include <IGESCAFControl.hxx>
 #include <IGESCAFControl_Reader.hxx>
 #include <IGESData_IGESEntity.hxx>
+#include <IGESData_IGESModel.hxx>
 #include <IGESData_LevelListEntity.hxx>
 #include <IGESGraph_Color.hxx>
 #include <Interface_InterfaceModel.hxx>
 #include <XCAFDoc_LayerTool.hxx>
 #include <XCAFDoc_ShapeMapTool.hxx>
 #include <XCAFDoc_ShapeTool.hxx>
+#include <XSAlgo.hxx>
+#include <XSAlgo_AlgoContainer.hxx>
 #include <XSControl_TransferReader.hxx>
 #include <XSControl_WorkSession.hxx>
+#include <UnitsMethods.hxx>
 
 //=======================================================================
 //function : checkColorRange
@@ -157,6 +161,19 @@ Standard_Boolean IGESCAFControl_Reader::Transfer (Handle(TDocStd_Document) &doc,
   //  TransferOneRoot ( i );
   //}
   
+  // set units
+  Handle(IGESData_IGESModel) aModel = Handle(IGESData_IGESModel)::DownCast(WS()->Model());
+
+  Standard_Real aScaleFactorMM = 1.;
+  if (!XCAFDoc_DocumentTool::GetLengthUnit(doc, aScaleFactorMM, UnitsMethods_LengthUnit_Millimeter))
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    aScaleFactorMM = UnitsMethods::GetCasCadeLengthUnit();
+    // set length unit to the document
+    XCAFDoc_DocumentTool::SetLengthUnit(doc, aScaleFactorMM, UnitsMethods_LengthUnit_Millimeter);
+  }
+  aModel->ChangeGlobalSection().SetCascadeUnit(aScaleFactorMM);
+
   TransferRoots(theProgress); // replaces the above
   num = NbShapes();
   if ( num <=0 ) return Standard_False;
@@ -178,7 +195,6 @@ Standard_Boolean IGESCAFControl_Reader::Transfer (Handle(TDocStd_Document) &doc,
   }
   
   // added by skl 13.10.2003
-  const Handle(Interface_InterfaceModel) &Model = WS()->Model();
   const Handle(XSControl_TransferReader) &TR = WS()->TransferReader();
   const Handle(Transfer_TransientProcess) &TP = TR->TransientProcess();
   Standard_Boolean IsCTool = Standard_True;
@@ -188,9 +204,9 @@ Standard_Boolean IGESCAFControl_Reader::Transfer (Handle(TDocStd_Document) &doc,
   Handle(XCAFDoc_LayerTool) LTool = XCAFDoc_DocumentTool::LayerTool(doc->Main());
   if(LTool.IsNull()) IsLTool = Standard_False;
 
-  Standard_Integer nb = Model->NbEntities();
+  Standard_Integer nb = aModel->NbEntities();
   for(i=1; i<=nb; i++) {
-    Handle(IGESData_IGESEntity) ent = Handle(IGESData_IGESEntity)::DownCast ( Model->Value(i) );
+    Handle(IGESData_IGESEntity) ent = Handle(IGESData_IGESEntity)::DownCast (aModel->Value(i) );
     if ( ent.IsNull() ) continue;
     Handle(Transfer_Binder) binder = TP->Find ( ent );
     if ( binder.IsNull() ) continue;
@@ -324,8 +340,6 @@ Standard_Boolean IGESCAFControl_Reader::Transfer (Handle(TDocStd_Document) &doc,
 
   CTool->ReverseChainsOfTreeNodes();
 
-  // end added by skl 13.10.2003
-
   // Update assembly compounds
   STool->UpdateAssemblies();
 
index 81802e8..819420a 100644 (file)
 #include <XCAFDoc_ColorTool.hxx>
 #include <XCAFDoc_DocumentTool.hxx>
 #include <XCAFDoc_LayerTool.hxx>
+#include <XCAFDoc_LengthUnit.hxx>
 #include <XCAFDoc_ShapeTool.hxx>
 #include <XCAFPrs.hxx>
 #include <XCAFPrs_Style.hxx>
+#include <XSAlgo.hxx>
+#include <XSAlgo_AlgoContainer.hxx>
 #include <XSControl_WorkSession.hxx>
+#include <UnitsMethods.hxx>
 
 namespace
 {
@@ -177,6 +181,7 @@ Standard_Boolean IGESCAFControl_Writer::Transfer (const TDF_LabelSequence& label
                                                   const Message_ProgressRange& theProgress)
 {  
   if ( labels.Length() <=0 ) return Standard_False;
+  prepareUnit(labels.First()); // set local length unit to the model
   Message_ProgressScope aPS(theProgress, "Labels", labels.Length());
   for ( Standard_Integer i=1; i <= labels.Length() && aPS.More(); i++ )
   {
@@ -561,6 +566,25 @@ Standard_Boolean IGESCAFControl_Writer::WriteNames (const TDF_LabelSequence& the
   return Standard_True;
 }
 
+//=======================================================================
+//function : prepareUnit
+//purpose  :
+//=======================================================================
+void IGESCAFControl_Writer::prepareUnit(const TDF_Label& theLabel)
+{
+  Handle(XCAFDoc_LengthUnit) aLengthAttr;
+  if (!theLabel.IsNull() &&
+    theLabel.Root().FindAttribute(XCAFDoc_LengthUnit::GetID(), aLengthAttr))
+  {
+    Model()->ChangeGlobalSection().SetCascadeUnit(aLengthAttr->GetUnitValue() * 1000);
+  }
+  else
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    Model()->ChangeGlobalSection().SetCascadeUnit(UnitsMethods::GetCasCadeLengthUnit());
+  }
+}
+
 //=======================================================================
 //function : SetColorMode
 //purpose  : 
index 24a953d..b5d31f6 100644 (file)
@@ -124,7 +124,10 @@ protected:
   //! to IGES entity
   Standard_EXPORT Standard_Boolean WriteNames (const TDF_LabelSequence& labels);
 
-
+  //! Finds length units located in root of label
+  //! If it exists, initializes local length unit from it
+  //! Else initializes according to Cascade length unit
+  Standard_EXPORT void prepareUnit(const TDF_Label& theLabel);
 
 
 private:
index 5226ac9..28b1b56 100644 (file)
@@ -34,7 +34,6 @@
 #include <Interface_Static.hxx>
 #include <TCollection_HAsciiString.hxx>
 #include <TColStd_Array1OfInteger.hxx>
-#include <UnitsMethods.hxx>
 
 IGESData_BasicEditor::IGESData_BasicEditor(const Handle(IGESData_Protocol)&  protocol)
 {
@@ -92,7 +91,7 @@ void IGESData_BasicEditor::Init (const Handle(IGESData_IGESModel)& model, const
   (const Standard_Real val)
 {
   if (val <= 0.) return Standard_False;
-  Standard_Real vmm = val * UnitsMethods::GetCasCadeLengthUnit(); //abv 20 Feb 00: adding cascade unit factor
+  Standard_Real vmm = val * themodel->GlobalSection().CascadeUnit();
   //#73 rln 10.03.99 S4135: "read.scale.unit" does not affect GlobalSection
   //if (Interface_Static::IVal("read.scale.unit") == 1) vmm = vmm * 1000.;
 // vmm est exprime en MILLIMETRES
@@ -358,20 +357,19 @@ Standard_Integer IGESData_BasicEditor::UnitNameFlag  (const Standard_CString nam
 Standard_Real IGESData_BasicEditor::UnitFlagValue (const Standard_Integer flag)
 {
   switch (flag) {
-    case  1 : return 0.0254;
-    case  2 : return 0.001;
-    case  3 : return 1.;
-    case  4 : return 0.3048;
-    case  5 : return 1609.27;
-    case  6 : return 1.;
-    case  7 : return 1000.;
-    case  8 : return 0.0000254;
-    case  9 : return 0.000001;
-    case 10 : return 0.01;
-    case 11 : return 0.0000000254;
-    default : break;
+    case  1: return 25.4; // inch
+    case  2: return 1.; // millimeter
+    case  3: return 1.;
+    case  4: return 304.8; // foot
+    case  5: return 1609344.; // mile
+    case  6: return 1000.; // meter
+    case  7: return 1000000.; // kilometer
+    case  8: return 0.0254; // mil (0.001 inch)
+    case  9: return 0.001; // micron
+    case 10: return 10.; // centimeter
+    case 11: return 0.0000254; // microinch
+    default: return 0.;
   }
-  return 0.;
 }
 
 Standard_CString IGESData_BasicEditor::UnitFlagName (const Standard_Integer flag)
index 3b8f698..dfcb3aa 100644 (file)
@@ -26,6 +26,8 @@
 #include <OSD_Process.hxx>
 #include <Quantity_Date.hxx>
 #include <TCollection_HAsciiString.hxx>
+#include <XSAlgo.hxx>
+#include <XSAlgo_AlgoContainer.hxx>
 #include <UnitsMethods.hxx>
 
 #include <stdio.h>
@@ -66,6 +68,7 @@ IGESData_GlobalSection::IGESData_GlobalSection()
   theMaxPower10Double (308),
   theMaxDigitsDouble  (15),
   theScale            (1.0),
+  theCascadeUnit      (1.0),
   theUnitFlag         (0),
   theLineWeightGrad   (1),
   theMaxLineWeight    (0.0),
@@ -115,7 +118,7 @@ void IGESData_GlobalSection::Init(const Handle(Interface_ParamSet)& params,
   //Message_Msg Msg48 ("XSTEP_48");
   //Message_Msg Msg49 ("XSTEP_49");
   //======================================
-
+  XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
   theSeparator = ',';       theEndMark = ';';
   theSendName.Nullify();    theFileName.Nullify();  theSystemId.Nullify();
   theInterfaceVersion.Nullify();
@@ -131,6 +134,7 @@ void IGESData_GlobalSection::Init(const Handle(Interface_ParamSet)& params,
   theAuthorName.Nullify();  theCompanyName.Nullify();
   theIGESVersion       = 11;//3 //#66 rln Setting IGES 5.3 by default(To avoid misleading fails below)
   theDraftingStandard  = 0;
+  theCascadeUnit       = UnitsMethods::GetCasCadeLengthUnit();
   theLastChangeDate.Nullify();  // nouveaute 5.1 (peut etre absente)
   theAppliProtocol.Nullify();   // nouveaute 5.3 (peut etre absente)
 
@@ -528,6 +532,15 @@ Standard_Real IGESData_GlobalSection::Scale () const
 }
 
 
+//=======================================================================
+//function : CascadeUnit
+//purpose  :
+//=======================================================================
+Standard_Real IGESData_GlobalSection::CascadeUnit() const
+{
+  return theCascadeUnit;
+}
+
 //=======================================================================
 //function : UnitFlag
 //purpose  : 
@@ -802,8 +815,7 @@ Handle(TCollection_HAsciiString) IGESData_GlobalSection::NewDateString
 
 Standard_Real IGESData_GlobalSection::UnitValue () const
 {
-  return UnitsMethods::GetLengthFactorValue ( theUnitFlag ) /
-         UnitsMethods::GetCasCadeLengthUnit(); //abv 22 Feb 00: adding cascade unit factor
+  return IGESData_BasicEditor::UnitFlagValue(theUnitFlag) / theCascadeUnit;
 }
 
 
@@ -848,6 +860,9 @@ Standard_Real IGESData_GlobalSection::UnitValue () const
     void  IGESData_GlobalSection::SetScale       (const Standard_Real val)
       {  theScale = val;  }
 
+    void  IGESData_GlobalSection::SetCascadeUnit (const Standard_Real theUnit)
+     { theCascadeUnit = theUnit; }
+
     void  IGESData_GlobalSection::SetUnitFlag    (const Standard_Integer val)
       {  theUnitFlag = val;  }
 
index 29bb832..8d47f30 100644 (file)
@@ -105,6 +105,9 @@ public:
   
   //! Returns the scale used in the IGES file.
   Standard_EXPORT Standard_Real Scale() const;
+
+  //! Returns the system length unit
+  Standard_EXPORT Standard_Real CascadeUnit() const;
   
   //! Returns the unit flag that was used to write the IGES file.
   Standard_EXPORT Standard_Integer UnitFlag() const;
@@ -203,6 +206,8 @@ public:
   
   Standard_EXPORT void SetReceiveName (const Handle(TCollection_HAsciiString)& val);
   
+  Standard_EXPORT void SetCascadeUnit(const Standard_Real theUnit);
+
   Standard_EXPORT void SetScale (const Standard_Real val);
   
   Standard_EXPORT void SetUnitFlag (const Standard_Integer val);
@@ -250,6 +255,7 @@ private:
   Standard_Integer theMaxDigitsDouble;
   Handle(TCollection_HAsciiString) theReceiveName;
   Standard_Real theScale;
+  Standard_Real theCascadeUnit;
   Standard_Integer theUnitFlag;
   Handle(TCollection_HAsciiString) theUnitName;
   Standard_Integer theLineWeightGrad;
index 3091718..1856b5b 100644 (file)
@@ -230,17 +230,6 @@ void   IGESData_IGESModel::AddStartLine
   else thestart->InsertBefore (atnum,new TCollection_HAsciiString(line));
 }
 
-
-
-//=======================================================================
-//function : GlobalSection
-//purpose  : 
-//=======================================================================
-
-const IGESData_GlobalSection& IGESData_IGESModel::GlobalSection () const
-      {  return theheader;  }
-
-
 //=======================================================================
 //function : SetGlobalSection
 //purpose  : 
index 55044e4..bd893b9 100644 (file)
@@ -92,7 +92,10 @@ public:
   Standard_EXPORT void AddStartLine (const Standard_CString line, const Standard_Integer atnum = 0);
   
   //! Returns the Global section of the IGES file.
-  Standard_EXPORT const IGESData_GlobalSection& GlobalSection() const;
+  const IGESData_GlobalSection& GlobalSection() const { return theheader; }
+
+  //! Returns the Global section of the IGES file.
+  IGESData_GlobalSection& ChangeGlobalSection() { return theheader; }
   
   //! Sets the Global section of the IGES file.
   Standard_EXPORT void SetGlobalSection (const IGESData_GlobalSection& header);
index 2c80cfe..8d480a9 100644 (file)
@@ -47,7 +47,6 @@
 #include <Select3D_SensitiveSegment.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <Standard_ProgramError.hxx>
-#include <UnitsAPI.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_Plane.hxx>
 
index 514cbed..7526eec 100644 (file)
@@ -72,7 +72,6 @@
 #include <Units.hxx>
 #include <Units_UnitsDictionary.hxx>
 #include <UnitsAPI.hxx>
-#include <UnitsAPI_SystemUnits.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(PrsDim_Dimension, AIS_InteractiveObject)
 
index b8a50cd..71f88bb 100644 (file)
@@ -340,6 +340,11 @@ bool RWGltf_CafWriter::Perform (const Handle(TDocStd_Document)& theDocument,
                                 const TColStd_IndexedDataMapOfStringString& theFileInfo,
                                 const Message_ProgressRange& theProgress)
 {
+  Standard_Real aLengthUnit = 1.;
+  if (XCAFDoc_DocumentTool::GetLengthUnit(theDocument, aLengthUnit))
+  {
+    myCSTrsf.SetInputLengthUnit(aLengthUnit);
+  }
   const Standard_Integer aDefSamplerId = 0;
   myMaterialMap = new RWGltf_GltfMaterialMap (myFile, aDefSamplerId);
   myMaterialMap->SetDefaultStyle (myDefaultStyle);
index eb10ed2..f998d3b 100644 (file)
@@ -58,6 +58,16 @@ RWMesh_CafReader::~RWMesh_CafReader()
   //
 }
 
+void RWMesh_CafReader::SetDocument(const Handle(TDocStd_Document)& theDoc)
+{
+  myXdeDoc = theDoc;
+  Standard_Real aScaleFactorM = 1.;
+  if (XCAFDoc_DocumentTool::GetLengthUnit(theDoc, aScaleFactorM))
+  {
+    SetSystemLengthUnit(aScaleFactorM);
+  }
+}
+
 // =======================================================================
 // function : SingleShape
 // purpose  :
@@ -159,6 +169,17 @@ void RWMesh_CafReader::fillDocument()
     return;
   }
 
+  // set units
+  Standard_Real aLengthUnit = 1.;
+  if (!XCAFDoc_DocumentTool::GetLengthUnit(myXdeDoc, aLengthUnit))
+  {
+    XCAFDoc_DocumentTool::SetLengthUnit(myXdeDoc, SystemLengthUnit());
+  }
+  else if (aLengthUnit != SystemLengthUnit())
+  {
+    Message::SendWarning("Warning: Length unit of document not equal to the system length unit");
+  }
+
   const Standard_Boolean wasAutoNaming = XCAFDoc_ShapeTool::AutoNaming();
   XCAFDoc_ShapeTool::SetAutoNaming (Standard_False);
   const TCollection_AsciiString aRootName; // = generateRootName (theFile);
index 0776adb..c4df3d5 100644 (file)
@@ -71,7 +71,8 @@ public:
   const Handle(TDocStd_Document)& Document() const { return myXdeDoc; }
 
   //! Set target document.
-  void SetDocument (const Handle(TDocStd_Document)& theDoc) { myXdeDoc = theDoc; }
+  //! Set system length unit according to the units of the document
+  Standard_EXPORT void SetDocument(const Handle(TDocStd_Document)& theDoc);
 
   //! Return prefix for generating root labels names.
   const TCollection_AsciiString& RootPrefix() const { return myRootPrefix; }
index 979af88..e092e29 100644 (file)
@@ -114,6 +114,12 @@ bool RWObj_CafWriter::Perform (const Handle(TDocStd_Document)& theDocument,
   OSD_Path::FolderAndFileFromPath (myFile, aFolder, aFileName);
   OSD_Path::FileNameAndExtension (aFileName, aShortFileNameBase, aFileExt);
 
+  Standard_Real aLengthUnit = 1.;
+  if (XCAFDoc_DocumentTool::GetLengthUnit(theDocument, aLengthUnit))
+  {
+    myCSTrsf.SetInputLengthUnit(aLengthUnit);
+  }
+
   if (theRootLabels.IsEmpty()
   || (theLabelFilter != NULL && theLabelFilter->IsEmpty()))
   {
index ed31a81..a0b4fbb 100644 (file)
@@ -47,6 +47,7 @@
 #include <StepBasic_SiUnitAndLengthUnit.hxx>
 #include <StepBasic_Unit.hxx>
 #include <StepBasic_DocumentFile.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <STEPCAFControl_Controller.hxx>
 #include <STEPCAFControl_DataMapIteratorOfDataMapOfShapePD.hxx>
 #include <STEPCAFControl_DataMapOfPDExternFile.hxx>
@@ -535,6 +536,23 @@ static void FillShapesMap(const TopoDS_Shape &S, TopTools_MapOfShape &map)
     FillShapesMap(it.Value(), map);
 }
 
+//=======================================================================
+//function : prepareUnits
+//purpose  :
+//=======================================================================
+void STEPCAFControl_Reader::prepareUnits(const Handle(StepData_StepModel)& theModel,
+                                         const Handle(TDocStd_Document)& theDoc) const
+{
+  Standard_Real aScaleFactorMM = 1.;
+  if (!XCAFDoc_DocumentTool::GetLengthUnit(theDoc, aScaleFactorMM, UnitsMethods_LengthUnit_Millimeter))
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    aScaleFactorMM = UnitsMethods::GetCasCadeLengthUnit();
+    // Sets length unit to the document
+    XCAFDoc_DocumentTool::SetLengthUnit(theDoc, aScaleFactorMM, UnitsMethods_LengthUnit_Millimeter);
+  }
+  theModel->SetLocalLengthUnit(aScaleFactorMM);
+}
 
 //=======================================================================
 //function : Transfer
@@ -549,6 +567,8 @@ Standard_Boolean STEPCAFControl_Reader::Transfer (STEPControl_Reader &reader,
                                                   const Message_ProgressRange& theProgress)
 {
   reader.ClearShapes();
+  Handle(StepData_StepModel) aModel = Handle(StepData_StepModel)::DownCast(reader.Model());
+  prepareUnits(aModel, doc);
   Standard_Integer i;
 
   // Read all shapes
@@ -582,14 +602,13 @@ Standard_Boolean STEPCAFControl_Reader::Transfer (STEPControl_Reader &reader,
   // from the ones representing hybrid models and shape sets
   STEPCAFControl_DataMapOfShapePD ShapePDMap;
   STEPCAFControl_DataMapOfPDExternFile PDFileMap;
-  Handle(Interface_InterfaceModel) Model = reader.Model();
   const Handle(Transfer_TransientProcess) &TP = reader.WS()->TransferReader()->TransientProcess();
-  Standard_Integer nb = Model->NbEntities();
+  Standard_Integer nb = aModel->NbEntities();
 
   Handle(TColStd_HSequenceOfTransient) SeqPDS = new TColStd_HSequenceOfTransient;
 
   for (i = 1; i <= nb; i++) {
-    Handle(Standard_Transient) enti = Model->Value(i);
+    Handle(Standard_Transient) enti = aModel->Value(i);
     if (enti->IsKind(STANDARD_TYPE(StepRepr_ProductDefinitionShape))) {
       // sequence for acceleration ReadMaterials
       SeqPDS->Append(enti);
@@ -752,7 +771,6 @@ Standard_Boolean STEPCAFControl_Reader::Transfer (STEPControl_Reader &reader,
 
   // Update assembly compounds
   STool->UpdateAssemblies();
-
   return Standard_True;
 }
 
@@ -1983,7 +2001,7 @@ void readAnnotation(const Handle(XSControl_TransferReader)& theTR,
   XSAlgo::AlgoContainer()->PrepareForTransfer();
   STEPControl_ActorRead anActor;
   anActor.PrepareUnits(aDModel, aTP);
-  Standard_Real aFact = UnitsMethods::LengthFactor();
+  Standard_Real aFact = StepData_GlobalFactors::Intance().LengthFactor();
 
   // retrieve AnnotationPlane
   Handle(StepRepr_RepresentationItem) aDMIAE = aDMIA->IdentifiedItemValue(1);
@@ -2090,7 +2108,7 @@ void readConnectionPoints(const Handle(XSControl_TransferReader)& theTR,
     XSAlgo::AlgoContainer()->PrepareForTransfer();
     STEPControl_ActorRead anActor;
     anActor.PrepareUnits(aSDR, aTP);
-    aFact = UnitsMethods::LengthFactor();
+    aFact = StepData_GlobalFactors::Intance().LengthFactor();
   }
   
   if (theGDT->IsKind(STANDARD_TYPE(StepShape_DimensionalSize))) {
@@ -4032,7 +4050,7 @@ Standard_Boolean STEPCAFControl_Reader::ReadGDTs(const Handle(XSControl_WorkSess
         STEPControl_ActorRead anActor;
         Handle(Transfer_TransientProcess) aTP = aTR->TransientProcess();
         anActor.PrepareUnits(aDMIA->UsedRepresentation(), aTP);
-        aFact = UnitsMethods::LengthFactor();
+        aFact = StepData_GlobalFactors::Intance().LengthFactor();
       }
 
       // Presentation
@@ -4196,8 +4214,8 @@ Standard_Boolean STEPCAFControl_Reader::ReadMaterials(const Handle(XSControl_Wor
                   aDensity = aDensity / (anUnitCtx.LengthFactor()*anUnitCtx.LengthFactor()*anUnitCtx.LengthFactor());
                   // transfer length value for Density from millimeter to santimeter
                   // in order to result density has dimension gram/(sm*sm*sm)
-                  aDensity = aDensity*1000. / (UnitsMethods::GetCasCadeLengthUnit()
-                    * UnitsMethods::GetCasCadeLengthUnit() * UnitsMethods::GetCasCadeLengthUnit());
+                  const Standard_Real aCascadeUnit = StepData_GlobalFactors::Intance().CascadeUnit();
+                  aDensity = aDensity*1000. / (aCascadeUnit * aCascadeUnit * aCascadeUnit);
                 }
                 if (NU->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndMassUnit))) {
                   Standard_Real afact = 1.;
index 2aa4d23..def983c 100644 (file)
@@ -291,6 +291,11 @@ private:
     const Handle(TDocStd_Document)& theDoc,
     const Handle(XSControl_WorkSession)& theWS);
 
+  //! Prepares units for transfer
+  void prepareUnits(const Handle(StepData_StepModel)& theModel,
+                    const Handle(TDocStd_Document)& theDoc) const;
+
+private:
 
   STEPControl_Reader myReader;
   NCollection_DataMap<TCollection_AsciiString, Handle(STEPCAFControl_ExternFile)> myFiles;
index b9ca23f..22d46ca 100644 (file)
 #include <XCAFDoc_DocumentTool.hxx>
 #include <XCAFDoc_GeomTolerance.hxx>
 #include <XCAFDoc_GraphNode.hxx>
+#include <XCAFDoc_LengthUnit.hxx>
 #include <XCAFDoc_LayerTool.hxx>
 #include <XCAFDoc_Material.hxx>
 #include <XCAFDoc_MaterialTool.hxx>
 #include <XCAFPrs_IndexedDataMapOfShapeStyle.hxx>
 #include <XCAFPrs_DataMapOfStyleShape.hxx>
 #include <XCAFPrs_Style.hxx>
+#include <XSAlgo.hxx>
+#include <XSAlgo_AlgoContainer.hxx>
 #include <XSControl_TransferWriter.hxx>
 #include <XSControl_WorkSession.hxx>
+#include <UnitsMethods.hxx>
 
 // added by skl 15.01.2004 for D&GT writing
 //#include <StepRepr_CompoundItemDefinition.hxx>
@@ -359,6 +363,25 @@ IFSelect_ReturnStatus STEPCAFControl_Writer::Write (const Standard_CString filen
   return status;
 }
 
+//=======================================================================
+//function : prepareUnit
+//purpose  :
+//=======================================================================
+void STEPCAFControl_Writer::prepareUnit(const TDF_Label& theLabel,
+                                        const Handle(StepData_StepModel)& theModel)
+{
+  Handle(XCAFDoc_LengthUnit) aLengthAttr;
+  if (!theLabel.IsNull() &&
+    theLabel.Root().FindAttribute(XCAFDoc_LengthUnit::GetID(), aLengthAttr))
+  {
+    theModel->SetLocalLengthUnit(aLengthAttr->GetUnitValue() * 1000); // convert to mm
+  }
+  else
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    theModel->SetLocalLengthUnit(UnitsMethods::GetCasCadeLengthUnit());
+  }
+}
 
 //=======================================================================
 //function : Transfer
@@ -516,6 +539,8 @@ Standard_Boolean STEPCAFControl_Writer::Transfer (STEPControl_Writer &writer,
   Handle(STEPCAFControl_ActorWrite) Actor =
     Handle(STEPCAFControl_ActorWrite)::DownCast ( writer.WS()->NormAdaptor()->ActorWrite() );
 
+  const Handle(StepData_StepModel) aModel = Handle(StepData_StepModel)::DownCast(writer.WS()->Model());
+  prepareUnit(labels.First(), aModel); // set local length unit to the model
   // translate free top-level shapes of the DECAF document
   Standard_Integer ap = Interface_Static::IVal ("write.step.schema");
   TDF_LabelSequence sublabels;
@@ -659,10 +684,9 @@ Standard_Boolean STEPCAFControl_Writer::Transfer (STEPControl_Writer &writer,
       WriteMaterials(writer.WS(),sublabels);
 
     // register all MDGPRs in model
-    const Handle(Interface_InterfaceModel) &Model = writer.WS()->Model();
     MoniTool_DataMapIteratorOfDataMapOfShapeTransient anItr(myMapCompMDGPR);
     for (; anItr.More(); anItr.Next())
-      Model->AddWithRefs( anItr.Value() );
+      aModel->AddWithRefs( anItr.Value() );
   }
   
   if ( multi ) { // external refs
index f74f078..f571852 100644 (file)
@@ -92,6 +92,12 @@ public:
                                              const Standard_CString multi = 0,
                                              const Message_ProgressRange& theProgress = Message_ProgressRange());
 
+  //! Mehod to writing sequence of root assemblies or part of the file specified by use by one label 
+  Standard_EXPORT Standard_Boolean Transfer (const TDF_LabelSequence& L,
+                                             const STEPControl_StepModelType mode = STEPControl_AsIs,
+                                             const Standard_CString multi = 0,
+                                             const Message_ProgressRange& theProgress = Message_ProgressRange());
+
   Standard_EXPORT Standard_Boolean Perform (const Handle(TDocStd_Document)& doc,
                                             const TCollection_AsciiString& filename,
                                             const Message_ProgressRange& theProgress = Message_ProgressRange());
@@ -155,15 +161,7 @@ public:
   
   Standard_EXPORT Standard_Boolean GetMaterialMode() const;
 
-
-
-
 protected:
-  //! Mehod to writing sequence of root assemblies or part of the file specified by use by one label 
-  Standard_EXPORT Standard_Boolean Transfer (const TDF_LabelSequence& L,
-                                             const STEPControl_StepModelType mode = STEPControl_AsIs,
-                                             const Standard_CString multi = 0,
-                                             const Message_ProgressRange& theProgress = Message_ProgressRange());
   
   //! Transfers labels to a STEP model
   //! Returns True if translation is OK
@@ -215,9 +213,14 @@ protected:
   //! Write SHUO assigned to specified component, to STEP model
   Standard_EXPORT Standard_Boolean WriteSHUOs (const Handle(XSControl_WorkSession)& WS, const TDF_LabelSequence& labels);
 
-  
+  //! Finds length units located in root of label
+  //! If it exists, initializes local length unit from it
+  //! Else initializes according to Cascade length unit
+  Standard_EXPORT void prepareUnit(const TDF_Label& theLabel,
+                                   const Handle(StepData_StepModel)& theModel);
 
 private:
+
   Standard_EXPORT Handle(StepRepr_ShapeAspect) WriteShapeAspect(const Handle(XSControl_WorkSession) &WS,
     const TDF_Label theLabel, const TopoDS_Shape theShape, Handle(StepRepr_RepresentationContext)& theRC,
     Handle(StepAP242_GeometricItemSpecificUsage)& theGISU);
@@ -236,6 +239,7 @@ private:
     const TDF_Label theGeomTolL, const Handle(StepDimTol_HArray1OfDatumSystemOrReference)& theDatumSystem,
     const Handle(StepRepr_RepresentationContext)& theRC);
 
+private:
 
 
   STEPControl_Writer myWriter;
index f2ffd2d..cefb2f6 100644 (file)
 #include <StepBasic_SolidAngleMeasureWithUnit.hxx>
 #include <StepBasic_SolidAngleUnit.hxx>
 #include <StepBasic_UncertaintyMeasureWithUnit.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <STEPConstruct_UnitContext.hxx>
 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
 #include <StepRepr_GlobalUncertaintyAssignedContext.hxx>
 #include <StepRepr_GlobalUnitAssignedContext.hxx>
 #include <TCollection_HAsciiString.hxx>
-#include <UnitsMethods.hxx>
 
 //=======================================================================
 //function : STEPConstruct_UnitContext
@@ -91,18 +91,20 @@ void STEPConstruct_UnitContext::Init(const Standard_Real Tol3d)
   Standard_CString uName = 0;
   Standard_Boolean hasPref = Standard_True;
   StepBasic_SiPrefix siPref = StepBasic_spMilli;
-  switch ( Interface_Static::IVal ( "write.step.unit" ) ) {
-  case  1 : uName = "INCH";             break;
-  default :
-  case  2 :                             break;
-  case  4 : uName = "FOOT";             break;
-  case  5 : uName = "MILE";             break;
-  case  6 : hasPref = Standard_False;   break;
-  case  7 : siPref = StepBasic_spKilo;  break;
-  case  8 : uName = "MIL";              break;
-  case  9 : siPref = StepBasic_spMicro; break;
-  case 10 : siPref = StepBasic_spCenti; break;
-  case 11 : uName = "MICROINCH";        break;
+  Standard_Real aScale = 1.;
+  switch (Interface_Static::IVal("write.step.unit"))
+  {
+    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 = Standard_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;
   }
   
   Handle(StepBasic_SiUnitAndLengthUnit) siUnit =
@@ -112,7 +114,7 @@ void STEPConstruct_UnitContext::Init(const Standard_Real Tol3d)
   if ( uName ) { // for non-metric units, create conversion_based_unit
     Handle(StepBasic_MeasureValueMember) val = new StepBasic_MeasureValueMember;
     val->SetName("LENGTH_UNIT");
-    val->SetReal ( UnitsMethods::GetLengthFactorValue ( Interface_Static::IVal ( "write.step.unit" ) ) );
+    val->SetReal (aScale);
 
     Handle(StepBasic_LengthMeasureWithUnit) measure = new StepBasic_LengthMeasureWithUnit;
     StepBasic_Unit Unit;
@@ -164,7 +166,7 @@ void STEPConstruct_UnitContext::Init(const Standard_Real Tol3d)
   
   Handle(StepBasic_MeasureValueMember) mvs = new StepBasic_MeasureValueMember;
   mvs->SetName("LENGTH_MEASURE");
-  mvs->SetReal ( Tol3d / UnitsMethods::LengthFactor() );
+  mvs->SetReal ( Tol3d / StepData_GlobalFactors::Intance().LengthFactor() );
   StepBasic_Unit Unit;
   Unit.SetValue ( lengthUnit );
   theTol3d->Init(mvs, Unit, TolName, TolDesc);
@@ -388,12 +390,13 @@ Standard_Integer STEPConstruct_UnitContext::ComputeFactors(const Handle(StepBasi
     return 0;
   }
   
+  const Standard_Real aCascadeUnit = StepData_GlobalFactors::Intance().CascadeUnit();
   if (aUnit->IsKind(STANDARD_TYPE(StepBasic_ConversionBasedUnitAndLengthUnit))||
       aUnit->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit))) {
 #ifdef METER
     lengthFactor = parameter;
 #else
-    lengthFactor = parameter * 1000. / UnitsMethods::GetCasCadeLengthUnit();
+    lengthFactor = parameter * 1000. / aCascadeUnit;
 #endif    
     if(!lengthDone) 
       lengthDone = Standard_True;
@@ -420,7 +423,7 @@ Standard_Integer STEPConstruct_UnitContext::ComputeFactors(const Handle(StepBasi
 #ifdef METER   
     af = parameter;
 #else
-    af = parameter * 1000. / UnitsMethods::GetCasCadeLengthUnit();
+    af = parameter * 1000. / aCascadeUnit;
 #endif    
     areaDone = Standard_True;
     areaFactor = pow(af,2);
@@ -431,7 +434,7 @@ Standard_Integer STEPConstruct_UnitContext::ComputeFactors(const Handle(StepBasi
 #ifdef METER   
     af = parameter;
 #else
-    af = parameter * 1000. / UnitsMethods::GetCasCadeLengthUnit();
+    af = parameter * 1000. / aCascadeUnit;
 #endif
     volumeDone = Standard_True;
     volumeFactor = pow(af,3);
index 3e0c3b7..b1443ce 100644 (file)
@@ -42,6 +42,7 @@
 #include <STEPConstruct_UnitContext.hxx>
 #include <STEPControl_ActorRead.hxx>
 #include <StepData_StepModel.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepDimTol_DatumFeature.hxx>
 #include <StepDimTol_GeometricTolerance.hxx>
 #include <StepDimTol_GeoTolAndGeoTolWthDatRefAndModGeoTolAndPosTol.hxx>
@@ -1752,7 +1753,7 @@ void STEPControl_ActorRead::PrepareUnits(const Handle(StepRepr_Representation)&
     Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
     Standard_Real angleFactor = ( anglemode == 0 ? myUnit.PlaneAngleFactor() :
                                  anglemode == 1 ? 1. : M_PI/180. );
-    UnitsMethods::InitializeFactors(myUnit.LengthFactor(),
+    StepData_GlobalFactors::Intance().InitializeFactors(myUnit.LengthFactor(),
                                    angleFactor,
                                    myUnit.SolidAngleFactor());
     if (stat1 != 0) TP->AddWarning (theRepCont,myUnit.StatusMessage(stat1));
@@ -1787,7 +1788,7 @@ void STEPControl_ActorRead::PrepareUnits(const Handle(StepRepr_Representation)&
 
 void  STEPControl_ActorRead::ResetUnits ()
 {
-  UnitsMethods::InitializeFactors ( 1, 1, 1 );
+  StepData_GlobalFactors::Intance().InitializeFactors ( 1, 1, 1 );
   myPrecision = Interface_Static::RVal("read.precision.val");
   myMaxTol = Max ( myPrecision, Interface_Static::RVal("read.maxprecision.val") );
 }
index cf3b6dd..43092ac 100644 (file)
@@ -45,6 +45,7 @@
 #include <STEPConstruct_UnitContext.hxx>
 #include <STEPControl_ActorWrite.hxx>
 #include <STEPControl_StepModelType.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepData_StepModel.hxx>
 #include <StepGeom_Axis2Placement3d.hxx>
 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
@@ -231,7 +232,7 @@ static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
 STEPControl_ActorWrite::STEPControl_ActorWrite ()
 : mygroup (0) , mytoler (-1.)
 {  
-  SetMode(STEPControl_ShellBasedSurfaceModel);  
+  SetMode(STEPControl_ShellBasedSurfaceModel);
 }
 
 //=======================================================================
@@ -450,8 +451,6 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::Transfer (const Handle(Transfer_
                                                           const Handle(Transfer_FinderProcess)& FP,
                                                           const Message_ProgressRange& theProgress)
 {
-  XSAlgo::AlgoContainer()->PrepareForTransfer();
-    
   Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
 
   if (mapper.IsNull()) return NullResult();
@@ -462,12 +461,15 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::Transfer (const Handle(Transfer_
   if ( ! model.IsNull() ) myContext.SetModel ( model ); //: abv 04.11.00: take APD from model
   myContext.AddAPD ( Standard_False ); // update APD
   myContext.SetLevel ( 1 ); // set assembly level to 1 (to ensure)
-  
-  //:S4136: init UnitsMethods to reset angle unit factors (see TopoDSToStep)
-  Standard_Real lFactor = UnitsMethods::GetLengthFactorValue ( Interface_Static::IVal ( "write.step.unit" ) );
-  lFactor /= UnitsMethods::GetCasCadeLengthUnit();
+  if (!model->IsInitializedUnit())
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    model->SetLocalLengthUnit(UnitsMethods::GetCasCadeLengthUnit());
+  }
+  Standard_Real aLFactor = model->WriteLengthUnit();
+  aLFactor /= model->LocalLengthUnit();
   Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
-  UnitsMethods::InitializeFactors ( lFactor, ( anglemode <= 1 ? 1. : M_PI/180. ), 1. );
+  StepData_GlobalFactors::Intance().InitializeFactors (aLFactor, ( anglemode <= 1 ? 1. : M_PI/180. ), 1. );
 
   // create SDR
   STEPConstruct_Part SDRTool;
index 15ea180..b7c003b 100644 (file)
@@ -442,6 +442,24 @@ void STEPControl_Reader::FileUnits( TColStd_SequenceOfAsciiString& theUnitLength
   }
 }
 
+//=======================================================================
+//function : SetSystemLengthUnit
+//purpose  :
+//=======================================================================
+void STEPControl_Reader::SetSystemLengthUnit(const Standard_Real theLengthUnit)
+{
+  StepModel()->SetLocalLengthUnit(theLengthUnit);
+}
+
+//=======================================================================
+//function : SystemLengthUnit
+//purpose  :
+//=======================================================================
+Standard_Real STEPControl_Reader::SystemLengthUnit() const
+{
+  return StepModel()->LocalLengthUnit();
+}
+
 //=======================================================================
 //function : getSiName
 //purpose  : 
index e96e442..1619174 100644 (file)
@@ -100,7 +100,11 @@ public:
   //! found in file
   Standard_EXPORT void FileUnits (TColStd_SequenceOfAsciiString& theUnitLengthNames, TColStd_SequenceOfAsciiString& theUnitAngleNames, TColStd_SequenceOfAsciiString& theUnitSolidAngleNames);
 
+  //! Sets system length unit used by transfer process
+  Standard_EXPORT void SetSystemLengthUnit(const Standard_Real theLengthUnit);
 
+  //! Returns system length unit used by transfer process
+  Standard_EXPORT Standard_Real SystemLengthUnit() const;
 
 
 protected:
index 77153b5..1d74eac 100644 (file)
 #include <TopExp_Explorer.hxx>
 #include <TopoDS_Shape.hxx>
 #include <Transfer_FinderProcess.hxx>
+#include <XSAlgo.hxx>
+#include <XSAlgo_AlgoContainer.hxx>
 #include <XSControl_TransferWriter.hxx>
 #include <XSControl_WorkSession.hxx>
+#include <UnitsMethods.hxx>
 
 //=======================================================================
 //function : STEPControl_Writer
@@ -136,7 +139,11 @@ IFSelect_ReturnStatus STEPControl_Writer::Transfer
   }
   if (mws < 0) return IFSelect_RetError;    // cas non reconnu
   thesession->TransferWriter()->SetTransferMode (mws);
-
+  if (!Model()->IsInitializedUnit())
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    Model()->SetLocalLengthUnit(UnitsMethods::GetCasCadeLengthUnit());
+  }
   return thesession->TransferWriteShape(sh, compgraph, theProgress);
 }
 
index 77c4b1d..ebd665a 100644 (file)
@@ -859,7 +859,7 @@ static Standard_Boolean IsOverlapPartEdges(const TopoDS_Edge& theFirstEdge,
                                            const Standard_Real& theTolerance,
                                            const Standard_Real& theStep,
                                            const Standard_Real& theStartLength,
-                                           const Standard_Real& theEndLenght)
+                                           const Standard_Real& theEndLength)
 {
   TColStd_SequenceOfInteger aSeqIntervals;
   BRepAdaptor_Curve aAdCurve1(theFirstEdge);
@@ -867,7 +867,7 @@ static Standard_Boolean IsOverlapPartEdges(const TopoDS_Edge& theFirstEdge,
   BRepExtrema_DistShapeShape aMinDist;
   aMinDist.LoadS1(theSecEdge);
 
-  for(Standard_Real aS = theStartLength; aS <= theEndLenght; aS+=theStep/2) {
+  for(Standard_Real aS = theStartLength; aS <= theEndLength; aS+=theStep/2) {
     
     gp_Pnt aPoint;
     if(aS <= Precision::Confusion()) {
index d37a261..a80a6ee 100644 (file)
@@ -31,6 +31,8 @@ StepData_FreeFormEntity.cxx
 StepData_FreeFormEntity.hxx
 StepData_GeneralModule.cxx
 StepData_GeneralModule.hxx
+StepData_GlobalFactors.cxx
+StepData_GlobalFactors.hxx
 StepData_GlobalNodeOfWriterLib.hxx
 StepData_GlobalNodeOfWriterLib_0.cxx
 StepData_HArray1OfField.hxx
diff --git a/src/StepData/StepData_GlobalFactors.cxx b/src/StepData/StepData_GlobalFactors.cxx
new file mode 100644 (file)
index 0000000..37cff58
--- /dev/null
@@ -0,0 +1,113 @@
+// Copyright (c) 2021 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.
+
+#include <StepData_GlobalFactors.hxx>
+
+// ============================================================================
+// Method : Consturctor
+// Purpose:
+// ============================================================================
+StepData_GlobalFactors::StepData_GlobalFactors()
+  :myLengthFactor(1.), myPlaneAngleFactor(1.),
+   mySolidAngleFactor(1.), myFactRD(1.),
+   myFactDR(1.), myCascadeUnit(1.)
+{}
+
+// ============================================================================
+// Method : Intance
+// Purpose:
+// ============================================================================
+StepData_GlobalFactors& StepData_GlobalFactors::Intance()
+{
+  static StepData_GlobalFactors THE_FACTORS;
+  return THE_FACTORS;
+}
+
+// ============================================================================
+// Method : InitializeFactors
+// Purpose:
+// ============================================================================
+void StepData_GlobalFactors::InitializeFactors(
+  const Standard_Real theLengthFactor,
+  const Standard_Real thePlaneAngleFactor,
+  const Standard_Real theSolidAngleFactor)
+{
+  myLengthFactor = theLengthFactor;
+  myPlaneAngleFactor = thePlaneAngleFactor;
+  mySolidAngleFactor = theSolidAngleFactor;
+  myFactRD = 1. / thePlaneAngleFactor;
+  myFactDR = thePlaneAngleFactor;
+}
+
+// ============================================================================
+// Method : LengthFactor
+// Purpose:
+// ============================================================================
+Standard_Real StepData_GlobalFactors::LengthFactor()
+{
+  return myLengthFactor;
+}
+
+// ============================================================================
+// Method : PlaneAngleFactor
+// Purpose:
+// ============================================================================
+Standard_Real StepData_GlobalFactors::PlaneAngleFactor()
+{
+  return myPlaneAngleFactor;
+}
+
+// ============================================================================
+// Method : SolidAngleFactor
+// Purpose:
+// ============================================================================
+Standard_Real StepData_GlobalFactors::SolidAngleFactor()
+{
+  return mySolidAngleFactor;
+}
+
+// ============================================================================
+// Method : FactorRadianDegree
+// Purpose:
+// ============================================================================
+Standard_Real StepData_GlobalFactors::FactorRadianDegree()
+{
+  return myFactRD;
+}
+
+// ============================================================================
+// Method : FactorDegreeRadian
+// Purpose:
+// ============================================================================
+Standard_Real StepData_GlobalFactors::FactorDegreeRadian()
+{
+  return myFactDR;
+}
+
+// ============================================================================
+// Method : SetCascadeUnit
+// Purpose:
+// ============================================================================
+void StepData_GlobalFactors::SetCascadeUnit(const Standard_Real theUnit)
+{
+  myCascadeUnit = theUnit;
+}
+
+// ============================================================================
+// Method : CascadeUnit
+// Purpose:
+// ============================================================================
+Standard_Real StepData_GlobalFactors::CascadeUnit()
+{
+  return myCascadeUnit;
+}
diff --git a/src/StepData/StepData_GlobalFactors.hxx b/src/StepData/StepData_GlobalFactors.hxx
new file mode 100644 (file)
index 0000000..90c30e3
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (c) 2021 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.
+
+#ifndef _StepData_GlobalFactors_HeaderFile
+#define _StepData_GlobalFactors_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_Boolean.hxx>
+#include <Standard_Integer.hxx>
+
+//! Class for using global units variables
+class StepData_GlobalFactors
+{
+
+private:
+
+  Standard_EXPORT StepData_GlobalFactors();
+
+public:
+
+  DEFINE_STANDARD_ALLOC
+  //! Returns a global static object
+  Standard_EXPORT static StepData_GlobalFactors& Intance();
+
+  //! Initializes the 3 factors for the conversion of units
+  Standard_EXPORT void InitializeFactors(
+    const Standard_Real theLengthFactor,
+    const Standard_Real thePlaneAngleFactor,
+    const Standard_Real theSolidAngleFactor);
+
+  //! Sets length unit for current transfer process
+  Standard_EXPORT void SetCascadeUnit(const Standard_Real theUnit);
+
+  //! Returns length unit for current transfer process (mm by default)
+  Standard_EXPORT Standard_Real CascadeUnit();
+
+  //! Returns transient length factor for scaling of shapes
+  //! at one stage of transfer process
+  Standard_EXPORT Standard_Real LengthFactor();
+
+  //! Returns transient plane angle factor for conversion of angles
+  //! at one stage of transfer process
+  Standard_EXPORT Standard_Real PlaneAngleFactor();
+
+  //! Returns transient solid angle factor for conversion of angles
+  //! at one stage of transfer process
+  Standard_EXPORT Standard_Real SolidAngleFactor();
+
+  //! Returns transient factor radian degree for conversion of angles
+  //! at one stage of transfer process
+  Standard_EXPORT Standard_Real FactorRadianDegree();
+
+  //! Returns transient factor degree radian for conversion of angles
+  //! at one stage of transfer process
+  Standard_EXPORT Standard_Real FactorDegreeRadian();
+
+private:
+
+  Standard_Real myLengthFactor;
+  Standard_Real myPlaneAngleFactor;
+  Standard_Real mySolidAngleFactor;
+  Standard_Real myFactRD;
+  Standard_Real myFactDR;
+  Standard_Real myCascadeUnit;
+};
+
+#endif // _StepData_GlobalFactors_HeaderFile
index 187e99c..2768a85 100644 (file)
@@ -25,6 +25,7 @@
 #include <Standard_Type.hxx>
 #include <StepData.hxx>
 #include <StepData_Protocol.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepData_StepModel.hxx>
 #include <StepData_StepWriter.hxx>
 #include <TCollection_HAsciiString.hxx>
 IMPLEMENT_STANDARD_RTTIEXT(StepData_StepModel,Interface_InterfaceModel)
 
 // Entete de fichier : liste d entites
-StepData_StepModel::StepData_StepModel () :mySourceCodePage((Resource_FormatType)Interface_Static::IVal("read.step.codepage"))
-{}
+StepData_StepModel::StepData_StepModel () :mySourceCodePage((Resource_FormatType)Interface_Static::IVal("read.step.codepage")),
+  myReadUnitIsInitialized(Standard_False), myWriteUnit (1.)
+{
+  switch (Interface_Static::IVal("write.step.unit"))
+  {
+    case  1: myWriteUnit = 25.4; break;
+    case  2: myWriteUnit = 1.; break;
+    case  4: myWriteUnit = 304.8; break;
+    case  5: myWriteUnit = 1609344.0; break;
+    case  6: myWriteUnit = 1000.0; break;
+    case  7: myWriteUnit = 1000000.0; break;
+    case  8: myWriteUnit = 0.0254; break;
+    case  9: myWriteUnit = 0.001; break;
+    case 10: myWriteUnit = 10.0; break;
+    case 11: myWriteUnit = 0.0000254; break;
+    default:
+      GlobalCheck()->AddWarning("Incorrect write.step.unit parameter, use default value");
+  }
+}
 
 
 Handle(Standard_Transient) StepData_StepModel::Entity
@@ -193,3 +211,40 @@ Handle(TCollection_HAsciiString) StepData_StepModel::StringLabel
   label = new TCollection_HAsciiString(text);
   return label;
 }
+
+//=======================================================================
+//function : SetLocalLengthUnit
+//purpose  :
+//=======================================================================
+void StepData_StepModel::SetLocalLengthUnit(const Standard_Real theUnit)
+{
+  StepData_GlobalFactors::Intance().SetCascadeUnit(theUnit);
+  myReadUnitIsInitialized = Standard_True;
+}
+
+//=======================================================================
+//function : LocalLengthUnit
+//purpose  :
+//=======================================================================
+Standard_Real StepData_StepModel::LocalLengthUnit() const
+{
+  return StepData_GlobalFactors::Intance().CascadeUnit();
+}
+
+//=======================================================================
+//function : SetLocalLengthUnit
+//purpose  :
+//=======================================================================
+void StepData_StepModel::SetWriteLengthUnit(const Standard_Real theUnit)
+{
+  myWriteUnit = theUnit;
+}
+
+//=======================================================================
+//function : LocalLengthUnit
+//purpose  :
+//=======================================================================
+Standard_Real StepData_StepModel::WriteLengthUnit() const
+{
+  return myWriteUnit;
+}
\ No newline at end of file
index 953f166..b7a9ec9 100644 (file)
@@ -105,6 +105,22 @@ public:
   //! Return the encoding of STEP file for converting names into UNICODE.
   void SetSourceCodePage (Resource_FormatType theCode) { mySourceCodePage = theCode; }
 
+  //! Sets local length unit using for transfer process
+  Standard_EXPORT void SetLocalLengthUnit(const Standard_Real theUnit);
+
+  //! Returns local length unit using for transfer process (1 by default)
+  Standard_EXPORT Standard_Real LocalLengthUnit() const;
+
+  //! Sets length unit using for writing process
+  Standard_EXPORT void SetWriteLengthUnit(const Standard_Real theUnit);
+
+  //! Returns length unit using for writing process (1 by default)
+  Standard_EXPORT Standard_Real WriteLengthUnit() const;
+
+  //! Returns the unit initialization flag
+  //! True - the unit was initialized
+  //! False - the unit value was not initialized, the default value is used
+  Standard_Boolean IsInitializedUnit() const { return myReadUnitIsInitialized; }
 
   DEFINE_STANDARD_RTTIEXT(StepData_StepModel,Interface_InterfaceModel)
 
@@ -119,6 +135,8 @@ private:
   Interface_EntityList theheader;
   Handle(TColStd_HArray1OfInteger) theidnums;
   Resource_FormatType mySourceCodePage;
+  Standard_Boolean myReadUnitIsInitialized;
+  Standard_Real myWriteUnit;
 
 
 };
index 8ee4177..98054dc 100644 (file)
@@ -226,12 +226,12 @@ void StepFile_ReadData::CreateNewText(const char* theNewText, int theLenText)
     return;
   }
   //  If error argument exists - prepare size to new text value and old result text
-  int aLenght = (myErrorArg) ? theLenText + (int)strlen(myResText) : theLenText;
+  int aLength = (myErrorArg) ? theLenText + (int)strlen(myResText) : theLenText;
 
-  if (myOneCharPage->myUsed > myMaxChar - aLenght - 1)
+  if (myOneCharPage->myUsed > myMaxChar - aLength - 1)
   {
     int aSizeOfPage = myMaxChar + 1;
-    if (aLenght >= myMaxChar) aSizeOfPage += (aLenght + 1 - myMaxChar);
+    if (aLength >= myMaxChar) aSizeOfPage += (aLength + 1 - myMaxChar);
     CharactersPage* aNewPage = new CharactersPage(aSizeOfPage);
     aNewPage->myNext = myOneCharPage;
     myOneCharPage = aNewPage;
@@ -241,7 +241,7 @@ void StepFile_ReadData::CreateNewText(const char* theNewText, int theLenText)
   char* anOldResText = myResText;
 
   myResText = myOneCharPage->myCharacters + myOneCharPage->myUsed;
-  myOneCharPage->myUsed += (aLenght + 1);
+  myOneCharPage->myUsed += (aLength + 1);
 
   // If error argument exists - append new text to old result text
   // Else create new result text
index 9c4a0f7..dcbd145 100644 (file)
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 
-#include <UnitsMethods.hxx>
+#include <StepData_GlobalFactors.hxx>
 
 //=============================================================================
 // Creation d' un Ax1Placement de Geom a partir d' un axis1_placement de Step
@@ -980,7 +980,7 @@ Handle(Geom_CartesianPoint) StepToGeom::MakeCartesianPoint (const Handle(StepGeo
 {
   if (SP->NbCoordinates() == 3)
   {
-    const Standard_Real LF = UnitsMethods::LengthFactor();
+    const Standard_Real LF = StepData_GlobalFactors::Intance().LengthFactor();
     const Standard_Real X = SP->CoordinatesValue(1) * LF;
     const Standard_Real Y = SP->CoordinatesValue(2) * LF;
     const Standard_Real Z = SP->CoordinatesValue(3) * LF;
@@ -1018,7 +1018,7 @@ Handle(Geom_Circle) StepToGeom::MakeCircle (const Handle(StepGeom_Circle)& SC)
       MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
     if (! A.IsNull())
     {
-      return new Geom_Circle(A->Ax2(),SC->Radius() * UnitsMethods::LengthFactor());
+      return new Geom_Circle(A->Ax2(),SC->Radius() * StepData_GlobalFactors::Intance().LengthFactor());
     }
   }
   return 0;
@@ -1096,8 +1096,8 @@ Handle(Geom_ConicalSurface) StepToGeom::MakeConicalSurface (const Handle(StepGeo
   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SS->Position());
   if (! A.IsNull())
   {
-    const Standard_Real R = SS->Radius() * UnitsMethods::LengthFactor();
-    const Standard_Real Ang = SS->SemiAngle() * UnitsMethods::PlaneAngleFactor();
+    const Standard_Real R = SS->Radius() * StepData_GlobalFactors::Intance().LengthFactor();
+    const Standard_Real Ang = SS->SemiAngle() * StepData_GlobalFactors::Intance().PlaneAngleFactor();
     //#2(K3-3) rln 12/02/98 ProSTEP ct_turbine-A.stp entity #518, #3571 (gp::Resolution() is too little)
     return new Geom_ConicalSurface(A->Ax2(), Max(Ang, Precision::Angular()), R);
   }
@@ -1215,7 +1215,7 @@ Handle(Geom_CylindricalSurface) StepToGeom::MakeCylindricalSurface (const Handle
   Handle(Geom_Axis2Placement) A = MakeAxis2Placement(SS->Position());
   if (! A.IsNull())
   {
-    return new Geom_CylindricalSurface(A->Ax2(), SS->Radius() * UnitsMethods::LengthFactor());
+    return new Geom_CylindricalSurface(A->Ax2(), SS->Radius() * StepData_GlobalFactors::Intance().LengthFactor());
   }
   return 0;
 }
@@ -1301,7 +1301,7 @@ Handle(Geom_Ellipse) StepToGeom::MakeEllipse (const Handle(StepGeom_Ellipse)& SC
     if (! A1.IsNull())
     {
       gp_Ax2 A( A1->Ax2() );
-      const Standard_Real LF = UnitsMethods::LengthFactor();
+      const Standard_Real LF = StepData_GlobalFactors::Intance().LengthFactor();
       const Standard_Real majorR = SC->SemiAxis1() * LF;
       const Standard_Real minorR = SC->SemiAxis2() * LF;
       if ( majorR - minorR >= 0. ) { //:o9 abv 19 Feb 99
@@ -1357,7 +1357,7 @@ Handle(Geom_Hyperbola) StepToGeom::MakeHyperbola (const Handle(StepGeom_Hyperbol
     if (! A1.IsNull())
     {
       const gp_Ax2 A( A1->Ax2() );
-      const Standard_Real LF = UnitsMethods::LengthFactor();
+      const Standard_Real LF = StepData_GlobalFactors::Intance().LengthFactor();
       return new Geom_Hyperbola(A, SC->SemiAxis() * LF, SC->SemiImagAxis() * LF);
     }
   }
@@ -1437,7 +1437,7 @@ Handle(Geom_Parabola) StepToGeom::MakeParabola (const Handle(StepGeom_Parabola)&
     Handle(Geom_Axis2Placement) A = MakeAxis2Placement (Handle(StepGeom_Axis2Placement3d)::DownCast(AxisSelect.Value()));
     if (! A.IsNull())
     {
-      return new Geom_Parabola(A->Ax2(), SC->FocalDist() * UnitsMethods::LengthFactor());
+      return new Geom_Parabola(A->Ax2(), SC->FocalDist() * StepData_GlobalFactors::Intance().LengthFactor());
     }
   }
   return 0;
@@ -1561,8 +1561,8 @@ Handle(Geom_RectangularTrimmedSurface) StepToGeom::MakeRectangularTrimmedSurface
 
     Standard_Real uFact = 1.;
     Standard_Real vFact = 1.;
-    const Standard_Real LengthFact  = UnitsMethods::LengthFactor();
-    const Standard_Real AngleFact   = UnitsMethods::PlaneAngleFactor(); // abv 30.06.00 trj4_k1_geo-tc-214.stp #1477: PI/180.;
+    const Standard_Real LengthFact  = StepData_GlobalFactors::Intance().LengthFactor();
+    const Standard_Real AngleFact   = StepData_GlobalFactors::Intance().PlaneAngleFactor(); // abv 30.06.00 trj4_k1_geo-tc-214.stp #1477: PI/180.;
 
     if (theBasis->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
         theBasis->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
@@ -1604,7 +1604,7 @@ Handle(Geom_SphericalSurface) StepToGeom::MakeSphericalSurface (const Handle(Ste
   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SS->Position());
   if (! A.IsNull())
   {
-    return new Geom_SphericalSurface(A->Ax2(), SS->Radius() * UnitsMethods::LengthFactor());
+    return new Geom_SphericalSurface(A->Ax2(), SS->Radius() * StepData_GlobalFactors::Intance().LengthFactor());
   }
   return 0;
 }
@@ -1642,7 +1642,7 @@ Handle(Geom_Surface) StepToGeom::MakeSurface (const Handle(StepGeom_Surface)& SS
       if (! aBasisSurface.IsNull())
       {
         // sln 03.10.01. BUC61003. creation of  offset surface is corrected
-        const Standard_Real anOffset = OS->Distance() * UnitsMethods::LengthFactor();
+        const Standard_Real anOffset = OS->Distance() * StepData_GlobalFactors::Intance().LengthFactor();
         if (aBasisSurface->Continuity() == GeomAbs_C0)
         {
           const BRepBuilderAPI_MakeFace aBFace(aBasisSurface, Precision::Confusion());
@@ -1781,7 +1781,7 @@ Handle(Geom_ToroidalSurface) StepToGeom::MakeToroidalSurface (const Handle(StepG
   Handle(Geom_Axis2Placement) A = MakeAxis2Placement (SS->Position());
   if (! A.IsNull())
   {
-    const Standard_Real LF = UnitsMethods::LengthFactor();
+    const Standard_Real LF = StepData_GlobalFactors::Intance().LengthFactor();
     return new Geom_ToroidalSurface(A->Ax2(), Abs(SS->MajorRadius() * LF), Abs(SS->MinorRadius() * LF));
   }
   return 0;
@@ -2011,12 +2011,12 @@ Handle(Geom_TrimmedCurve) StepToGeom::MakeTrimmedCurve (const Handle(StepGeom_Tr
   if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Line))) {
     const Handle(StepGeom_Line) theLine =
       Handle(StepGeom_Line)::DownCast(theSTEPCurve);
-    fact = theLine->Dir()->Magnitude() * UnitsMethods::LengthFactor();
+    fact = theLine->Dir()->Magnitude() * StepData_GlobalFactors::Intance().LengthFactor();
   }
   else if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Circle)) ||
            theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
 //    if (trim1 > 2.1*M_PI || trim2 > 2.1*M_PI) fact = M_PI / 180.;
-    fact = UnitsMethods::PlaneAngleFactor();
+    fact = StepData_GlobalFactors::Intance().PlaneAngleFactor();
     //:p3 abv 23 Feb 99: shift on pi/2 on ellipse with R1 < R2
     const Handle(StepGeom_Ellipse) ellipse = Handle(StepGeom_Ellipse)::DownCast(theSTEPCurve);
     if ( !ellipse.IsNull() && ellipse->SemiAxis1() - ellipse->SemiAxis2() < 0. )
@@ -2125,7 +2125,7 @@ Handle(Geom2d_BSplineCurve) StepToGeom::MakeTrimmedCurve2d (const Handle(StepGeo
     else if (BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Circle)) ||
              BasisCurve->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
 //      if (u1 > 2.1*M_PI || u2 > 2.1*M_PI) fact = M_PI / 180.;
-      fact = UnitsMethods::PlaneAngleFactor();
+      fact = StepData_GlobalFactors::Intance().PlaneAngleFactor();
       //:p3 abv 23 Feb 99: shift on pi/2 on ellipse with R1 < R2
       const Handle(StepGeom_Ellipse) ellipse = Handle(StepGeom_Ellipse)::DownCast(BasisCurve);
       if ( !ellipse.IsNull() && ellipse->SemiAxis1() - ellipse->SemiAxis2() < 0. )
@@ -2158,7 +2158,7 @@ Handle(Geom_VectorWithMagnitude) StepToGeom::MakeVectorWithMagnitude (const Hand
   Handle(Geom_Direction) D = MakeDirection (SV->Orientation());
   if (! D.IsNull())
   {
-    const gp_Vec V(D->Dir().XYZ() * SV->Magnitude() * UnitsMethods::LengthFactor());
+    const gp_Vec V(D->Dir().XYZ() * SV->Magnitude() * StepData_GlobalFactors::Intance().LengthFactor());
     return new Geom_VectorWithMagnitude(V);
   }
   return 0;
index eb61588..cd34da9 100644 (file)
@@ -36,6 +36,7 @@
 #include <ShapeAnalysis_Curve.hxx>
 #include <ShapeConstruct_Curve.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_CartesianPoint.hxx>
 #include <StepGeom_Curve.hxx>
 #include <StepGeom_Pcurve.hxx>
@@ -60,7 +61,7 @@
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <Transfer_TransientProcess.hxx>
-#include <UnitsMethods.hxx>
+#include <GeomConvert_Units.hxx>
 #include <Standard_Failure.hxx>
 
 //#include <StepGeom_Polyline.hxx>
@@ -491,7 +492,8 @@ Handle(Geom2d_Curve)  StepToTopoDS_TranslateEdge::MakePCurve
     if (! C2d.IsNull()) {
     // -- if the surface is a RectangularTrimmedSurface, 
     // -- send the BasisSurface.
-     C2d = UnitsMethods::DegreeToRadian(C2d, ConvSurf);
+     C2d = GeomConvert_Units::DegreeToRadian(C2d, ConvSurf,
+       StepData_GlobalFactors::Intance().LengthFactor(), StepData_GlobalFactors::Intance().FactorDegreeRadian());
     }
     
   }
index b05fbfd..f384afd 100755 (executable)
@@ -10,7 +10,6 @@ HeaderSection
 RWHeaderSection
 APIHeaderSection
 StepSelect
-UnitsMethods
 XSAlgo
 LibCtl
 MoniTool
index 6b13120..a10bf8d 100755 (executable)
@@ -11,5 +11,6 @@ TCollection
 TShort
 Units
 UnitsAPI
+UnitsMethods
 NCollection
 Message
index 7cea157..a562a59 100644 (file)
@@ -52,6 +52,7 @@
 #include <ShapeAlgo.hxx>
 #include <ShapeAlgo_AlgoContainer.hxx>
 #include <StdFail_NotDone.hxx>
+#include <StepData_GlobalFactors.hxx>
 #include <StepGeom_Curve.hxx>
 #include <StepGeom_DegenerateToroidalSurface.hxx>
 #include <StepGeom_GeometricRepresentationContextAndParametricRepresentationContext.hxx>
@@ -83,7 +84,7 @@
 #include <Transfer_FinderProcess.hxx>
 #include <TransferBRep.hxx>
 #include <TransferBRep_ShapeMapper.hxx>
-#include <UnitsMethods.hxx>
+#include <GeomConvert_Units.hxx>
 
 // Processing of non-manifold topology (ssv; 10.11.2010)
 // ----------------------------------------------------------------------------
@@ -377,10 +378,12 @@ void TopoDSToStep_MakeStepFace::Init(const TopoDS_Face& aFace,
        if (Su->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
          Handle(Geom_RectangularTrimmedSurface) alocalRTS =
            Handle(Geom_RectangularTrimmedSurface)::DownCast(Su);
-         C2dMapped = UnitsMethods::RadianToDegree(C2d, alocalRTS->BasisSurface());
+         C2dMapped = GeomConvert_Units::RadianToDegree(C2d, alocalRTS->BasisSurface(),
+      StepData_GlobalFactors::Intance().LengthFactor(), StepData_GlobalFactors::Intance().FactorRadianDegree());
        }
        else {
-         C2dMapped = UnitsMethods::RadianToDegree(C2d, Su);
+         C2dMapped = GeomConvert_Units::RadianToDegree(C2d, Su,
+      StepData_GlobalFactors::Intance().LengthFactor(), StepData_GlobalFactors::Intance().FactorRadianDegree());
        }
 //
 //     C2dMapped = C2d;  // cky : en remplacement de ce qui precede
index a76018e..73d353d 100644 (file)
@@ -1,2 +1,3 @@
 UnitsMethods.cxx
 UnitsMethods.hxx
+UnitsMethods_LengthUnit.hxx
index 6de4275..eba7796 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
-#include <Geom2d_BoundedCurve.hxx>
-#include <Geom2d_BSplineCurve.hxx>
-#include <Geom2d_Circle.hxx>
-#include <Geom2d_Conic.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom2d_Ellipse.hxx>
-#include <Geom2d_Hyperbola.hxx>
-#include <Geom2d_Line.hxx>
-#include <Geom2d_Parabola.hxx>
-#include <Geom2dConvert.hxx>
-#include <Geom_ConicalSurface.hxx>
-#include <Geom_CylindricalSurface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_SphericalSurface.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_SurfaceOfRevolution.hxx>
-#include <Geom_ToroidalSurface.hxx>
-#include <gp.hxx>
-#include <gp_Dir2d.hxx>
-#include <gp_GTrsf2d.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Trsf2d.hxx>
 #include <UnitsMethods.hxx>
 
-static Standard_Real theLengthFactor     = 1.;
-static Standard_Real thePlaneAngleFactor = 1.;
-static Standard_Real theSolidAngleFactor = 1.;
-static Standard_Boolean set3d            = Standard_True;
-
-static Standard_Real FactRD = 1.;
-static Standard_Real FactDR = 1.;
-
-static Standard_Real theCasCadeLengthUnit = 1.; // abv 28 Feb 00
-
-// ============================================================================
-// Method :
-// Purpose:
-// ============================================================================
-
-void UnitsMethods::InitializeFactors(const Standard_Real LengthFactor, const Standard_Real PlaneAngleFactor, const Standard_Real SolidAngleFactor)
-{
-  theLengthFactor     = LengthFactor;
-  thePlaneAngleFactor = PlaneAngleFactor;
-  theSolidAngleFactor = SolidAngleFactor;
-  FactRD = 1./PlaneAngleFactor; 
-  FactDR = PlaneAngleFactor;
-}
-
-// ============================================================================
-// Method :
-// Purpose:
-// ============================================================================
-
-Standard_Real UnitsMethods ::LengthFactor()
-{
-  return theLengthFactor;
-}
+#include <TCollection_AsciiString.hxx>
 
-// ============================================================================
-// Method :
-// Purpose:
-// ============================================================================
+static Standard_Real UnitsMethods_CascadeLengthUnit = 1.;
 
-Standard_Real UnitsMethods::PlaneAngleFactor()
+//=======================================================================
+//function : GetCasCadeLengthUnit
+//purpose  :
+//=======================================================================
+Standard_Real UnitsMethods::GetCasCadeLengthUnit(const UnitsMethods_LengthUnit theBaseUnit)
 {
-  return thePlaneAngleFactor;
+  return UnitsMethods_CascadeLengthUnit * GetLengthUnitScale(UnitsMethods_LengthUnit_Millimeter, theBaseUnit);
 }
 
-// ============================================================================
-// Method :
-// Purpose:
-// ============================================================================
-
-Standard_Real UnitsMethods::SolidAngleFactor()
+//=======================================================================
+//function : SetCasCadeLengthUnit
+//purpose  :
+//=======================================================================
+void UnitsMethods::SetCasCadeLengthUnit(const Standard_Real theUnitValue,
+                                        const UnitsMethods_LengthUnit theBaseUnit)
 {
-  return theSolidAngleFactor;
+  UnitsMethods_CascadeLengthUnit = theUnitValue * GetLengthUnitScale(theBaseUnit, UnitsMethods_LengthUnit_Millimeter);
 }
 
-// ============================================================================
-// Method :
-// Purpose:
-// ============================================================================
-
-void UnitsMethods::Set3dConversion(const Standard_Boolean B)
+//=======================================================================
+//function : SetCasCadeLengthUnit
+//purpose  :
+//=======================================================================
+void UnitsMethods::SetCasCadeLengthUnit(const Standard_Integer theUnit)
 {
-  set3d = B;
+  UnitsMethods_CascadeLengthUnit = GetLengthFactorValue(theUnit);
 }
 
-// ============================================================================
-// Method :
-// Purpose:
-// ============================================================================
-
-Standard_Boolean UnitsMethods::Convert3d()
+//=======================================================================
+//function : GetLengthFactorValue
+//purpose  :
+//=======================================================================
+Standard_Real UnitsMethods::GetLengthFactorValue(const Standard_Integer theUnit)
 {
-  return set3d;
+  switch (theUnit)
+  {
+    case  1: return 25.4; // inch
+    case  2: return 1.; // millimeter
+    case  4: return 304.8; // foot
+    case  5: return 1609344.; // mile
+    case  6: return 1000.; // meter
+    case  7: return 1000000.; // kilometer
+    case  8: return 0.0254; // mil (0.001 inch)
+    case  9: return 0.001; // micron
+    case 10: return 10.; // centimeter
+    case 11: return 0.0000254; // microinch
+    default: return 1.;
+  }
 }
 
-
-// ============================================================================
-// Method :
-// Purpose:
-// ============================================================================
-
-Handle(Geom2d_Curve) UnitsMethods::RadianToDegree
-                                   (const Handle(Geom2d_Curve)  & theCurve2d,
-                                   const Handle(Geom_Surface)  & theSurf)
+//=======================================================================
+//function : GetLengthUnitScale
+//purpose  :
+//=======================================================================
+Standard_Real UnitsMethods::GetLengthUnitScale(const UnitsMethods_LengthUnit theFromUnit,
+                                               const UnitsMethods_LengthUnit theToUnit)
 {
-  Handle(Geom2d_Curve) aCurve2d = Handle(Geom2d_Curve)::DownCast(theCurve2d->Copy());
-  Standard_Real uFact = 1.;
-  Standard_Real vFact = 1.; 
-  Standard_Real LengthFact  = 1. / UnitsMethods::LengthFactor();
-  Standard_Real AngleFact  = FactRD;    // 180./PI;  pilotable
-  
-  gp_Pnt2d    Pt1;
-  gp_XY       pXY;
-  gp_GTrsf2d  tMatu , tMatv;
-  
-  //  theSurf is a CylindricalSurface or a ConicalSurface or
-  //             a ToroidalSurface or a SphericalSurface or
-  //             a SurfaceOfRevolution
-  if (theSurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
-      theSurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
-    uFact = vFact = AngleFact;
-  }
-  else if (theSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
-    uFact = AngleFact;
-    vFact = LengthFact;
-  }
-  else if ( theSurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
-    uFact = AngleFact;
-  }
-  else if (theSurf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
-    Handle(Geom_ConicalSurface) conicS = 
-      Handle(Geom_ConicalSurface)::DownCast(theSurf);
-    Standard_Real semAng = conicS->SemiAngle();
-    uFact = AngleFact;
-    vFact = LengthFact * Cos(semAng);
-  }
-  else if (theSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
-    uFact = vFact = LengthFact;
-    if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
-        aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
-      gp_Trsf2d aT;
-      aT.SetScale (gp::Origin2d(), LengthFact);
-      aCurve2d->Transform (aT);
-      return aCurve2d;
-    }
-  }
-  else {
-//  debug
-//    std::cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType();
-    return aCurve2d;
-  }
-
-  if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
-    Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aCurve2d);
-
-    gp_Pnt2d myLoc = aLine2d->Location();
-    gp_Dir2d myDir = aLine2d->Direction();
-
-    gp_Pnt2d myNewLoc;
-    myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
-
-    gp_Dir2d myNewDir;
-    myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
-
-    Handle(Geom2d_Line) myNewLine2d = Handle(Geom2d_Line)::DownCast(aLine2d->Copy());
-    myNewLine2d->SetLocation(myNewLoc);
-    myNewLine2d->SetDirection(myNewDir);
-
-    return myNewLine2d;
-  }
-  else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
-    if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
-        aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
-      Handle(Geom2d_BSplineCurve) aBSpline2d = 
-       Geom2dConvert::CurveToBSplineCurve(aCurve2d);
-      aCurve2d = aBSpline2d;
-    } 
-    else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
-#ifdef OCCT_DEBUG
-      std::cout << "PCURVE of Parabola type in U or V Periodic Surface" << std::endl;
-      std::cout << "Parameters Not transformed to Degree" << std::endl;
-#endif
-    }
-    else if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
-#ifdef OCCT_DEBUG
-      std::cout << "PCURVE of Hyperbola type in U or V Periodic Surface" << std::endl;
-      std::cout << "Parameters Not transformed to Degree" << std::endl;
-#endif
-    }
-    
-  }
-  
-  // Compute affinity
-  tMatu.SetAffinity(gp::OY2d(), uFact);
-  tMatv.SetAffinity(gp::OX2d(), vFact);
-  
-  if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) {
-    if (aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
-      Handle(Geom2d_BSplineCurve) aBSpline2d = 
-       Handle(Geom2d_BSplineCurve)::DownCast(aCurve2d);
-      Handle(Geom2d_BSplineCurve) myNewBSpline2d = 
-       Handle(Geom2d_BSplineCurve)::DownCast(aBSpline2d->Copy());
-      Standard_Integer nbPol = aBSpline2d->NbPoles();
-      for (Standard_Integer i = 1; i<=nbPol ; i++) {
-       pXY = aBSpline2d->Pole(i).XY();
-       tMatu.Transforms(pXY);
-       tMatv.Transforms(pXY);
-       Pt1.SetXY(pXY);
-       myNewBSpline2d->SetPole(i, Pt1);
-      }
-      return myNewBSpline2d;
-    }
-    else {
-#ifdef OCCT_DEBUG
-      std::cout << "PCURVE of Other Types of Bounded Curve in U or V Periodic Surface" << std::endl;
-      std::cout << "Parameters Not transformed to Degree" << std::endl;
-#endif
-    }
-  }
-  return aCurve2d;
+  Standard_Real aVal1 = GetLengthFactorValue(theFromUnit);
+  Standard_Real aVal2 = GetLengthFactorValue(theToUnit);
+  return aVal1 / aVal2;
 }
 
-//=============================================================================
-// DegreeToRadian: 1. Change definition of the pcurves according to Length
-//                     Factor                  
-//                  2. STEP cylinder, torus, cone and sphere are parametrized
-//                     from 0 to 360 degree
-//                     Then pcurves parameter have to be transformed 
-//                     from DEGREE to RADIAN
-//=============================================================================
-
-Handle(Geom2d_Curve) UnitsMethods::DegreeToRadian
-                             (const Handle(Geom2d_Curve) & thePcurve,
-                             const Handle(Geom_Surface) & aSurface)
+//=======================================================================
+//function : GetLengthUnitByScale
+//purpose  :
+//=======================================================================
+UnitsMethods_LengthUnit UnitsMethods::GetLengthUnitByFactorValue(const Standard_Real theFactorValue,
+                                                                 const UnitsMethods_LengthUnit theBaseUnit)
 {
-  Handle(Geom2d_Curve)  aPcurve = Handle(Geom2d_Curve)::DownCast(thePcurve->Copy());
-  Standard_Real uFact       = 1.;
-  Standard_Real vFact       = 1.; 
-  Standard_Real LengthFact  = UnitsMethods::LengthFactor();
-  Standard_Real AngleFact   = FactDR;  // PI/180.;  pilotable
-
-  gp_Pnt2d    Pt1;
-  gp_XY       pXY;
-  gp_GTrsf2d  tMatu , tMatv;
-
-  // What to change ??
-
-  if (aSurface->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
-      aSurface->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
-    uFact = vFact = AngleFact;
+  const Standard_Real aPreci = 1.e-6;
+  const Standard_Real aValue = theFactorValue * GetLengthUnitScale(theBaseUnit, UnitsMethods_LengthUnit_Millimeter);
+  if (Abs(1. - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Millimeter;
   }
-  else if (aSurface->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
-    uFact = AngleFact;
-    vFact = LengthFact;
+  else if (Abs(25.4 - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Inch;
   }
-  else if ( aSurface->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
-    uFact = AngleFact;
+  else if (Abs(304.8 - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Foot;
   }
-  else if (aSurface->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
-    Handle(Geom_ConicalSurface) conicS = 
-      Handle(Geom_ConicalSurface)::DownCast(aSurface);
-    Standard_Real semAng = conicS->SemiAngle();
-    uFact = AngleFact;
-    vFact = LengthFact / Cos(semAng);
+  else if (Abs(1609344. - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Mile;
   }
-  else if (aSurface->IsKind(STANDARD_TYPE(Geom_Plane))) {
-    uFact = vFact = LengthFact;
-    if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) ||
-        aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
-      gp_Trsf2d aT;
-      aT.SetScale (gp::Origin2d(), LengthFact);
-      aPcurve->Transform (aT);
-      return aPcurve;
-    }
+  else if (Abs(1000. - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Meter;
   }
-  else {
-//  debug
-//    std::cout <<"UnitsMethods: SurfType = "<< aSurface->DynamicType();
-    return aPcurve;
+  else if (Abs(1000000. - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Kilometer;
   }
-
-  if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
-    if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) || 
-       aPcurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
-      Handle(Geom2d_BSplineCurve) aBSpline2d = 
-       Geom2dConvert::CurveToBSplineCurve(aPcurve);
-      aPcurve = aBSpline2d;
-    }
-    else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
-#ifdef OCCT_DEBUG
-      std::cout << "PCURVE of Parabola type" << std::endl;
-      std::cout << "Parameters Not Yet transformed according to LengthUnit" << std::endl;
-#endif
-      return aPcurve;
-    }
-    else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
-#ifdef OCCT_DEBUG
-      std::cout << "PCURVE of Hyperbola type" << std::endl;
-      std::cout << "Parameters Not Yet transformed according to LengthUnit" << std::endl;
-#endif
-      return aPcurve;
-    }
+  else if (Abs(0.0254 - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Mil;
   }
-
-  // Compute affinity
-
-  tMatu.SetAffinity(gp::OY2d(), uFact);
-  tMatv.SetAffinity(gp::OX2d(), vFact);
-
-  if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_Line))) {
-    Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(aPcurve);
-
-    gp_Pnt2d myLoc = aLine2d->Location();
-    gp_Dir2d myDir = aLine2d->Direction();
-
-    gp_Pnt2d myNewLoc;
-    myNewLoc.SetCoord(myLoc.X()*uFact, myLoc.Y()*vFact);
-
-    gp_Dir2d myNewDir;
-    myNewDir.SetCoord(myDir.X()*uFact, myDir.Y()*vFact);
-
-    aLine2d->SetLocation(myNewLoc);
-    aLine2d->SetDirection(myNewDir);
-
-    aPcurve = aLine2d;
+  else if (Abs(0.001 - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Micron;
   }
-  else if (aPcurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
-    Handle(Geom2d_BSplineCurve) aBSpline2d = 
-      Handle(Geom2d_BSplineCurve)::DownCast(aPcurve);
-
-// transform the Poles of the BSplineCurve according to AngleFact and LengthFact
-
-    Standard_Integer nbPol = aBSpline2d->NbPoles();
-    for (Standard_Integer i = 1; i<=nbPol ; i++) {
-      pXY = aBSpline2d->Pole(i).XY();
-      tMatu.Transforms(pXY);
-      tMatv.Transforms(pXY);
-      Pt1.SetXY(pXY);
-      aBSpline2d->SetPole(i, Pt1);
-    }
-    aPcurve = aBSpline2d;
+  else if (Abs(10. - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Centimeter;
   }
-  else {
-#ifdef OCCT_DEBUG
-    std::cout << "DegreeToRadian : Type " << aPcurve->DynamicType();
-    std::cout << " not yet implemented" << std::endl;
-#endif
+  else if (Abs(0.0000254 - aValue) < aPreci)
+  {
+    return UnitsMethods_LengthUnit_Microinch;
   }
-  return aPcurve;
-}
-
-// ============================================================================
-// Method :
-// Purpose:
-// ============================================================================
-
-Handle(Geom2d_Curve) UnitsMethods::MirrorPCurve
-(const Handle(Geom2d_Curve) & C2d) 
-{
-  Handle(Geom2d_Curve) theMirrored = 
-    Handle(Geom2d_Curve)::DownCast(C2d->Copy());
-  
-  gp_Trsf2d T;
-  gp_Pnt2d  Loc(0.,0.);
-  gp_Dir2d  Dir(1.,0.);
-  gp_Ax2d   ax2(Loc, Dir);
-  T.SetMirror(ax2);
-  theMirrored->Transform(T);
-  return theMirrored;
+  return UnitsMethods_LengthUnit_Undefined;
 }
 
 //=======================================================================
-//function : GetCasCadeLengthUnit
-//purpose  : 
+//function : DumpLengthUnit
+//purpose  :
 //=======================================================================
-
-Standard_Real UnitsMethods::GetCasCadeLengthUnit () 
+Standard_CString UnitsMethods::DumpLengthUnit(const UnitsMethods_LengthUnit theUnit)
 {
-  return theCasCadeLengthUnit;
+  switch (theUnit)
+  {
+    case UnitsMethods_LengthUnit_Millimeter: return "mm";
+    case UnitsMethods_LengthUnit_Meter:      return "m";
+    case UnitsMethods_LengthUnit_Centimeter: return "cm";
+    case UnitsMethods_LengthUnit_Kilometer:  return "km";
+    case UnitsMethods_LengthUnit_Micron:     return "micron";
+    case UnitsMethods_LengthUnit_Inch:       return "in";
+    case UnitsMethods_LengthUnit_Mil:        return "min";
+    case UnitsMethods_LengthUnit_Microinch:  return "nin";
+    case UnitsMethods_LengthUnit_Foot:       return "ft";
+    case UnitsMethods_LengthUnit_Mile:       return "stat.mile";
+    default: return "UNDEFINED";
+  }
 }
 
 //=======================================================================
-//function : SetCasCadeLengthUnit
-//purpose  : 
+//function : DumpLengthUnit
+//purpose  :
 //=======================================================================
-
-void UnitsMethods::SetCasCadeLengthUnit (const Standard_Integer unit) 
+Standard_CString UnitsMethods::DumpLengthUnit(const Standard_Real theScaleFactor,
+                                              const UnitsMethods_LengthUnit theBaseUnit)
 {
-  theCasCadeLengthUnit = UnitsMethods::GetLengthFactorValue ( unit );
+  const UnitsMethods_LengthUnit aUnit = GetLengthUnitByFactorValue(theScaleFactor, theBaseUnit);
+  return DumpLengthUnit(aUnit);
 }
 
 //=======================================================================
-//function : GetLengthFactorValue
-//purpose  : 
+//function : LengthUnitFromString
+//purpose  :
 //=======================================================================
-
-Standard_Real UnitsMethods::GetLengthFactorValue (const Standard_Integer par) 
+UnitsMethods_LengthUnit UnitsMethods::LengthUnitFromString(Standard_CString theStr,
+                                                           const Standard_Boolean theCaseSensitive)
 {
-  switch ( par ) {
-  case  1 : return 25.4; // inch
-  case  2 : return 1.; // millimeter
-  
-  case  4 : return 304.8; // foot
-  case  5 : return 1609344.; // mile
-  case  6 : return 1000.; // meter
-  case  7 : return 1000000.; // kilometer
-  case  8 : return 0.0254; // mil (0.001 inch)
-  case  9 : return 0.001; // micron
-  case 10 : return 10.; // centimeter
-  case 11 : return 0.0000254; // microinch
-  default : return 1.;
+  TCollection_AsciiString aStr(theStr);
+  if (!theCaseSensitive)
+  {
+    aStr.LowerCase();
+  }
+  if (aStr.IsEqual("mm"))
+  {
+    return UnitsMethods_LengthUnit_Millimeter;
+  }
+  else if (aStr.IsEqual("m"))
+  {
+    return UnitsMethods_LengthUnit_Meter;
+  }
+  else if (aStr.IsEqual("cm"))
+  {
+    return UnitsMethods_LengthUnit_Centimeter;
+  }
+  else if (aStr.IsEqual("km"))
+  {
+    return UnitsMethods_LengthUnit_Kilometer;
+  }
+  else if (aStr.IsEqual("micron"))
+  {
+    return UnitsMethods_LengthUnit_Micron;
+  }
+  else if (aStr.IsEqual("in"))
+  {
+    return UnitsMethods_LengthUnit_Inch;
+  }
+  else if (aStr.IsEqual("min"))
+  {
+    return UnitsMethods_LengthUnit_Mil;
+  }
+  else if (aStr.IsEqual("nin"))
+  {
+    return UnitsMethods_LengthUnit_Microinch;
+  }
+  else if (aStr.IsEqual("ft"))
+  {
+    return UnitsMethods_LengthUnit_Foot;
+  }
+  else if (aStr.IsEqual("stat.mile"))
+  {
+    return UnitsMethods_LengthUnit_Mile;
+  }
+  else
+  {
+    return UnitsMethods_LengthUnit_Undefined;
   }
 }
-
index 621c239..88ae982 100644 (file)
@@ -1,7 +1,4 @@
-// Created on: 1994-09-29
-// Created by: Dieter THIEMANN
-// Copyright (c) 1994-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// Copyright (c) 2021 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
+#include <UnitsMethods_LengthUnit.hxx>
 
-#include <Standard_Real.hxx>
-#include <Standard_Boolean.hxx>
-#include <Standard_Integer.hxx>
-class Geom2d_Curve;
-class Geom_Surface;
-
-
-
-class UnitsMethods 
+//! Class for using global units variables
+class UnitsMethods
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
-  
-  //! Initializes the 3 factors for the conversion of
-  //! units
-  Standard_EXPORT static void InitializeFactors (const Standard_Real LengthFactor, const Standard_Real PlaneAngleFactor, const Standard_Real SolidAngleFactor);
-  
-  Standard_EXPORT static Standard_Real LengthFactor();
-  
-  Standard_EXPORT static Standard_Real PlaneAngleFactor();
-  
-  Standard_EXPORT static Standard_Real SolidAngleFactor();
-  
-  Standard_EXPORT static void Set3dConversion (const Standard_Boolean B);
-  
-  Standard_EXPORT static Standard_Boolean Convert3d();
-  
-  Standard_EXPORT static Handle(Geom2d_Curve) RadianToDegree (const Handle(Geom2d_Curve)& C, const Handle(Geom_Surface)& S);
-  
-  Standard_EXPORT static Handle(Geom2d_Curve) DegreeToRadian (const Handle(Geom2d_Curve)& C, const Handle(Geom_Surface)& S);
-  
-  Standard_EXPORT static Handle(Geom2d_Curve) MirrorPCurve (const Handle(Geom2d_Curve)& C);
-  
-  //! Returns value of unit encoded by parameter param
-  //! (integer value denoting unit, as described in IGES
-  //! standard) in millimeters
-  Standard_EXPORT static Standard_Real GetLengthFactorValue (const Standard_Integer param);
-  
-  //! Returns value of current internal unit for CASCADE
-  //! in millemeters
-  Standard_EXPORT static Standard_Real GetCasCadeLengthUnit();
-  
-  //! Sets value of current internal unit for CASCADE
-  //! by parameter param (integer value denoting unit,
-  //! as described in IGES standard)
-  //! GetCasCadeLengthUnit() will then return value
-  //! equal to GetLengthFactorValue(param)
-  Standard_EXPORT static void SetCasCadeLengthUnit (const Standard_Integer param);
-
-
-
-
-protected:
 
+  //! Returns value of unit encoded by parameter theUnit
+  //! (integer value denoting unit, as described in IGES
+  //! standard) in millimeters by default
+  Standard_EXPORT static Standard_Real GetLengthFactorValue(const Standard_Integer theUnit);
 
+  //! Returns value of current internal unit for CASCADE
+  //! in millemeters by default
+  Standard_EXPORT static Standard_Real GetCasCadeLengthUnit(const UnitsMethods_LengthUnit theBaseUnit = UnitsMethods_LengthUnit_Millimeter);
 
+  //! Sets value of current internal unit for CASCADE
+  Standard_EXPORT static void SetCasCadeLengthUnit(const Standard_Real theUnitValue,
+    const UnitsMethods_LengthUnit theBaseUnit = UnitsMethods_LengthUnit_Millimeter);
 
+  //! Sets value of current internal unit for CASCADE
+  //! by parameter theUnit (integer value denoting unit,
+  //! as described in IGES standard)
+  Standard_EXPORT static void SetCasCadeLengthUnit(const Standard_Integer theUnit);
 
-private:
+  //! Returns the scale factor for switch from first given unit to second given unit
+  Standard_EXPORT static Standard_Real GetLengthUnitScale(const UnitsMethods_LengthUnit theFromUnit,
+                                                          const UnitsMethods_LengthUnit theToUnit);
 
+  //! Returns the enumeration corresponding to the given scale factor
+  Standard_EXPORT static UnitsMethods_LengthUnit GetLengthUnitByFactorValue(const Standard_Real theFactorValue,
+    const UnitsMethods_LengthUnit theBaseUnit = UnitsMethods_LengthUnit_Millimeter);
 
+  //! Returns string name for the given scale factor
+  Standard_EXPORT static Standard_CString DumpLengthUnit(const Standard_Real theScaleFactor,
+    const UnitsMethods_LengthUnit theBaseUnit = UnitsMethods_LengthUnit_Millimeter);
 
+  //! Returns string for the given value of LengthUnit
+  Standard_EXPORT static Standard_CString DumpLengthUnit(const UnitsMethods_LengthUnit theUnit);
 
+  //! Make conversion of given string to value of LengthUnit
+  Standard_EXPORT static UnitsMethods_LengthUnit LengthUnitFromString(Standard_CString theStr,
+                                                                      const Standard_Boolean theCaseSensitive);
 
 };
 
-
-
-
-
-
-
 #endif // _UnitsMethods_HeaderFile
diff --git a/src/UnitsMethods/UnitsMethods_LengthUnit.hxx b/src/UnitsMethods/UnitsMethods_LengthUnit.hxx
new file mode 100644 (file)
index 0000000..28e6de3
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright (c) 2021 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.
+
+#ifndef _UnitsMethods_LengthUnit_HeaderFile
+#define _UnitsMethods_LengthUnit_HeaderFile
+
+//! The Enumeration describes possible values for length units
+enum UnitsMethods_LengthUnit
+{
+  UnitsMethods_LengthUnit_Undefined = 0,   // 1.
+  UnitsMethods_LengthUnit_Inch = 1,        // 25.4
+  UnitsMethods_LengthUnit_Millimeter = 2,  // 1.
+  UnitsMethods_LengthUnit_Foot = 4,        // 304.8
+  UnitsMethods_LengthUnit_Mile = 5,        // 1609344.
+  UnitsMethods_LengthUnit_Meter = 6,       // 1000.
+  UnitsMethods_LengthUnit_Kilometer = 7,   // 1000000.
+  UnitsMethods_LengthUnit_Mil = 8,         // (0.001 inch) // 0.0254
+  UnitsMethods_LengthUnit_Micron = 9,      // 0.001
+  UnitsMethods_LengthUnit_Centimeter = 10, // 10.
+  UnitsMethods_LengthUnit_Microinch = 11   // 0.0000254
+};
+
+#endif // _UnitsMethods_LengthUnit
index 5b3030f..f2af588 100755 (executable)
@@ -39,6 +39,8 @@ XCAFDoc_GraphNode.hxx
 XCAFDoc_GraphNodeSequence.hxx
 XCAFDoc_LayerTool.cxx
 XCAFDoc_LayerTool.hxx
+XCAFDoc_LengthUnit.cxx
+XCAFDoc_LengthUnit.hxx
 XCAFDoc_Location.cxx
 XCAFDoc_Location.hxx
 XCAFDoc_Material.cxx
index 737000e..36b6388 100755 (executable)
@@ -47,3 +47,4 @@ efd212f4-6dfd-11d4-b9c8-0060b0ee281b: LayerTool attribute
 efd212f5-6dfd-11d4-b9c8-0060b0ee281b: GraphNode attribute
 efd212f6-6dfd-11d4-b9c8-0060b0ee281b
 efd212f7-6dfd-11d4-b9c8-0060b0ee281b
+efd212f8-6dfd-11d4-b9c8-0060b0ee281b: LengthUnit attribute
index b97a20f..88ec31a 100644 (file)
@@ -28,6 +28,7 @@
 #include <TDataStd_ByteArray.hxx>
 #include <TDataStd_IntegerArray.hxx>
 #include <TDataStd_Name.hxx>
+#include <XCAFDoc_LengthUnit.hxx>
 #include <TDataStd_RealArray.hxx>
 #include <TDataStd_Real.hxx>
 #include <TDataStd_TreeNode.hxx>
@@ -395,6 +396,11 @@ TCollection_AsciiString XCAFDoc::AttributeInfo (const Handle(TDF_Attribute)& the
     Handle(TDataStd_AsciiString) val = Handle(TDataStd_AsciiString)::DownCast ( theAtt );
     anInfo = TCollection_AsciiString ( val->Get(), '?' );
   }
+  else if (theAtt->IsKind(STANDARD_TYPE(XCAFDoc_LengthUnit))) {
+    Handle(XCAFDoc_LengthUnit) aVal = Handle(XCAFDoc_LengthUnit)::DownCast(theAtt);
+    anInfo = TCollection_AsciiString(aVal->GetUnitValue());
+    anInfo += " ";  anInfo += aVal->GetUnitName();
+  }
   else if ( theAtt->IsKind(STANDARD_TYPE(TDataStd_IntegerArray)) ) {
     Handle(TDataStd_IntegerArray) val = Handle(TDataStd_IntegerArray)::DownCast ( theAtt );
     for ( Standard_Integer j=val->Lower(); j <= val->Upper(); j++ ) {
index 5a662ca..02c6fb0 100644 (file)
 #include <XCAFDoc_ClippingPlaneTool.hxx>
 #include <XCAFDoc_DimTolTool.hxx>
 #include <XCAFDoc_LayerTool.hxx>
+#include <XCAFDoc_LengthUnit.hxx>
 #include <XCAFDoc_MaterialTool.hxx>
 #include <XCAFDoc_NotesTool.hxx>
 #include <XCAFDoc_ShapeTool.hxx>
 #include <XCAFDoc_ViewTool.hxx>
 #include <XCAFDoc_VisMaterialTool.hxx>
+#include <UnitsMethods.hxx>
 
 IMPLEMENT_DERIVED_ATTRIBUTE_WITH_TYPE(XCAFDoc_DocumentTool,TDataStd_GenericEmpty,"xcaf","DocumentTool")
 
@@ -329,6 +331,76 @@ Handle(XCAFDoc_NotesTool) XCAFDoc_DocumentTool::NotesTool(const TDF_Label& acces
   return XCAFDoc_NotesTool::Set(NotesLabel(acces));
 }
 
+//=======================================================================
+//function : GetLengthUnit
+//purpose  :
+//=======================================================================
+Standard_Boolean XCAFDoc_DocumentTool::GetLengthUnit(const Handle(TDocStd_Document)& theDoc,
+                                                     Standard_Real& theResult,
+                                                     const UnitsMethods_LengthUnit theBaseUnit)
+{
+  if (theDoc.IsNull())
+  {
+    return Standard_False;
+  }
+  Handle(XCAFDoc_LengthUnit) aLengthAttr;
+  if (theDoc->Main().Root().FindAttribute(XCAFDoc_LengthUnit::GetID(), aLengthAttr))
+  {
+    theResult = aLengthAttr->GetUnitValue() *
+      UnitsMethods::GetLengthUnitScale(UnitsMethods_LengthUnit_Meter, theBaseUnit);
+    return Standard_True;
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : GetLengthUnit
+//purpose  :
+//=======================================================================
+Standard_Boolean XCAFDoc_DocumentTool::GetLengthUnit(const Handle(TDocStd_Document)& theDoc,
+                                                     Standard_Real& theResult)
+{
+  if (theDoc.IsNull())
+  {
+    return Standard_False;
+  }
+  Handle(XCAFDoc_LengthUnit) aLengthAttr;
+  if (theDoc->Main().Root().FindAttribute(XCAFDoc_LengthUnit::GetID(), aLengthAttr))
+  {
+    theResult = aLengthAttr->GetUnitValue();
+    return Standard_True;
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : SetLengthUnit
+//purpose  :
+//=======================================================================
+void XCAFDoc_DocumentTool::SetLengthUnit(const Handle(TDocStd_Document)& theDoc,
+                                         const Standard_Real theUnitValue,
+                                         const UnitsMethods_LengthUnit theBaseUnit)
+{
+  // Sets length unit info
+  TCollection_AsciiString aUnitName = UnitsMethods::DumpLengthUnit(theUnitValue, theBaseUnit);
+  const Standard_Real aScaleFactor = theUnitValue *
+    UnitsMethods::GetLengthUnitScale(theBaseUnit, UnitsMethods_LengthUnit_Meter);
+  XCAFDoc_LengthUnit::Set(theDoc->Main().Root(), aUnitName, aScaleFactor);
+}
+
+//=======================================================================
+//function : SetLengthUnit
+//purpose  :
+//=======================================================================
+void XCAFDoc_DocumentTool::SetLengthUnit(const Handle(TDocStd_Document)& theDoc,
+                                         const Standard_Real theUnitValue)
+{
+  // Sets length unit info
+  TCollection_AsciiString aUnitName =
+    UnitsMethods::DumpLengthUnit(theUnitValue, UnitsMethods_LengthUnit_Meter);
+  XCAFDoc_LengthUnit::Set(theDoc->Main().Root(), aUnitName, theUnitValue);
+}
+
 //=======================================================================
 //function : ID
 //purpose  : 
index 65a6c7a..ac9fe2b 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <TDataStd_GenericEmpty.hxx>
 #include <Standard_Boolean.hxx>
+#include <UnitsMethods_LengthUnit.hxx>
+
 class Standard_GUID;
 class TDF_Label;
 class TDocStd_Document;
@@ -120,6 +122,26 @@ public:
   //! Creates (if it does not exist) NotesTool attribute on NotesLabel().
   Standard_EXPORT static Handle(XCAFDoc_NotesTool) NotesTool(const TDF_Label& acces);
 
+  //! Returns value of current internal unit for the document
+  //! converted to base unit type.
+  Standard_EXPORT static Standard_Boolean GetLengthUnit(const Handle(TDocStd_Document)& theDoc,
+                                                        Standard_Real& theResut,
+                                                        const UnitsMethods_LengthUnit theBaseUnit);
+
+  //! Returns value of current internal unit for the document in meter
+  Standard_EXPORT static Standard_Boolean GetLengthUnit(const Handle(TDocStd_Document)& theDoc,
+                                                        Standard_Real& theResut);
+
+  //! Sets value of current internal unit to the document in meter
+  Standard_EXPORT static void SetLengthUnit(const Handle(TDocStd_Document)& theDoc,
+                                            const Standard_Real theUnitValue);
+
+  //! Sets value of current internal unit to the document
+  //! @param theUnitValue must be represented in the base unit type
+  Standard_EXPORT static void SetLengthUnit(const Handle(TDocStd_Document)& theDoc,
+                                            const Standard_Real theUnitValue,
+                                            const UnitsMethods_LengthUnit theBaseUnit);
+
 public:
 
   Standard_EXPORT XCAFDoc_DocumentTool();
diff --git a/src/XCAFDoc/XCAFDoc_LengthUnit.cxx b/src/XCAFDoc/XCAFDoc_LengthUnit.cxx
new file mode 100644 (file)
index 0000000..536dbff
--- /dev/null
@@ -0,0 +1,158 @@
+// Copyright (c) 2021 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.
+
+#include <XCAFDoc_LengthUnit.hxx>
+
+#include <Standard_Dump.hxx>
+#include <Standard_GUID.hxx>
+#include <Standard_Type.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TDF_Attribute.hxx>
+#include <TDF_Label.hxx>
+#include <UnitsMethods.hxx>
+
+IMPLEMENT_DERIVED_ATTRIBUTE_WITH_TYPE(XCAFDoc_LengthUnit, TDF_Attribute, "xcaf", "LengthUnit")
+
+//=======================================================================
+//function : XCAFDoc_LengthUnit
+//purpose  :
+//=======================================================================
+XCAFDoc_LengthUnit::XCAFDoc_LengthUnit() : TDF_Attribute(), myUnitScaleValue(1.)
+{}
+
+//=======================================================================
+//function : Set
+//purpose  :
+//=======================================================================
+Handle(XCAFDoc_LengthUnit) XCAFDoc_LengthUnit::Set(const TDF_Label& theLabel,
+                                                     const TCollection_AsciiString& theUnitName,
+                                                     const Standard_Real theUnitValue)
+{
+  return Set(theLabel, GetID(), theUnitName, theUnitValue);
+}
+
+//=======================================================================
+//function : Set
+//purpose  :
+//=======================================================================
+Handle(XCAFDoc_LengthUnit) XCAFDoc_LengthUnit::Set(const TDF_Label& theLabel,
+                                                     const Standard_Real theUnitValue)
+{
+  TCollection_AsciiString aUnitName = UnitsMethods::DumpLengthUnit(theUnitValue, UnitsMethods_LengthUnit_Meter);
+  return Set(theLabel, GetID(), aUnitName, theUnitValue);
+}
+
+//=======================================================================
+//function : Set
+//purpose  :
+//=======================================================================
+Handle(XCAFDoc_LengthUnit) XCAFDoc_LengthUnit::Set(const TDF_Label& theLabel,
+                                                     const Standard_GUID& theGUID,
+                                                     const TCollection_AsciiString& theUnitName,
+                                                     const Standard_Real theUnitValue)
+{
+  Handle(XCAFDoc_LengthUnit) A;
+  if (!theLabel.FindAttribute(theGUID, A)) {
+    A = new XCAFDoc_LengthUnit();
+    A->SetID(theGUID);
+    theLabel.AddAttribute(A);
+  }
+  A->Set(theUnitName, theUnitValue);
+  return A;
+}
+
+//=======================================================================
+//function : Set
+//purpose  :
+//=======================================================================
+void XCAFDoc_LengthUnit::Set(const TCollection_AsciiString& theUnitName,
+                              const Standard_Real theUnitValue)
+{
+  Backup();
+  myUnitName = theUnitName;
+  myUnitScaleValue = theUnitValue;
+}
+
+//=======================================================================
+//function : GetID
+//purpose  :
+//=======================================================================
+const Standard_GUID& XCAFDoc_LengthUnit::GetID()
+{
+  static const Standard_GUID theGUID ("efd212f8-6dfd-11d4-b9c8-0060b0ee281b");
+  return theGUID;
+}
+
+//=======================================================================
+//function : ID
+//purpose  : 
+//=======================================================================
+
+const Standard_GUID& XCAFDoc_LengthUnit::ID() const
+{
+  return GetID();
+}
+
+//=======================================================================
+//function : Restore
+//purpose  : 
+//=======================================================================
+
+void XCAFDoc_LengthUnit::Restore(const Handle(TDF_Attribute)& theWith)
+{
+  Handle(XCAFDoc_LengthUnit) anAttr = Handle(XCAFDoc_LengthUnit)::DownCast(theWith);
+  myUnitName = anAttr->GetUnitName();
+  myUnitScaleValue = anAttr->GetUnitValue();
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : 
+//=======================================================================
+void XCAFDoc_LengthUnit::Paste(const Handle(TDF_Attribute)& theInto,
+  const Handle(TDF_RelocationTable)&  theRT ) const
+{
+  (void)theRT;
+  Handle(XCAFDoc_LengthUnit) anAttr = Handle(XCAFDoc_LengthUnit)::DownCast(theInto);
+  anAttr->Set(myUnitName, myUnitScaleValue);
+}
+
+//=======================================================================
+//function : Dump
+//purpose  : 
+//=======================================================================
+Standard_OStream& XCAFDoc_LengthUnit::Dump(Standard_OStream& theOS) const
+{
+  Standard_OStream& anOS = TDF_Attribute::Dump(theOS);
+  anOS << " UnitName=|" << myUnitName << "|";
+  anOS << " UnitScaleValue=|" << myUnitScaleValue << "|";
+  Standard_Character aSGUID[Standard_GUID_SIZE_ALLOC];
+  ID().ToCString(aSGUID);
+  anOS << aSGUID << "|" << std::endl;
+  return anOS;
+}
+
+//=======================================================================
+//function : DumpJson
+//purpose  : 
+//=======================================================================
+void XCAFDoc_LengthUnit::DumpJson(Standard_OStream& theOStream, Standard_Integer theDepth) const
+{
+  OCCT_DUMP_TRANSIENT_CLASS_BEGIN(theOStream)
+
+  OCCT_DUMP_BASE_CLASS(theOStream, theDepth, TDF_Attribute)
+
+  OCCT_DUMP_FIELD_VALUES_STRING(theOStream, "UnitName", 1, &myUnitName)
+
+  OCCT_DUMP_FIELD_VALUES_NUMERICAL(theOStream, "UnitScaleValue", 1, &myUnitScaleValue)
+}
diff --git a/src/XCAFDoc/XCAFDoc_LengthUnit.hxx b/src/XCAFDoc/XCAFDoc_LengthUnit.hxx
new file mode 100644 (file)
index 0000000..17e612c
--- /dev/null
@@ -0,0 +1,104 @@
+// Copyright (c) 2021 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.
+
+#ifndef _XCAFDoc_LengthUnit_HeaderFile
+#define _XCAFDoc_LengthUnit_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+#include <TDF_DerivedAttribute.hxx>
+
+#include <TCollection_AsciiString.hxx>
+#include <TDF_Attribute.hxx>
+#include <Standard_Boolean.hxx>
+#include <Standard_OStream.hxx>
+#include <Standard_GUID.hxx>
+
+class TDF_Label;
+class TCollection_AsciiString;
+class TDF_Attribute;
+class TDF_RelocationTable;
+
+
+class XCAFDoc_LengthUnit;
+DEFINE_STANDARD_HANDLE(XCAFDoc_LengthUnit, TDF_Attribute)
+
+//! Used to define a Length Unit attribute containing a length unit info
+class XCAFDoc_LengthUnit : public TDF_Attribute
+{
+
+public:
+
+  //! Returns the GUID of the attribute.
+  Standard_EXPORT static const Standard_GUID& GetID();
+
+  //! Finds or creates a LengthUnit attribute
+  //! @param theUnitName - name of the unit: mm, m, cm, km, micron, in, min, nin, ft, stat.mile
+  //! @param theUnitValue - length scale factor to meter
+  //! The LengthUnit attribute is returned.
+  Standard_EXPORT static Handle(XCAFDoc_LengthUnit) Set(const TDF_Label& theLabel,
+                                                         const TCollection_AsciiString& theUnitName,
+                                                         const Standard_Real theUnitValue);
+
+  //! Finds or creates a LengthUnit attribute
+  //! @param theUnitValue - length scale factor to meter
+  //! The LengthUnit attribute is returned.
+  Standard_EXPORT static Handle(XCAFDoc_LengthUnit) Set(const TDF_Label& theLabel,
+                                                         const Standard_Real theUnitValue);
+
+  //! Finds, or creates, a LengthUnit attribute with explicit user defined GUID
+  //! @param theUnitName - name of the unit: mm, m, cm, km, micron, in, min, nin, ft, stat.mile
+  //! @param theUnitValue - length scale factor to meter
+  //! The LengthUnit attribute is returned
+  Standard_EXPORT static Handle(XCAFDoc_LengthUnit) Set(const TDF_Label& theLabel,
+                                                         const Standard_GUID& theGUID,
+                                                         const TCollection_AsciiString& theUnitName,
+                                                         const Standard_Real theUnitValue);
+
+  //! Creates a LengthUnit attribute
+  //! @param theUnitName - name of the unit: mm, m, cm, km, micron, in, min, nin, ft, stat.mile
+  //! @param theUnitValue - length scale factor to meter
+  Standard_EXPORT void Set(const TCollection_AsciiString& theUnitName,
+                           const Standard_Real theUnitValue);
+  
+  //! Length unit description (could be arbitrary text)
+  const TCollection_AsciiString& GetUnitName() const { return myUnitName; }
+
+  //! Returns length unit scale factor to meter
+  Standard_Real GetUnitValue() const { return myUnitScaleValue; }
+
+  Standard_EXPORT Standard_Boolean IsEmpty() const { return myUnitName.IsEmpty(); }
+
+  Standard_EXPORT XCAFDoc_LengthUnit();
+
+  Standard_EXPORT virtual const Standard_GUID& ID() const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual void Restore(const Handle(TDF_Attribute)& theWith) Standard_OVERRIDE;
+
+  Standard_EXPORT virtual void Paste(const Handle(TDF_Attribute)& theInto, const Handle(TDF_RelocationTable)& theRT) const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual Standard_OStream& Dump(Standard_OStream& anOS) const Standard_OVERRIDE;
+
+  //! Dumps the content of me into the stream
+  Standard_EXPORT virtual void DumpJson(Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
+
+
+  DEFINE_DERIVED_ATTRIBUTE(XCAFDoc_LengthUnit, TDF_Attribute)
+
+private:
+
+  Standard_Real myUnitScaleValue;
+  TCollection_AsciiString myUnitName;
+};
+
+#endif // _XCAFDoc_LengthUnit_HeaderFile
index bb9ecf0..e3a278f 100644 (file)
@@ -41,6 +41,7 @@
 #include <TDataStd_Comment.hxx>
 #include <TDataStd_Integer.hxx>
 #include <TDataStd_IntegerArray.hxx>
+#include <XCAFDoc_LengthUnit.hxx>
 #include <TDataStd_Name.hxx>
 #include <TDataStd_Real.hxx>
 #include <TDataStd_RealArray.hxx>
@@ -96,6 +97,7 @@
 #include <XSDRAW.hxx>
 #include <XSDRAWIGES.hxx>
 #include <XSDRAWSTEP.hxx>
+#include <UnitsMethods.hxx>
 
 #include <BinXCAFDrivers.hxx>
 #include <XmlXCAFDrivers.hxx>
@@ -1063,6 +1065,93 @@ static Standard_Integer XSetTransparency (Draw_Interpretor& di, Standard_Integer
   return 0;
 }
 
+//=======================================================================
+//function : setLengthUnit
+//purpose  :
+//=======================================================================
+static Standard_Integer setLengthUnit(Draw_Interpretor& di,
+                                      Standard_Integer argc,
+                                      const char** argv)
+{
+  if (argc != 3)
+  {
+    di << "Use: " << argv[0] << " Doc {unitName|scaleFactor} \n";
+    return 1;
+  }
+
+  Handle(TDocStd_Document) aDoc;
+  DDocStd::GetDocument(argv[1], aDoc);
+  if (aDoc.IsNull())
+  {
+    di << "Error: " << argv[1] << " is not a document\n"; return 1;
+  }
+
+  TCollection_AsciiString anUnit(argv[2]);
+  Standard_Real anUnitValue = 1.;
+  TCollection_AsciiString anUnitName;
+  if (!anUnit.IsRealValue(true))
+  {
+    UnitsMethods_LengthUnit aTypeUnit = UnitsMethods::LengthUnitFromString(anUnit.ToCString(), Standard_False);
+    if (aTypeUnit == UnitsMethods_LengthUnit_Undefined)
+    {
+      di << "Error: " << anUnit
+         << " is incorrect unit, use m, mm, km, cm, micron, mille, in, min, nin, ft, stat.mile\n";
+      return 1;
+    }
+    anUnitName = anUnit;
+    anUnitValue = UnitsMethods::GetLengthFactorValue(aTypeUnit) * 0.001;
+  }
+  else
+  {
+    anUnitValue = anUnit.RealValue();
+    anUnitName = UnitsMethods::DumpLengthUnit(anUnitValue, UnitsMethods_LengthUnit_Meter);
+  }
+  XCAFDoc_LengthUnit::Set(aDoc->Main().Root(), anUnitName, anUnitValue);
+  return 0;
+}
+
+//=======================================================================
+//function : dumpLengthUnit
+//purpose  :
+//=======================================================================
+static Standard_Integer dumpLengthUnit(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
+{
+  if (argc != 2 && argc != 3) {
+    di << "Use: " << argv[0] << " Doc [-scale]\n";
+    return 1;
+  }
+
+  Handle(TDocStd_Document) aDoc;
+  DDocStd::GetDocument(argv[1], aDoc);
+  if (aDoc.IsNull()) 
+  { 
+    di << "Error: " << argv[1] << " is not a document\n"; return 1;
+  }
+  Handle(XCAFDoc_LengthUnit) aUnits;
+  if (!aDoc->Main().Root().FindAttribute(XCAFDoc_LengthUnit::GetID(), aUnits))
+  {
+    di << "Error: Document doesn't contain a Length Unit\n";
+    return 1;
+  }
+  if (argc == 3)
+  {
+    TCollection_AsciiString anOption(argv[2]);
+    anOption.LowerCase();
+    if (anOption.IsEqual("-scale"))
+    {
+      di << aUnits->GetUnitValue();
+      return 0;
+    }
+    else
+    {
+      di << "Error: Incorrect option, use -scale\n";
+      return 1;
+    }
+  }
+  di << aUnits->GetUnitName();
+  return 0;
+}
+
 //=======================================================================
 //function : XShowFaceBoundary
 //purpose  : Set face boundaries on/off
@@ -1328,7 +1417,18 @@ void XDEDRAW::Init(Draw_Interpretor& di)
   di.Add ("XSetTransparency", "Doc Transparency [label1 label2 ...]\t: Set transparency for given label(s) or whole doc",
                   __FILE__, XSetTransparency, g);
 
-  di.Add ("XShowFaceBoundary", 
+  di.Add("XSetLengthUnit",
+    "Doc {unit_name|scale_factor}\t: Set value of length unit"
+    "\n\t\t: Possible unit_name: m, mm, km, cm, micron, mille, in(inch), min(microinch), nin(nano inch), ft, stat.mile"
+    "\n\t\t: Possible scale factor: any real value more then 0. Factor to meter.",
+    __FILE__, setLengthUnit, g);
+
+  di.Add("XGetLengthUnit",
+    "Doc [-scale]\t: Print name of length unit"
+    "\n\t\t: -scale : print value of the scaling factor to meter of length unit",
+    __FILE__, dumpLengthUnit, g);
+
+  di.Add ("XShowFaceBoundary",
           "Doc Label IsOn [R G B [LineWidth [LineStyle]]]:"
           "- turns on/off drawing of face boundaries and defines boundary line style",
           __FILE__, XShowFaceBoundary, g);
index 45cb4b1..55a9004 100644 (file)
@@ -36,6 +36,8 @@
 #include <TDocStd_Document.hxx>
 #include <XDEDRAW.hxx>
 #include <XDEDRAW_Common.hxx>
+#include <XSAlgo.hxx>
+#include <XSAlgo_AlgoContainer.hxx>
 #include <XSControl_WorkSession.hxx>
 #include <XSDRAW.hxx>
 #include <XSDRAW_Vars.hxx>
@@ -510,7 +512,6 @@ static Standard_Integer WriteStep (Draw_Interpretor& di, Standard_Integer argc,
       }
     k++;
   }
-
   TDF_Label label;
   if( argc > k)
   {
@@ -653,10 +654,13 @@ static Standard_Integer WriteVrml(Draw_Interpretor& di, Standard_Integer argc, c
 
   VrmlAPI_Writer writer;
   writer.SetRepresentation(VrmlAPI_ShadedRepresentation);
-  Standard_Real anOCCLengthUnit =
-      UnitsMethods::GetLengthFactorValue(Interface_Static::IVal("xstep.cascade.unit"));
-  Standard_Real aScale = 0.001*anOCCLengthUnit;
-  if (!writer.WriteDoc(aDoc, argv[2], aScale))
+  Standard_Real aScaleFactorM = 1.;
+  if (!XCAFDoc_DocumentTool::GetLengthUnit(aDoc, aScaleFactorM))
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    aScaleFactorM = UnitsMethods::GetCasCadeLengthUnit(UnitsMethods_LengthUnit_Meter);
+  }
+  if (!writer.WriteDoc(aDoc, argv[2], aScaleFactorM))
   {
     di << "Error: File " << argv[2] << " was not written\n";
   }
index 286c7e4..4096d6b 100644 (file)
@@ -34,6 +34,9 @@
 #include <XCAFDoc_Location.hxx>
 #include <XCAFDoc_ShapeTool.hxx>
 #include <XDEDRAW_Shapes.hxx>
+#include <XSAlgo.hxx>
+#include <XSAlgo_AlgoContainer.hxx>
+#include <UnitsMethods.hxx>
 
 #include <stdio.h>
 //=======================================================================
@@ -56,6 +59,14 @@ static Standard_Integer addShape (Draw_Interpretor& di, Standard_Integer argc, c
     return 1;
   }
 
+  Standard_Real aLengthUnit = 1.;
+  if (!XCAFDoc_DocumentTool::GetLengthUnit(Doc, aLengthUnit))
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    aLengthUnit = UnitsMethods::GetCasCadeLengthUnit(UnitsMethods_LengthUnit_Meter);
+    XCAFDoc_DocumentTool::SetLengthUnit(Doc, aLengthUnit);
+  }
+
   Handle(XCAFDoc_ShapeTool) myAssembly = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
   Standard_Boolean makeAssembly = Standard_True;
   if ( argc==4 && Draw::Atoi(argv[3]) == 0 ) makeAssembly = Standard_False;
index ee58a6b..60da829 100644 (file)
@@ -82,7 +82,7 @@ XSAlgo_AlgoContainer::XSAlgo_AlgoContainer()
 
 void XSAlgo_AlgoContainer::PrepareForTransfer() const
 {
-  UnitsMethods::SetCasCadeLengthUnit ( Interface_Static::IVal("xstep.cascade.unit") );
+  UnitsMethods::SetCasCadeLengthUnit(Interface_Static::IVal("xstep.cascade.unit"));
 }
 
 //=======================================================================
index ab7cf79..3edd421 100644 (file)
 #include <Transfer_FinderProcess.hxx>
 #include <Transfer_TransientProcess.hxx>
 #include <TransferBRep_ShapeMapper.hxx>
+#include <XSAlgo.hxx>
+#include <XSAlgo_AlgoContainer.hxx>
 #include <XSControl_Controller.hxx>
 #include <XSControl_TransferReader.hxx>
 #include <XSControl_TransferWriter.hxx>
 #include <XSControl_WorkSession.hxx>
 #include <XSDRAW.hxx>
 #include <XSDRAWSTEP.hxx>
+#include <UnitsMethods.hxx>
 
 #include <stdio.h>
 //  Pour le transfert (write)
@@ -151,7 +154,10 @@ static Standard_Integer stepread (Draw_Interpretor& di, Standard_Integer argc, c
     else di<<"No model loaded\n";
     return 1;
   }
-  
+
+  XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+  sr.SetSystemLengthUnit(UnitsMethods::GetCasCadeLengthUnit());
+
   //   nom = "." -> fichier deja lu
   Standard_Integer i, num, nbs, modepri = 1;
   if (fromtcl) modepri = 4;
@@ -299,7 +305,9 @@ static Standard_Integer testreadstep (Draw_Interpretor& di, Standard_Integer arg
     case IFSelect_RetError : { di<<"file not found\n";   return 1; }      
     case IFSelect_RetFail  : { di<<"error during read\n";  return 1; }    
     default  :  { di<<"failure\n";   return 1; }                          
-  }  
+  }
+  XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+  Reader.SetSystemLengthUnit(UnitsMethods::GetCasCadeLengthUnit());
   Reader.TransferRoots();
   TopoDS_Shape shape = Reader.OneShape();
   DBRep::Set(argv[2],shape); 
index 20c6ee9..a1ab08d 100644 (file)
@@ -74,6 +74,8 @@
 #include <VrmlData_ShapeConvert.hxx>
 #include <XCAFDoc_DocumentTool.hxx>
 #include <XCAFDoc_ShapeTool.hxx>
+#include <XSAlgo.hxx>
+#include <XSAlgo_AlgoContainer.hxx>
 #include <XSDRAW.hxx>
 #include <XSDRAWIGES.hxx>
 #include <XSDRAWSTEP.hxx>
@@ -179,7 +181,6 @@ static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
 {
   TCollection_AsciiString aDestName, aFilePath;
   Standard_Boolean toUseExistingDoc = Standard_False;
-  Standard_Real aSystemUnitFactor = UnitsMethods::GetCasCadeLengthUnit() * 0.001;
   Standard_Boolean toListExternalFiles = Standard_False;
   Standard_Boolean isParallel = Standard_False;
   Standard_Boolean isDoublePrec = Standard_False;
@@ -306,9 +307,14 @@ static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
       return 1;
     }
   }
-
+  Standard_Real aScaleFactorM = 1.;
+  if (!XCAFDoc_DocumentTool::GetLengthUnit(aDoc, aScaleFactorM, UnitsMethods_LengthUnit_Meter))
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    aScaleFactorM = UnitsMethods::GetCasCadeLengthUnit(UnitsMethods_LengthUnit_Meter);
+  }
   RWGltf_CafReader aReader;
-  aReader.SetSystemLengthUnit (aSystemUnitFactor);
+  aReader.SetSystemLengthUnit (aScaleFactorM);
   aReader.SetSystemCoordinateSystem (RWMesh_CoordinateSystem_Zup);
   aReader.SetDocument (aDoc);
   aReader.SetParallel (isParallel);
@@ -504,8 +510,12 @@ static Standard_Integer WriteGltf (Draw_Interpretor& theDI,
 
   TCollection_AsciiString anExt = aGltfFilePath;
   anExt.LowerCase();
-
-  const Standard_Real aSystemUnitFactor = UnitsMethods::GetCasCadeLengthUnit() * 0.001;
+  Standard_Real aScaleFactorM = 1.;
+  if (!XCAFDoc_DocumentTool::GetLengthUnit(aDoc, aScaleFactorM, UnitsMethods_LengthUnit_Meter))
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    aScaleFactorM = UnitsMethods::GetCasCadeLengthUnit(UnitsMethods_LengthUnit_Meter);
+  }
 
   RWGltf_CafWriter aWriter (aGltfFilePath, anExt.EndsWith (".glb"));
   aWriter.SetTransformationFormat (aTrsfFormat);
@@ -515,7 +525,7 @@ static Standard_Integer WriteGltf (Draw_Interpretor& theDI,
   aWriter.SetToEmbedTexturesInGlb (toEmbedTexturesInGlb);
   aWriter.SetMergeFaces (toMergeFaces);
   aWriter.SetSplitIndices16 (toSplitIndices16);
-  aWriter.ChangeCoordinateSystemConverter().SetInputLengthUnit (aSystemUnitFactor);
+  aWriter.ChangeCoordinateSystemConverter().SetInputLengthUnit (aScaleFactorM);
   aWriter.ChangeCoordinateSystemConverter().SetInputCoordinateSystem (aSystemCoordSys);
   aWriter.Perform (aDoc, aFileInfo, aProgress->Start());
   return 0;
@@ -742,10 +752,16 @@ static Standard_Integer ReadObj (Draw_Interpretor& theDI,
       return 1;
     }
   }
+  Standard_Real aScaleFactorM = 1.;
+  if (!XCAFDoc_DocumentTool::GetLengthUnit(aDoc, aScaleFactorM, UnitsMethods_LengthUnit_Meter))
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
+    aScaleFactorM = UnitsMethods::GetCasCadeLengthUnit(UnitsMethods_LengthUnit_Meter);
+  }
 
   RWObj_CafReader aReader;
   aReader.SetSinglePrecision (isSinglePrecision);
-  aReader.SetSystemLengthUnit (UnitsMethods::GetCasCadeLengthUnit() * 0.001);
+  aReader.SetSystemLengthUnit (aScaleFactorM);
   aReader.SetSystemCoordinateSystem (aResultCoordSys);
   aReader.SetFileLengthUnit (aFileUnitFactor);
   aReader.SetFileCoordinateSystem (aFileCoordSys);
@@ -982,8 +998,8 @@ static Standard_Integer loadvrml
       }
 
       VrmlData_Scene aScene;
-      Standard_Real anOCCUnit = UnitsMethods::GetCasCadeLengthUnit();
-      aScene.SetLinearScale(1000. / anOCCUnit);
+      Standard_Real anOCCUnitMM = UnitsMethods::GetCasCadeLengthUnit();
+      aScene.SetLinearScale(1000. / anOCCUnitMM);
 
       aScene.SetVrmlDir (aVrmlDir);
       aScene << aStream;
index 588ea8e..de2f620 100644 (file)
@@ -12,6 +12,8 @@ XmlMXCAFDoc_DimTolDriver.cxx
 XmlMXCAFDoc_DimTolDriver.hxx
 XmlMXCAFDoc_GraphNodeDriver.cxx
 XmlMXCAFDoc_GraphNodeDriver.hxx
+XmlMXCAFDoc_LengthUnitDriver.cxx
+XmlMXCAFDoc_LengthUnitDriver.hxx
 XmlMXCAFDoc_LocationDriver.cxx
 XmlMXCAFDoc_LocationDriver.hxx
 XmlMXCAFDoc_LocationDriver.lxx
index 4d4cc12..ffd01b6 100644 (file)
@@ -25,6 +25,7 @@
 #include <XmlMXCAFDoc_DatumDriver.hxx>
 #include <XmlMXCAFDoc_DimTolDriver.hxx>
 #include <XmlMXCAFDoc_GraphNodeDriver.hxx>
+#include <XmlMXCAFDoc_LengthUnitDriver.hxx>
 #include <XmlMXCAFDoc_LocationDriver.hxx>
 #include <XmlMXCAFDoc_MaterialDriver.hxx>
 #include <XmlMXCAFDoc_VisMaterialDriver.hxx>
@@ -56,6 +57,7 @@ void XmlMXCAFDoc::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable,
   }
   
   aDriverTable -> AddDriver (aLocationDriver);
+  aDriverTable -> AddDriver (new XmlMXCAFDoc_LengthUnitDriver (anMsgDrv));
   aDriverTable -> AddDriver (new XmlMXCAFDoc_AssemblyItemRefDriver(anMsgDrv));
   aDriverTable -> AddDriver (new XmlMXCAFDoc_DatumDriver      (anMsgDrv));
   aDriverTable -> AddDriver (new XmlMXCAFDoc_DimTolDriver     (anMsgDrv));
index a6dc13b..7da0f4e 100644 (file)
@@ -25,6 +25,7 @@ class Message_Messenger;
 class XmlMXCAFDoc_CentroidDriver;
 class XmlMXCAFDoc_ColorDriver;
 class XmlMXCAFDoc_GraphNodeDriver;
+class XmlMXCAFDoc_LengthUnitDriver;
 class XmlMXCAFDoc_LocationDriver;
 class XmlMXCAFDoc_DatumDriver;
 class XmlMXCAFDoc_DimTolDriver;
@@ -63,6 +64,7 @@ private:
 friend class XmlMXCAFDoc_CentroidDriver;
 friend class XmlMXCAFDoc_ColorDriver;
 friend class XmlMXCAFDoc_GraphNodeDriver;
+friend class XmlMXCAFDoc_LengthUnitDriver;
 friend class XmlMXCAFDoc_LocationDriver;
 friend class XmlMXCAFDoc_DatumDriver;
 friend class XmlMXCAFDoc_DimTolDriver;
diff --git a/src/XmlMXCAFDoc/XmlMXCAFDoc_LengthUnitDriver.cxx b/src/XmlMXCAFDoc/XmlMXCAFDoc_LengthUnitDriver.cxx
new file mode 100644 (file)
index 0000000..a2dbabd
--- /dev/null
@@ -0,0 +1,98 @@
+// Copyright (c) 2021 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.
+
+#include <XmlMXCAFDoc_LengthUnitDriver.hxx>
+
+#include <Message_Messenger.hxx>
+#include <Standard_Type.hxx>
+#include <TDF_Attribute.hxx>
+#include <XCAFDoc_LengthUnit.hxx>
+#include <XmlObjMgt.hxx>
+#include <XmlObjMgt_Persistent.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(XmlMXCAFDoc_LengthUnitDriver, XmlMDF_ADriver)
+IMPLEMENT_DOMSTRING(UnitScaleValue, "value")
+
+//=======================================================================
+//function : XmlMXCAFDoc_LengthUnitDriver
+//purpose  : Constructor
+//=======================================================================
+XmlMXCAFDoc_LengthUnitDriver::XmlMXCAFDoc_LengthUnitDriver
+(const Handle(Message_Messenger)& theMsgDriver)
+  : XmlMDF_ADriver(theMsgDriver, "xcaf", "LengthUnit")
+{}
+
+//=======================================================================
+//function : NewEmpty
+//purpose  : 
+//=======================================================================
+Handle(TDF_Attribute) XmlMXCAFDoc_LengthUnitDriver::NewEmpty() const
+{
+  return (new XCAFDoc_LengthUnit());
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : persistent -> transient (retrieve)
+//=======================================================================
+Standard_Boolean XmlMXCAFDoc_LengthUnitDriver::Paste(const XmlObjMgt_Persistent& theSource,
+                                                     const Handle(TDF_Attribute)& theTarget,
+                                                     XmlObjMgt_RRelocationTable&) const
+{
+  XmlObjMgt_DOMString aNameStr = XmlObjMgt::GetStringValue(theSource);
+
+  if (aNameStr == NULL)
+  {
+    TCollection_ExtendedString aMessageString =
+      TCollection_ExtendedString("Cannot retrieve LengthUnit attribute");
+    myMessageDriver->Send(aMessageString, Message_Fail);
+    return Standard_False;
+  }
+  const XmlObjMgt_Element& anElement = theSource;
+  XmlObjMgt_DOMString aUnitScaleValue = anElement.getAttribute(::UnitScaleValue());
+  if (aUnitScaleValue == NULL)
+  {
+    TCollection_ExtendedString aMessageString
+    ("Cannot retrieve LengthUnit scale factor");
+    myMessageDriver->Send(aMessageString, Message_Fail);
+    return Standard_False;
+  }
+  TCollection_AsciiString aScaleFactor(aUnitScaleValue.GetString());
+  TCollection_AsciiString anUnitName(aNameStr.GetString());
+  if (!aScaleFactor.IsRealValue(true))
+  {
+    TCollection_ExtendedString aMessageString
+    ("Cannot retrieve LengthUnit scale factor");
+    myMessageDriver->Send(aMessageString, Message_Fail);
+    return Standard_False;
+  }
+
+  Handle(XCAFDoc_LengthUnit) anInt = Handle(XCAFDoc_LengthUnit)::DownCast(theTarget);
+  anInt->Set(anUnitName, aScaleFactor.RealValue());
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : transient -> persistent (store)
+//=======================================================================
+void XmlMXCAFDoc_LengthUnitDriver::Paste (const Handle(TDF_Attribute)& theSource,
+                                          XmlObjMgt_Persistent&        theTarget,
+                                          XmlObjMgt_SRelocationTable&  ) const
+{
+  Handle(XCAFDoc_LengthUnit) anAtt = Handle(XCAFDoc_LengthUnit)::DownCast(theSource);
+  XmlObjMgt_DOMString aNameUnit = anAtt->GetUnitName().ToCString(); 
+  XmlObjMgt_DOMString aValueUnit = TCollection_AsciiString(anAtt->GetUnitValue()).ToCString();
+  XmlObjMgt::SetStringValue (theTarget, aNameUnit);
+  theTarget.Element().setAttribute(::UnitScaleValue(), aValueUnit);
+}
diff --git a/src/XmlMXCAFDoc/XmlMXCAFDoc_LengthUnitDriver.hxx b/src/XmlMXCAFDoc/XmlMXCAFDoc_LengthUnitDriver.hxx
new file mode 100644 (file)
index 0000000..e0954f6
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (c) 2021 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.
+
+#ifndef _XmlMXCAFDoc_LengthUnitDriver_HeaderFile
+#define _XmlMXCAFDoc_LengthUnitDriver_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+
+#include <XmlMDF_ADriver.hxx>
+#include <Standard_Boolean.hxx>
+#include <XmlObjMgt_RRelocationTable.hxx>
+#include <XmlObjMgt_SRelocationTable.hxx>
+class Message_Messenger;
+class TDF_Attribute;
+class XmlObjMgt_Persistent;
+
+
+class XmlMXCAFDoc_LengthUnitDriver;
+DEFINE_STANDARD_HANDLE(XmlMXCAFDoc_LengthUnitDriver, XmlMDF_ADriver)
+
+//! Attribute Driver.
+class XmlMXCAFDoc_LengthUnitDriver : public XmlMDF_ADriver
+{
+
+public:
+
+  Standard_EXPORT XmlMXCAFDoc_LengthUnitDriver(const Handle(Message_Messenger)& theMessageDriver);
+  
+  Standard_EXPORT virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE;
+  
+  Standard_EXPORT virtual Standard_Boolean Paste (const XmlObjMgt_Persistent& theSource,
+                                                  const Handle(TDF_Attribute)& theTarget,
+                                                  XmlObjMgt_RRelocationTable& theRelocTable) const Standard_OVERRIDE;
+  
+  Standard_EXPORT virtual void Paste (const Handle(TDF_Attribute)& theSource,
+                                      XmlObjMgt_Persistent& theTarget,
+                                      XmlObjMgt_SRelocationTable& theRelocTable) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT(XmlMXCAFDoc_LengthUnitDriver,XmlMDF_ADriver)
+
+};
+
+#endif // _XmlMXCAFDoc_LengthUnitDriver_HeaderFile
index 53b527d..97d19c6 100755 (executable)
@@ -7,7 +7,7 @@ puts ""
 #######################################################################
 
 set BugNumber OCC22962
-set check_value 96
+set check_value 97
 pload DCAF
 
 ReadStep D1 [locate_data_file OCC22962-dm1-oc-214.stp]
diff --git a/tests/bugs/xde/bug31382 b/tests/bugs/xde/bug31382
new file mode 100644 (file)
index 0000000..cc6773e
--- /dev/null
@@ -0,0 +1,81 @@
+puts "# =============================================================================="
+puts "# 0031382: Data Exchange - BinXCAF should preserve length unit information"
+puts "# =============================================================================="
+
+pload DCAF
+
+box b 10 20 30
+
+catch { Close D }
+catch { Close D1 }
+# check saving value of length unit
+NewDocument D XmlXCAF
+XAddShape D b 0
+XSetLengthUnit D in
+XSave D ${imagedir}/${casename}.xml
+XOpen ${imagedir}//${casename}.xml D1
+set LU [XGetLengthUnit D1]
+if {$LU != "in"} {
+  puts "Error: Length unit is not coincided with given1"
+}
+Close D
+Close D1
+NewDocument D BinXCAF
+XAddShape D b 0
+XSetLengthUnit D m
+XSave D ${imagedir}/${casename}.xbf
+XOpen ${imagedir}//${casename}.xbf D1
+set LU [XGetLengthUnit D1]
+if {$LU != "m"} {
+  puts "Error: Length unit is not coincided with given2"
+}
+Close D
+Close D1
+
+# if length unit is undefined in the document value from session
+# must be set to document before saving it to xml
+NewDocument D XmlXCAF
+param xstep.cascade.unit 5
+XAddShape D b 0
+XSave D ${imagedir}/${casename}.xml
+set LU [XGetLengthUnit D]
+if {$LU == "mm"} {
+  puts "Error: Length unit is not coincided with given3"
+}
+XOpen ${imagedir}//${casename}.xml D1
+set LU [XGetLengthUnit D1]
+if {$LU == "stat.mile"} {
+  puts "Length unit is coincided with given"
+} else {
+  puts "Error: Length unit is not coincided with given4"
+}
+Close D
+Close D1
+
+# if length unit is undefined in the document value from session
+# must be set to document before saving it to xbf
+NewDocument D BinXCAF
+param xstep.cascade.unit 7
+XAddShape D b 0
+XSave D ${imagedir}/${casename}.xbf
+set LU [XGetLengthUnit D]
+if {$LU == "km"} {
+  puts "Length unit is coincided with given"
+} else {
+  puts "Error: Length unit is not coincided with given"
+}
+XOpen ${imagedir}//${casename}.xbf D1
+set LU [XGetLengthUnit D1]
+if {$LU == "km"} {
+   puts "Length unit is coincided with given"
+} else {
+   puts "Error: Length unit is not coincided with given"
+}
+
+# return to default global unit
+param xstep.cascade.unit 2
+file delete ${imagedir}//${casename}.xbf
+file delete ${imagedir}//${casename}.xml
+
+Close D
+Close D1
index 056eb26..7dbfbf6 100644 (file)
@@ -8,5 +8,8 @@ cpulimit 1000
 NewDocument D BinXCAF
 UndoLimit D 100
 
+# Local length unit value
+set lengthunit_start ""
+
 # Open a transaction
 NewCommand D
index 7fe1a83..be9d6b2 100644 (file)
@@ -38,6 +38,8 @@ set fa_Second 0; set sh_Second 0; set so_Second 0; set co_Second 0; set shpp_Sec
 ###################################### CHECKSHAPE ##################
 set chwi_First 0; set chfa_First 0; set chsh_First 0; set chso_First 0
 set chwi_Second 0; set chfa_Second 0; set chsh_Second 0; set chso_Second 0
+#################################################UNITS#############
+set lengthunit_First ""; set lengthunit_Second "";
 ###################################################################
 set ref_Compare 0
 set todo_msg ""
@@ -48,6 +50,10 @@ set end_line "\" \n"
 
 # Read original file
 if { [string length $filename] > 1} {
+    XNewDoc D_First
+    if { $lengthunit_start != "" } {
+      XSetLengthUnit D_First $lengthunit_start
+    }
     set ext [file extension $filename]
     set ReadCommand ReadStep
     set WriteCommand WriteStep
@@ -75,7 +81,9 @@ if { [string length $filename] > 1} {
 # Get information about translation
 if { $mist < 1} {           
     puts ""
-   
+    if { $lengthunit_start != "" } {
+      set lengthunit_First [XGetLengthUnit D_First]
+    }
     set tps_2 [data c]
     if { [llength $tps_2] > 0 } {
        # Finding all strings with warnings
@@ -248,7 +256,10 @@ if { $mist < 1} {
        set mist_w 1
     }
     if { $mist_w < 1 } {
-       
+        XNewDoc D_Second
+        if { $lengthunit_start != "" } {
+          XSetLengthUnit D_Second $lengthunit_start
+        }
         if { [catch { $ReadCommand D_Second $imagedir/${casename}_D_First$ext } catch_result] } {
            set err_msg "Error: Second - file was not read - exception"
            puts $err_msg
@@ -274,7 +285,9 @@ if { $mist_w > 0 || $mist_Second > 0 } {
 # Get information about translation
 if { $mist < 1} {           
     puts ""
-    
+    if { $lengthunit_start != "" } {
+      set lengthunit_Second [XGetLengthUnit D_Second]
+    }
     set tps_2 [data c]
     if { [llength $tps_2] > 0 } {
        # Finding all strings with warnings
@@ -599,6 +612,13 @@ if { $dump_file == 1 } {
        puts $fd_stream "set ProductMode OFF"
     }
     puts $fd_stream "set filename $filename"
+
+    if {$lengthunit_start != ""} {
+      puts $fd_stream "" 
+      puts $fd_stream "# set $lengthunit_start as local lenght unit"
+      puts $fd_stream "set lengthunit_start \"$lengthunit_start\""
+    }
+
     if { $mist != 1 } {
         puts $fd_stream "" 
         puts $fd_stream "set ref_data \{"
@@ -718,7 +738,10 @@ if { $dump_file != 0 } {
         puts "Error : $ref_Compare differences with reference data found :\n$err_compare_ref"
     } else {
         puts "Comparison of current result with reference data - OK\n"
-    }    
+    }
+    if { $lengthunit_First != $lengthunit_Second } {
+      puts "Error: different length units $lengthunit_First & $lengthunit_Second in result documents" 
+    } 
 }
 
 puts "--------------------------------------------------------------------"
index 51ba39c..c927fd8 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename buc40130.igs
 
+# set min as local length unit
+set lengthunit_start "min"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 1 )  Summary  = 0  ( 1 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 38  ( 54 )  Summary  = 38  ( 54 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 0  ( 0 )  Shell    = 0  ( 0 )  Face     = 3312  ( 3312 ) 
 STATSHAPE   : Solid    = 0  ( 0 )  Shell    = 0  ( 0 )  Face     = 3312  ( 3312 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =   0.9010557082  (   0.9010557089 )  AvgTol   =  0.005653398036  (  0.005653399581 )
+TOLERANCE   : MaxTol   =   0.9957815729  (    12.75113485 )  AvgTol   =    0.1129308837  (    0.1590338739 )
 LABELS      : N0Labels = 3312  ( 3312 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 3312  ( 3312 )   NameLabels = 3312  ( 3312 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
index ecbda70..9c480c2 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename t500core.igs
 
+# set min as local length unit
+set lengthunit_start "min"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 169  ( 444 )  Summary  = 169  ( 444 )
-CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 179  ( 535 )  Summary  = 179  ( 535 )
+CHECKSHAPE  : Wires    = 5  ( 5 )  Faces    = 5  ( 5 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 0  ( 0 )  Shell    = 0  ( 0 )  Face     = 674  ( 674 ) 
 STATSHAPE   : Solid    = 0  ( 0 )  Shell    = 0  ( 0 )  Face     = 674  ( 674 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =    0.483503583  (   0.4835035831 )  AvgTol   =  0.003038641057  (  0.003027097474 )
+TOLERANCE   : MaxTol   =   0.9933031338  (   0.9932065271 )  AvgTol   =    0.0725721901  (   0.07359500431 )
 LABELS      : N0Labels = 702  ( 702 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 702  ( 702 )   NameLabels = 702  ( 702 )   ColorLabels = 16  ( 16 )   LayerLabels = 702  ( 702 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 1  ( 1 )
index 8b99b0c..1b4dca8 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename ardi1.igs
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 2 )  Warnings = 0  ( 1 )  Summary  = 0  ( 3 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 2  ( 6 )  Summary  = 2  ( 6 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 0  ( 0 )  Shell    = 0  ( 0 )  Face     = 4  ( 4 ) 
 STATSHAPE   : Solid    = 0  ( 0 )  Shell    = 0  ( 0 )  Face     = 4  ( 4 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 1.000100016e-007  ( 1.000100016e-007 )  AvgTol   =  1.000015387e-007  (  1.000015387e-007 )
+TOLERANCE   : MaxTol   = 1.000100001e-007  ( 1.000100001e-007 )  AvgTol   =  1.000015385e-007  (  1.000015385e-007 )
 LABELS      : N0Labels = 4  ( 4 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 4  ( 4 )   NameLabels = 4  ( 4 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
index 5b3dfb4..2b3dac1 100755 (executable)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename waaier_para.igs
 
+# set min as local lenght unit
+set lengthunit_start "min"
+
 set ref_data {
 DATA        : Faulties = 0  ( 1 )  Warnings = 0  ( 1 )  Summary  = 0  ( 2 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 40  ( 622 )  Summary  = 40  ( 622 )
-CHECKSHAPE  : Wires    = 2  ( 2 )  Faces    = 3  ( 3 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 56  ( 608 )  Summary  = 56  ( 608 )
+CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 0  ( 0 )  Shell    = 0  ( 0 )  Face     = 162  ( 162 ) 
 STATSHAPE   : Solid    = 0  ( 0 )  Shell    = 0  ( 0 )  Face     = 162  ( 162 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =   0.9221218176  (   0.9410156556 )  AvgTol   =   0.01501977367  (   0.01438008679 )
+TOLERANCE   : MaxTol   =   0.4450036298  (   0.4450020791 )  AvgTol   =  0.004412017114  (  0.004434725442 )
 LABELS      : N0Labels = 162  ( 162 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 162  ( 162 )   NameLabels = 162  ( 162 )   ColorLabels = 162  ( 162 )   LayerLabels = 162  ( 162 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 1  ( 1 )
index 0ce212c..8893606 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename r0701_ug.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 3  ( 20 )  Summary  = 3  ( 20 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 26  ( 26 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 26  ( 26 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 1.497084727e-005  ( 1.497084651e-005 )  AvgTol   =  2.422471639e-006  (  7.787901742e-006 )
+TOLERANCE   : MaxTol   = 2.908188025e-006  (         1e-005 )  AvgTol   =  2.202340438e-007  (  6.439786142e-006 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 1  ( 1 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 1  ( 1 )
index 322cd38..8556295 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename bm1_ie_t4.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 0  ( 0 )  Shell    = 15  ( 15 )  Face     = 16  ( 16 ) 
 STATSHAPE   : Solid    = 0  ( 0 )  Shell    = 15  ( 15 )  Face     = 16  ( 16 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 0.005727453836  ( 0.005727453946 )  AvgTol   =  0.001247002689  (  0.001247002697 )
+TOLERANCE   : MaxTol   = 0.0002254903085  ( 0.0002254903128 )  AvgTol   =  4.915646123e-005  (  4.915646149e-005 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
index 5847fb9..7ebda2b 100644 (file)
@@ -1,6 +1,9 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename dnc_63_050_ppv_a.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
index bf6afcb..d3a5846 100755 (executable)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename tr9_r0501-ug.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 1  ( 398 )  Summary  = 1  ( 398 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 6  ( 403 )  Summary  = 6  ( 403 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 532  ( 532 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 532  ( 532 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 1.956021749e-005  ( 0.0003145873437 )  AvgTol   =  8.898149576e-007  (  7.870748276e-006 )
+TOLERANCE   : MaxTol   =         1e-005  ( 1.238532849e-005 )  AvgTol   =  2.427533179e-007  (  6.244877739e-006 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 1  ( 1 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 1  ( 1 )
index fb8bd61..cfe8e56 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename ca_exhaust.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 10  ( 12 )  Summary  = 10  ( 12 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 32  ( 32 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 32  ( 32 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 0.009164178529  ( 0.009164178525 )  AvgTol   =  0.001138135471  (  0.001138139984 )
+TOLERANCE   : MaxTol   = 0.0003607944462  ( 0.000360794446 )  AvgTol   =  4.485642177e-005  (  4.485642172e-005 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
index 5b22904..ee61fe2 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename trj5_k1-al-214.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 23  ( 23 )  Summary  = 23  ( 23 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 24  ( 24 )  Summary  = 24  ( 24 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 39  ( 39 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 39  ( 39 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 0.001016447268  ( 0.001059860842 )  AvgTol   =  0.0001469856415  (  0.0001714018813 )
+TOLERANCE   : MaxTol   = 4.0017609e-005  ( 4.172680481e-005 )  AvgTol   =  5.844755983e-006  (  6.806025269e-006 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 1  ( 1 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 1  ( 1 )
index 5eca616..1be2ee1 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename trj9_b2-in-214.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 12  ( 17 )  Summary  = 12  ( 17 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 2  ( 2 )  Face     = 306  ( 306 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 2  ( 2 )  Face     = 306  ( 306 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =   0.1005256507  (   0.1005256507 )  AvgTol   =  0.0007133932383  (  0.0007138150606 )
+TOLERANCE   : MaxTol   = 0.003957702784  ( 0.003957702784 )  AvgTol   =  2.816914725e-005  (  2.817757736e-005 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 1  ( 1 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 1  ( 1 )
index b2559ed..bbfa090 100755 (executable)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename trj8_pm6-hc-214.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 80 )  Summary  = 0  ( 80 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 14  ( 545 )  Summary  = 14  ( 545 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 10  ( 539 )  Summary  = 10  ( 539 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 98  ( 98 )  Shell    = 98  ( 98 )  Face     = 1504  ( 1504 ) 
 STATSHAPE   : Solid    = 272  ( 272 )  Shell    = 272  ( 272 )  Face     = 3214  ( 3214 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =   0.9320948364  (      3.3196868 )  AvgTol   =  0.0006692755906  (  0.003731702354 )
+TOLERANCE   : MaxTol   =    0.050070202  (   0.1306963307 )  AvgTol   =  2.387622465e-005  (  0.0001483894796 )
 LABELS      : N0Labels = 230  ( 230 )  N1Labels = 1907  ( 1907 )  N2Labels = 0  ( 0 )   TotalLabels = 2137  ( 2137 )   NameLabels = 633  ( 633 )   ColorLabels = 1602  ( 1602 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 161  ( 161 )  Volume   = 161  ( 161 )  Area     = 161  ( 161 )
 NCOLORS     : NColors  = 6  ( 6 )
index 91e4308..4a58c10 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename PRO10368.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 128  ( 158 )  Summary  = 128  ( 158 )
-CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 100  ( 111 )  Summary  = 100  ( 111 )
+CHECKSHAPE  : Wires    = 2  ( 2 )  Faces    = 2  ( 2 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 0  ( 0 )  Shell    = 3  ( 3 )  Face     = 773  ( 773 ) 
 STATSHAPE   : Solid    = 0  ( 0 )  Shell    = 3  ( 3 )  Face     = 773  ( 773 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =  0.06070038836  (  0.06070038829 )  AvgTol   =  0.002531214122  (  0.003392486293 )
+TOLERANCE   : MaxTol   =  0.01182785352  (  0.01199490965 )  AvgTol   =  0.0001340065537  (  0.0001692956662 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 3  ( 3 )  N2Labels = 0  ( 0 )   TotalLabels = 4  ( 4 )   NameLabels = 1  ( 1 )   ColorLabels = 0  ( 0 )   LayerLabels = 3  ( 3 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
index 4b0af3e..03e7516 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename BUC60031.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 TPSTAT      : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 22  ( 22 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 22  ( 22 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =  0.01755144512  (  0.05734823138 )  AvgTol   =  0.004026424043  (  0.008725930264 )
+TOLERANCE   : MaxTol   = 0.0008790534196  ( 0.002257804385 )  AvgTol   =  0.0002077159479  (  0.0003435677762 )
 LABELS      : N0Labels = 3  ( 3 )  N1Labels = 19  ( 19 )  N2Labels = 0  ( 0 )   TotalLabels = 22  ( 22 )   NameLabels = 5  ( 5 )   ColorLabels = 18  ( 18 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 4  ( 4 )
index 38b263a..5b79700 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename db_exhaust-A.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 4  ( 6 )  Summary  = 4  ( 6 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 6  ( 6 )  Summary  = 6  ( 6 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 3  ( 3 )  Shell    = 3  ( 3 )  Face     = 41  ( 41 ) 
 STATSHAPE   : Solid    = 3  ( 3 )  Shell    = 3  ( 3 )  Face     = 41  ( 41 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 0.003918852111  (  0.02740530648 )  AvgTol   =  0.0003818720564  (  0.001490986976 )
+TOLERANCE   : MaxTol   = 8.622882581e-005  ( 0.0009633609586 )  AvgTol   =  9.2909299e-006  (  5.719855947e-005 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 3  ( 3 )  N2Labels = 0  ( 0 )   TotalLabels = 4  ( 4 )   NameLabels = 1  ( 1 )   ColorLabels = 3  ( 3 )   LayerLabels = 3  ( 3 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 1  ( 1 )
index fff4716..6d62ff2 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename tr9_r0101-pe.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 0  ( 9 )  Summary  = 0  ( 9 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 0  ( 5 )  Summary  = 0  ( 5 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 621  ( 621 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 621  ( 621 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 0.009439804956  (  0.06828121929 )  AvgTol   =  0.002407155114  (  0.006125891304 )
+TOLERANCE   : MaxTol   = 0.0003716458644  ( 0.001004445675 )  AvgTol   =  9.473671712e-005  (  0.0002334520641 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 1  ( 1 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 1  ( 1 )
index eb9f7c2..2f6ca48 100644 (file)
@@ -1,13 +1,19 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
+puts "TODO CR23096 ALL: TOLERANCE : Faulty" 
+
+
 set filename BUC61003-3.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
-DATA        : Faulties = 0  ( 2 )  Warnings = 0  ( 1611 )  Summary  = 0  ( 1613 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 108  ( 168 )  Summary  = 108  ( 168 )
+DATA        : Faulties = 0  ( 1 )  Warnings = 0  ( 1611 )  Summary  = 0  ( 1612 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 76  ( 168 )  Summary  = 76  ( 168 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 34  ( 34 )  Shell    = 34  ( 34 )  Face     = 3882  ( 3882 ) 
 STATSHAPE   : Solid    = 34  ( 34 )  Shell    = 34  ( 34 )  Face     = 3882  ( 3882 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =   0.2091571291  (   0.2091571291 )  AvgTol   =  0.0003480273495  (  0.0003489544134 )
+TOLERANCE   : MaxTol   =   0.2952785433  ( 0.008234532641 )  AvgTol   =  0.0003974949851  (  1.38845912e-005 )
 LABELS      : N0Labels = 35  ( 35 )  N1Labels = 34  ( 34 )  N2Labels = 0  ( 0 )   TotalLabels = 69  ( 69 )   NameLabels = 69  ( 69 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
index 444da2b..5fd07ae 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
 set filename tr10_r0601_id.stp
 
+# set in as local length unit
+set lengthunit_start "in"
+
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 187  ( 204 )  Summary  = 187  ( 204 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 177  ( 177 )  Summary  = 177  ( 177 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 1327  ( 1327 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 1327  ( 1327 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =   0.0796871773  (  0.07968717732 )  AvgTol   =  0.0006754901311  (  0.001252692846 )
+TOLERANCE   : MaxTol   = 0.003137290445  ( 0.003137290446 )  AvgTol   =  2.733421898e-005  (  4.935392768e-005 )
 LABELS      : N0Labels = 3  ( 3 )  N1Labels = 3707  ( 3707 )  N2Labels = 0  ( 0 )   TotalLabels = 3710  ( 3710 )   NameLabels = 5  ( 5 )   ColorLabels = 3706  ( 3706 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 8  ( 8 )
index a2e9f91..39d9854 100644 (file)
@@ -4,7 +4,11 @@ puts "Test case exporting glTF model into glTF file."
 puts "========"
 
 Close D1 -silent
-ReadGltf D1 [locate_data_file bug30691_DamagedHelmet.gltf]
+XNewDoc D1
+XSetLengthUnit D1 cm
+ReadGltf D1 [locate_data_file bug30691_DamagedHelmet.gltf] -nocreatedoc
+XGetOneShape s1 D1
+set aLProps1 [uplevel #0 sprops $s1]
 
 set aTmpGltfBase "${imagedir}/${casename}_tmp"
 set aTmpGltf "${aTmpGltfBase}.gltf"
@@ -14,7 +18,17 @@ lappend occ_tmp_files "${aTmpGltfBase}_textures"
 
 WriteGltf D1 "$aTmpGltf"
 
-ReadGltf D "$aTmpGltf"
+Close D -silent
+XNewDoc D
+XSetLengthUnit D cm
+ReadGltf D "$aTmpGltf" -nocreatedoc
+
 XGetOneShape s D
+set aLProps2 [uplevel #0 sprops $s]
 checknbshapes s -face 1 -compound 0
 checktrinfo s -tri 15452 -nod 14556
+regexp {Mass\s:\s*([0-9\.]+)} $aLProps1 dummy anArea1
+regexp {Mass\s:\s*([0-9\.]+)} $aLProps2 dummy anArea2
+if {abs($anArea1 - $anArea2) > 1e-8 * $anArea1} {
+  puts "Error: invalid area $anArea1 instead of $anArea2"
+}
index 206876b..d138eaf 100644 (file)
@@ -3,7 +3,14 @@ puts "0029296: Data Exchange - implement import of mesh data from files in OBJ f
 puts "Ship model with transparent windows"
 puts "========"
 
-ReadObj D [locate_data_file ship_boat.obj]
+XNewDoc D
+XSetLengthUnit D in
+ReadObj D [locate_data_file ship_boat.obj] -nocreatedoc -unit 1
 XGetOneShape s D
 checknbshapes s -face 2359 -compound 2
 checktrinfo s -tri 27297 -nod 40496
+set aLProps [uplevel #0 sprops $s]
+regexp {Mass\s:\s*([0-9\.e\+]+)} $aLProps dummy anArea
+if {abs($anArea - 2.65152e+10) > 1e-8} {
+  puts "Error: invalid area $anArea instead of 2.65152e+10"
+}
index e4c4940..45ffd01 100644 (file)
@@ -6,7 +6,12 @@ puts "========"
 pload XDE OCAF MODELING VISUALIZATION
 Close D  -silent
 Close D1 -silent
-ReadObj D1 [locate_data_file "P-51 Mustang.obj"]
+
+XNewDoc D1
+XSetLengthUnit D1 cm
+ReadObj D1 [locate_data_file "P-51 Mustang.obj"] -nocreatedoc -unit 1
+XGetOneShape s1 D1
+set aLProps1 [uplevel #0 sprops $s1]
 
 set aTmpObjBase "${imagedir}/${casename}_tmp"
 set aTmpObj "${aTmpObjBase}.obj"
@@ -16,11 +21,20 @@ lappend occ_tmp_files "${aTmpObjBase}_textures"
 
 WriteObj D1 "$aTmpObj"
 
-ReadObj D "$aTmpObj"
+XNewDoc D
+XSetLengthUnit D cm
+ReadObj D "$aTmpObj" -nocreatedoc -unit 1
 XGetOneShape s D
+set aLProps2 [uplevel #0 sprops $s]
 checknbshapes s -face 14 -compound 1
 checktrinfo s -tri 4309 -nod 4727
 
+regexp {Mass\s:\s*([0-9\.]+)} $aLProps1 dummy anArea1
+regexp {Mass\s:\s*([0-9\.]+)} $aLProps2 dummy anArea2
+if {abs($anArea1 - $anArea2) > 1e-8 * $anArea1} {
+  puts "Error: invalid area $anArea1 instead of $anArea2"
+}
+
 vclear
 vinit View1
 XDisplay -dispMode 1 D