0030692: Data Exchange - introduce base framework RWMesh for importing mesh data...
[occt.git] / src / RWMesh / RWMesh_CoordinateSystemConverter.hxx
CommitLineData
fc552d84 1// Author: Kirill Gavrilov
2// Copyright: Open CASCADE 2015-2019
3//
4// This file is part of Open CASCADE Technology software library.
5//
6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15#ifndef _RWMesh_CoordinateSystemConverter_HeaderFile
16#define _RWMesh_CoordinateSystemConverter_HeaderFile
17
18#include <RWMesh_CoordinateSystem.hxx>
19
20#include <gp.hxx>
21#include <gp_Ax3.hxx>
22#include <gp_XYZ.hxx>
23#include <gp_Trsf.hxx>
24#include <Graphic3d_Mat4.hxx>
25#include <Graphic3d_Vec.hxx>
26
27//! Coordinate system converter defining the following tools:
28//! - Initialization for commonly used coordinate systems Z-up and Y-up.
29//! - Perform length unit conversion (scaling).
30//! - Conversion of three basic elements:
31//! a) mesh node Positions,
32//! b) mesh node Normals,
33//! c) model nodes Transformations (locations).
34//!
35//! RWMesh_CoordinateSystem enumeration is used for convenient conversion between two commonly
36//! used coordinate systems, to make sure that imported model is oriented up.
37//! But gp_Ax3 can be used instead for defining a conversion between arbitrary systems (e.g. including non-zero origin).
38//!
39//! The converter requires defining explicitly both input and output systems,
40//! so that if either input or output is undefined, then conversion will be skipped.
41//! Length units conversion and coordinate system conversion are decomposed,
42//! so that application might specify no length units conversion but Y-up to Z-up coordinate system conversion.
43//!
44//! Class defines dedicated methods for parameters of input and output systems.
45//! This allows passing tool through several initialization steps,
46//! so that a reader can initialize input length units (only if file format defines such information),
47//! while application specifies output length units, and conversion will be done only when both defined.
48class RWMesh_CoordinateSystemConverter
49{
50public:
51
52 //! Return a standard coordinate system definition.
53 static gp_Ax3 StandardCoordinateSystem (RWMesh_CoordinateSystem theSys)
54 {
55 switch (theSys)
56 {
57 case RWMesh_CoordinateSystem_posYfwd_posZup: return gp_Ax3 (gp::Origin(), gp::DZ(), gp::DX());
58 case RWMesh_CoordinateSystem_negZfwd_posYup: return gp_Ax3 (gp::Origin(), gp::DY(), gp::DX());
59 case RWMesh_CoordinateSystem_Undefined: break;
60 }
61 return gp_Ax3();
62 }
63
64public:
65
66 //! Empty constructor.
67 Standard_EXPORT RWMesh_CoordinateSystemConverter();
68
69 //! Return TRUE if there is no transformation (target and current coordinates systems are same).
70 Standard_Boolean IsEmpty() const { return myIsEmpty; }
71
72 //! Return source length units, defined as scale factor to m (meters).
73 //! -1.0 by default, which means that NO conversion will be applied (regardless output length unit).
74 Standard_Real InputLengthUnit() const { return myInputLengthUnit; }
75
76 //! Set source length units as scale factor to m (meters).
77 void SetInputLengthUnit (Standard_Real theInputScale)
78 {
79 Init (myInputAx3, theInputScale, myOutputAx3, myOutputLengthUnit);
80 }
81
82 //! Return destination length units, defined as scale factor to m (meters).
83 //! -1.0 by default, which means that NO conversion will be applied (regardless input length unit).
84 Standard_Real OutputLengthUnit() const { return myOutputLengthUnit; }
85
86 //! Set destination length units as scale factor to m (meters).
87 void SetOutputLengthUnit (Standard_Real theOutputScale)
88 {
89 Init (myInputAx3, myInputLengthUnit, myOutputAx3, theOutputScale);
90 }
91
92 //! Return TRUE if source coordinate system has been set; FALSE by default.
93 Standard_Boolean HasInputCoordinateSystem() const { return myHasInputAx3; }
94
95 //! Source coordinate system; UNDEFINED by default.
96 const gp_Ax3& InputCoordinateSystem() const { return myInputAx3; }
97
98 //! Set source coordinate system.
99 void SetInputCoordinateSystem (const gp_Ax3& theSysFrom)
100 {
101 myHasInputAx3 = Standard_True;
102 Init (theSysFrom, myInputLengthUnit, myOutputAx3, myOutputLengthUnit);
103 }
104
105 //! Set source coordinate system.
106 void SetInputCoordinateSystem (RWMesh_CoordinateSystem theSysFrom)
107 {
108 myHasInputAx3 = theSysFrom != RWMesh_CoordinateSystem_Undefined;
109 Init (StandardCoordinateSystem (theSysFrom), myInputLengthUnit, myOutputAx3, myOutputLengthUnit);
110 }
111
112 //! Return TRUE if destination coordinate system has been set; FALSE by default.
113 Standard_Boolean HasOutputCoordinateSystem() const { return myHasOutputAx3; }
114
115 //! Destination coordinate system; UNDEFINED by default.
116 const gp_Ax3& OutputCoordinateSystem() const { return myOutputAx3; }
117
118 //! Set destination coordinate system.
119 void SetOutputCoordinateSystem (const gp_Ax3& theSysTo)
120 {
121 myHasOutputAx3 = Standard_True;
122 Init (myInputAx3, myInputLengthUnit, theSysTo, myOutputLengthUnit);
123 }
124
125 //! Set destination coordinate system.
126 void SetOutputCoordinateSystem (RWMesh_CoordinateSystem theSysTo)
127 {
128 myHasOutputAx3 = theSysTo != RWMesh_CoordinateSystem_Undefined;
129 Init (myInputAx3, myInputLengthUnit, StandardCoordinateSystem (theSysTo), myOutputLengthUnit);
130 }
131
132 //! Initialize transformation.
133 Standard_EXPORT void Init (const gp_Ax3& theInputSystem,
134 Standard_Real theInputLengthUnit,
135 const gp_Ax3& theOutputSystem,
136 Standard_Real theOutputLengthUnit);
137
138public:
139
140 //! Transform transformation.
141 void TransformTransformation (gp_Trsf& theTrsf) const
142 {
143 if (myHasScale)
144 {
145 gp_XYZ aTransPart = theTrsf.TranslationPart();
146 aTransPart *= myUnitFactor;
147 theTrsf.SetTranslationPart (aTransPart);
148 }
149 if (myTrsf.Form() != gp_Identity)
150 {
151 theTrsf = myTrsf * theTrsf * myTrsfInv;
152 }
153 }
154
155 //! Transform position.
156 void TransformPosition (gp_XYZ& thePos) const
157 {
158 if (myHasScale)
159 {
160 thePos *= myUnitFactor;
161 }
162 if (myTrsf.Form() != gp_Identity)
163 {
164 myTrsf.Transforms (thePos);
165 }
166 }
167
168 //! Transform normal (e.g. exclude translation/scale part of transformation).
169 void TransformNormal (Graphic3d_Vec3& theNorm) const
170 {
171 if (myTrsf.Form() != gp_Identity)
172 {
173 const Graphic3d_Vec4 aNorm = myNormTrsf * Graphic3d_Vec4 (theNorm, 0.0f);
174 theNorm = aNorm.xyz();
175 }
176 }
177
178private:
179
180 gp_Ax3 myInputAx3; //!< source coordinate system
181 gp_Ax3 myOutputAx3; //!< destination coordinate system
182 Standard_Real myInputLengthUnit; //!< source length units, defined as scale factor to m (meters); -1.0 by default which means UNDEFINED
183 Standard_Real myOutputLengthUnit; //!< destination length units, defined as scale factor to m (meters); -1.0 by default which means UNDEFINED
184 Standard_Boolean myHasInputAx3; //!< flag indicating if source coordinate system is defined or not
185 Standard_Boolean myHasOutputAx3; //!< flag indicating if destination coordinate system is defined or not
186
187 gp_Trsf myTrsf; //!< transformation from input Ax3 to output Ax3
188 gp_Trsf myTrsfInv; //!< inversed transformation from input Ax3 to output Ax3
189 Graphic3d_Mat4 myNormTrsf; //!< transformation 4x4 matrix from input Ax3 to output Ax3
190 Standard_Real myUnitFactor; //!< unit scale factor
191 Standard_Boolean myHasScale; //!< flag indicating that length unit transformation should be performed
192 Standard_Boolean myIsEmpty; //!< flag indicating that transformation is empty
193
194};
195
196#endif // _RWMesh_CoordinateSystemConverter_HeaderFile