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. |
48 | class RWMesh_CoordinateSystemConverter |
49 | { |
50 | public: |
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 | |
64 | public: |
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 | |
138 | public: |
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 | |
178 | private: |
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 |