Warning, file /include/opencascade/Graphic3d_Flipper.hxx was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _Graphic3d_Flipper_HeaderFile
0015 #define _Graphic3d_Flipper_HeaderFile
0016
0017 #include <BVH_Box.hxx>
0018 #include <Bnd_Box.hxx>
0019 #include <NCollection_Mat4.hxx>
0020 #include <Standard_Transient.hxx>
0021 #include <gp_Ax2.hxx>
0022
0023
0024
0025
0026
0027
0028
0029 class Graphic3d_Flipper : public Standard_Transient
0030 {
0031 DEFINE_STANDARD_RTTIEXT(Graphic3d_Flipper, Standard_Transient)
0032
0033 public:
0034
0035 Graphic3d_Flipper(const gp_Ax2& theRefPlane)
0036 : myRefPlane(theRefPlane)
0037 {
0038 }
0039
0040
0041 gp_Ax2 RefPlane() const { return myRefPlane; }
0042
0043
0044 void SetRefPlane(const gp_Ax2& theValue) { myRefPlane = theValue; }
0045
0046
0047
0048
0049 template <class T>
0050 void Apply(const NCollection_Mat4<T>& theWorldView, Bnd_Box& theBoundingBox) const;
0051
0052
0053
0054
0055 template <class T>
0056 void Apply(const NCollection_Mat4<T>& theWorldView, BVH_Box<T, 3>& theBoundingBox) const;
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 template <class T>
0076 NCollection_Mat4<T> Compute(const NCollection_Mat4<T>& theWorldView) const;
0077
0078
0079 Standard_EXPORT virtual void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const;
0080
0081 private:
0082 gp_Ax2 myRefPlane;
0083 };
0084
0085
0086
0087 template <class T>
0088 void Graphic3d_Flipper::Apply(const NCollection_Mat4<T>& theWorldView,
0089 Bnd_Box& theBoundingBox) const
0090 {
0091 if (theBoundingBox.IsVoid())
0092 {
0093 return;
0094 }
0095
0096 T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
0097 theBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
0098
0099 typename BVH_Box<T, 3>::BVH_VecNt aMin(aXmin, aYmin, aZmin);
0100 typename BVH_Box<T, 3>::BVH_VecNt aMax(aXmax, aYmax, aZmax);
0101 BVH_Box<T, 3> aBBox(aMin, aMax);
0102
0103 Apply(theWorldView, aBBox);
0104
0105 theBoundingBox = Bnd_Box();
0106 theBoundingBox.Update(aBBox.CornerMin().x(),
0107 aBBox.CornerMin().y(),
0108 aBBox.CornerMin().z(),
0109 aBBox.CornerMax().x(),
0110 aBBox.CornerMax().y(),
0111 aBBox.CornerMax().z());
0112 }
0113
0114
0115
0116 template <class T>
0117 void Graphic3d_Flipper::Apply(const NCollection_Mat4<T>& theWorldView,
0118 BVH_Box<T, 3>& theBoundingBox) const
0119 {
0120 NCollection_Mat4<T> aTPers = Compute(theWorldView);
0121 if (aTPers.IsIdentity() || !theBoundingBox.IsValid())
0122 {
0123 return;
0124 }
0125
0126 const typename BVH_Box<T, 3>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
0127 const typename BVH_Box<T, 3>::BVH_VecNt& aMax = theBoundingBox.CornerMax();
0128
0129 typename BVH_Box<T, 4>::BVH_VecNt anArrayOfCorners[8];
0130 anArrayOfCorners[0] =
0131 typename BVH_Box<T, 4>::BVH_VecNt(aMin.x(), aMin.y(), aMin.z(), static_cast<T>(1.0));
0132 anArrayOfCorners[1] =
0133 typename BVH_Box<T, 4>::BVH_VecNt(aMin.x(), aMin.y(), aMax.z(), static_cast<T>(1.0));
0134 anArrayOfCorners[2] =
0135 typename BVH_Box<T, 4>::BVH_VecNt(aMin.x(), aMax.y(), aMin.z(), static_cast<T>(1.0));
0136 anArrayOfCorners[3] =
0137 typename BVH_Box<T, 4>::BVH_VecNt(aMin.x(), aMax.y(), aMax.z(), static_cast<T>(1.0));
0138 anArrayOfCorners[4] =
0139 typename BVH_Box<T, 4>::BVH_VecNt(aMax.x(), aMin.y(), aMin.z(), static_cast<T>(1.0));
0140 anArrayOfCorners[5] =
0141 typename BVH_Box<T, 4>::BVH_VecNt(aMax.x(), aMin.y(), aMax.z(), static_cast<T>(1.0));
0142 anArrayOfCorners[6] =
0143 typename BVH_Box<T, 4>::BVH_VecNt(aMax.x(), aMax.y(), aMin.z(), static_cast<T>(1.0));
0144 anArrayOfCorners[7] =
0145 typename BVH_Box<T, 4>::BVH_VecNt(aMax.x(), aMax.y(), aMax.z(), static_cast<T>(1.0));
0146
0147 theBoundingBox.Clear();
0148 for (int anIt = 0; anIt < 8; ++anIt)
0149 {
0150 typename BVH_Box<T, 4>::BVH_VecNt& aCorner = anArrayOfCorners[anIt];
0151 aCorner = aTPers * aCorner;
0152 aCorner = aCorner / aCorner.w();
0153 theBoundingBox.Add(typename BVH_Box<T, 3>::BVH_VecNt(aCorner.x(), aCorner.y(), aCorner.z()));
0154 }
0155 }
0156
0157
0158
0159 template <class T>
0160 NCollection_Mat4<T> Graphic3d_Flipper::Compute(const NCollection_Mat4<T>& theWorldView) const
0161 {
0162 NCollection_Vec4<T> aReferenceOrigin(static_cast<T>(myRefPlane.Location().X()),
0163 static_cast<T>(myRefPlane.Location().Y()),
0164 static_cast<T>(myRefPlane.Location().Z()),
0165 static_cast<T>(1));
0166 NCollection_Vec4<T> aReferenceX(static_cast<T>(myRefPlane.XDirection().X()),
0167 static_cast<T>(myRefPlane.XDirection().Y()),
0168 static_cast<T>(myRefPlane.XDirection().Z()),
0169 static_cast<T>(1));
0170 NCollection_Vec4<T> aReferenceY(static_cast<T>(myRefPlane.YDirection().X()),
0171 static_cast<T>(myRefPlane.YDirection().Y()),
0172 static_cast<T>(myRefPlane.YDirection().Z()),
0173 static_cast<T>(1));
0174 NCollection_Vec4<T> aReferenceZ(static_cast<T>(myRefPlane.Axis().Direction().X()),
0175 static_cast<T>(myRefPlane.Axis().Direction().Y()),
0176 static_cast<T>(myRefPlane.Axis().Direction().Z()),
0177 static_cast<T>(1));
0178
0179 NCollection_Mat4<T> aMatrixMV;
0180 aMatrixMV.Convert(theWorldView);
0181
0182 const NCollection_Vec4<T> aMVReferenceOrigin = aMatrixMV * aReferenceOrigin;
0183 const NCollection_Vec4<T> aMVReferenceX =
0184 aMatrixMV * NCollection_Vec4<T>(aReferenceX.xyz() + aReferenceOrigin.xyz(), static_cast<T>(1));
0185 const NCollection_Vec4<T> aMVReferenceY =
0186 aMatrixMV * NCollection_Vec4<T>(aReferenceY.xyz() + aReferenceOrigin.xyz(), static_cast<T>(1));
0187 const NCollection_Vec4<T> aMVReferenceZ =
0188 aMatrixMV * NCollection_Vec4<T>(aReferenceZ.xyz() + aReferenceOrigin.xyz(), static_cast<T>(1));
0189
0190 const NCollection_Vec4<T> aDirX = aMVReferenceX - aMVReferenceOrigin;
0191 const NCollection_Vec4<T> aDirY = aMVReferenceY - aMVReferenceOrigin;
0192 const NCollection_Vec4<T> aDirZ = aMVReferenceZ - aMVReferenceOrigin;
0193
0194 const bool isReversedX = aDirX.xyz().Dot(NCollection_Vec3<T>::DX()) < static_cast<T>(0);
0195 const bool isReversedY = aDirY.xyz().Dot(NCollection_Vec3<T>::DY()) < static_cast<T>(0);
0196 const bool isReversedZ = aDirZ.xyz().Dot(NCollection_Vec3<T>::DZ()) < static_cast<T>(0);
0197
0198 NCollection_Mat4<T> aTransform;
0199 if ((isReversedX || isReversedY) && !isReversedZ)
0200 {
0201
0202 aTransform.SetColumn(0, -aTransform.GetColumn(0).xyz());
0203 aTransform.SetColumn(1, -aTransform.GetColumn(1).xyz());
0204 }
0205 else if (isReversedY && isReversedZ)
0206 {
0207
0208 aTransform.SetColumn(1, -aTransform.GetColumn(1).xyz());
0209 aTransform.SetColumn(2, -aTransform.GetColumn(2).xyz());
0210 }
0211 else if (isReversedZ)
0212 {
0213
0214 aTransform.SetColumn(0, -aTransform.GetColumn(0).xyz());
0215 aTransform.SetColumn(2, -aTransform.GetColumn(2).xyz());
0216 }
0217 else
0218 {
0219 return NCollection_Mat4<T>();
0220 }
0221
0222 NCollection_Mat4<T> aRefAxes;
0223 NCollection_Mat4<T> aRefInv;
0224 aRefAxes.SetColumn(0, aReferenceX.xyz());
0225 aRefAxes.SetColumn(1, aReferenceY.xyz());
0226 aRefAxes.SetColumn(2, aReferenceZ.xyz());
0227 aRefAxes.SetColumn(3, aReferenceOrigin.xyz());
0228 aRefAxes.Inverted(aRefInv);
0229
0230 aTransform = aRefAxes * aTransform * aRefInv;
0231 return aTransform;
0232 }
0233
0234 #endif