Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-30 08:46:57

0001 // Author: Kirill Gavrilov
0002 // Copyright: Open CASCADE 2015-2019
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #ifndef _RWMesh_CoordinateSystemConverter_HeaderFile
0016 #define _RWMesh_CoordinateSystemConverter_HeaderFile
0017 
0018 #include <RWMesh_CoordinateSystem.hxx>
0019 
0020 #include <gp_Ax3.hxx>
0021 #include <gp_XYZ.hxx>
0022 #include <gp_Trsf.hxx>
0023 #include <Graphic3d_Vec.hxx>
0024 
0025 //! Coordinate system converter defining the following tools:
0026 //! - Initialization for commonly used coordinate systems Z-up and Y-up.
0027 //! - Perform length unit conversion (scaling).
0028 //! - Conversion of three basic elements:
0029 //!   a) mesh node Positions,
0030 //!   b) mesh node Normals,
0031 //!   c) model nodes Transformations (locations).
0032 //!
0033 //! RWMesh_CoordinateSystem enumeration is used for convenient conversion between two commonly
0034 //! used coordinate systems, to make sure that imported model is oriented up.
0035 //! But gp_Ax3 can be used instead for defining a conversion between arbitrary systems (e.g.
0036 //! including non-zero origin).
0037 //!
0038 //! The converter requires defining explicitly both input and output systems,
0039 //! so that if either input or output is undefined, then conversion will be skipped.
0040 //! Length units conversion and coordinate system conversion are decomposed,
0041 //! so that application might specify no length units conversion but Y-up to Z-up coordinate system
0042 //! conversion.
0043 //!
0044 //! Class defines dedicated methods for parameters of input and output systems.
0045 //! This allows passing tool through several initialization steps,
0046 //! so that a reader can initialize input length units (only if file format defines such
0047 //! information), while application specifies output length units, and conversion will be done only
0048 //! when both defined.
0049 class RWMesh_CoordinateSystemConverter
0050 {
0051 public:
0052   //! Return a standard coordinate system definition.
0053   static gp_Ax3 StandardCoordinateSystem(RWMesh_CoordinateSystem theSys)
0054   {
0055     switch (theSys)
0056     {
0057       case RWMesh_CoordinateSystem_posYfwd_posZup:
0058         return gp_Ax3(gp::Origin(), gp::DZ(), gp::DX());
0059       case RWMesh_CoordinateSystem_negZfwd_posYup:
0060         return gp_Ax3(gp::Origin(), gp::DY(), gp::DX());
0061       case RWMesh_CoordinateSystem_Undefined:
0062         break;
0063     }
0064     return gp_Ax3();
0065   }
0066 
0067 public:
0068   //! Empty constructor.
0069   Standard_EXPORT RWMesh_CoordinateSystemConverter();
0070 
0071   //! Return TRUE if there is no transformation (target and current coordinates systems are same).
0072   Standard_Boolean IsEmpty() const { return myIsEmpty; }
0073 
0074   //! Return source length units, defined as scale factor to m (meters).
0075   //! -1.0 by default, which means that NO conversion will be applied (regardless output length
0076   //! unit).
0077   Standard_Real InputLengthUnit() const { return myInputLengthUnit; }
0078 
0079   //! Set source length units as scale factor to m (meters).
0080   void SetInputLengthUnit(Standard_Real theInputScale)
0081   {
0082     Init(myInputAx3, theInputScale, myOutputAx3, myOutputLengthUnit);
0083   }
0084 
0085   //! Return destination length units, defined as scale factor to m (meters).
0086   //! -1.0 by default, which means that NO conversion will be applied (regardless input length
0087   //! unit).
0088   Standard_Real OutputLengthUnit() const { return myOutputLengthUnit; }
0089 
0090   //! Set destination length units as scale factor to m (meters).
0091   void SetOutputLengthUnit(Standard_Real theOutputScale)
0092   {
0093     Init(myInputAx3, myInputLengthUnit, myOutputAx3, theOutputScale);
0094   }
0095 
0096   //! Return TRUE if source coordinate system has been set; FALSE by default.
0097   Standard_Boolean HasInputCoordinateSystem() const { return myHasInputAx3; }
0098 
0099   //! Source coordinate system; UNDEFINED by default.
0100   const gp_Ax3& InputCoordinateSystem() const { return myInputAx3; }
0101 
0102   //! Set source coordinate system.
0103   void SetInputCoordinateSystem(const gp_Ax3& theSysFrom)
0104   {
0105     myHasInputAx3 = Standard_True;
0106     Init(theSysFrom, myInputLengthUnit, myOutputAx3, myOutputLengthUnit);
0107   }
0108 
0109   //! Set source coordinate system.
0110   void SetInputCoordinateSystem(RWMesh_CoordinateSystem theSysFrom)
0111   {
0112     myHasInputAx3 = theSysFrom != RWMesh_CoordinateSystem_Undefined;
0113     Init(StandardCoordinateSystem(theSysFrom), myInputLengthUnit, myOutputAx3, myOutputLengthUnit);
0114   }
0115 
0116   //! Return TRUE if destination coordinate system has been set; FALSE by default.
0117   Standard_Boolean HasOutputCoordinateSystem() const { return myHasOutputAx3; }
0118 
0119   //! Destination coordinate system; UNDEFINED by default.
0120   const gp_Ax3& OutputCoordinateSystem() const { return myOutputAx3; }
0121 
0122   //! Set destination coordinate system.
0123   void SetOutputCoordinateSystem(const gp_Ax3& theSysTo)
0124   {
0125     myHasOutputAx3 = Standard_True;
0126     Init(myInputAx3, myInputLengthUnit, theSysTo, myOutputLengthUnit);
0127   }
0128 
0129   //! Set destination coordinate system.
0130   void SetOutputCoordinateSystem(RWMesh_CoordinateSystem theSysTo)
0131   {
0132     myHasOutputAx3 = theSysTo != RWMesh_CoordinateSystem_Undefined;
0133     Init(myInputAx3, myInputLengthUnit, StandardCoordinateSystem(theSysTo), myOutputLengthUnit);
0134   }
0135 
0136   //! Initialize transformation.
0137   Standard_EXPORT void Init(const gp_Ax3& theInputSystem,
0138                             Standard_Real theInputLengthUnit,
0139                             const gp_Ax3& theOutputSystem,
0140                             Standard_Real theOutputLengthUnit);
0141 
0142 public:
0143   //! Transform transformation.
0144   void TransformTransformation(gp_Trsf& theTrsf) const
0145   {
0146     if (myHasScale)
0147     {
0148       gp_XYZ aTransPart = theTrsf.TranslationPart();
0149       aTransPart *= myUnitFactor;
0150       theTrsf.SetTranslationPart(aTransPart);
0151     }
0152     if (myTrsf.Form() != gp_Identity)
0153     {
0154       theTrsf = myTrsf * theTrsf * myTrsfInv;
0155     }
0156   }
0157 
0158   //! Transform position.
0159   void TransformPosition(gp_XYZ& thePos) const
0160   {
0161     if (myHasScale)
0162     {
0163       thePos *= myUnitFactor;
0164     }
0165     if (myTrsf.Form() != gp_Identity)
0166     {
0167       myTrsf.Transforms(thePos);
0168     }
0169   }
0170 
0171   //! Transform normal (e.g. exclude translation/scale part of transformation).
0172   void TransformNormal(Graphic3d_Vec3& theNorm) const
0173   {
0174     if (myTrsf.Form() != gp_Identity)
0175     {
0176       const Graphic3d_Vec4 aNorm = myNormTrsf * Graphic3d_Vec4(theNorm, 0.0f);
0177       theNorm                    = aNorm.xyz();
0178     }
0179   }
0180 
0181 private:
0182   gp_Ax3 myInputAx3;          //!< source      coordinate system
0183   gp_Ax3 myOutputAx3;         //!< destination coordinate system
0184                               // clang-format off
0185   Standard_Real    myInputLengthUnit;  //!< source      length units, defined as scale factor to m (meters); -1.0 by default which means UNDEFINED
0186   Standard_Real    myOutputLengthUnit; //!< destination length units, defined as scale factor to m (meters); -1.0 by default which means UNDEFINED
0187   Standard_Boolean myHasInputAx3;      //!< flag indicating if source coordinate system is defined or not
0188   Standard_Boolean myHasOutputAx3;     //!< flag indicating if destination coordinate system is defined or not
0189 
0190   gp_Trsf          myTrsf;             //!< transformation from input Ax3 to output Ax3
0191   gp_Trsf          myTrsfInv;          //!< inversed transformation from input Ax3 to output Ax3
0192   Graphic3d_Mat4   myNormTrsf;         //!< transformation 4x4 matrix from input Ax3 to output Ax3
0193   Standard_Real    myUnitFactor;       //!< unit scale factor
0194   Standard_Boolean myHasScale;         //!< flag indicating that length unit transformation should be performed
0195                               // clang-format on
0196   Standard_Boolean myIsEmpty; //!< flag indicating that transformation is empty
0197 };
0198 
0199 #endif // _RWMesh_CoordinateSystemConverter_HeaderFile