File indexing completed on 2024-11-15 09:47:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef _Graphic3d_TransformPers_HeaderFile
0017 #define _Graphic3d_TransformPers_HeaderFile
0018
0019 #include <Aspect_TypeOfTriedronPosition.hxx>
0020 #include <BVH_Box.hxx>
0021 #include <Graphic3d_Camera.hxx>
0022 #include <Graphic3d_TransformUtils.hxx>
0023 #include <Graphic3d_TransModeFlags.hxx>
0024 #include <Graphic3d_Vec.hxx>
0025 #include <NCollection_Mat4.hxx>
0026
0027 DEFINE_STANDARD_HANDLE(Graphic3d_TransformPers, Standard_Transient)
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 class Graphic3d_TransformPers : public Standard_Transient
0045 {
0046 DEFINE_STANDARD_RTTIEXT(Graphic3d_TransformPers, Standard_Transient)
0047 public:
0048
0049
0050 static Standard_Boolean IsZoomOrRotate (Graphic3d_TransModeFlags theMode)
0051 {
0052 return (theMode & (Graphic3d_TMF_ZoomPers | Graphic3d_TMF_RotatePers)) != 0;
0053 }
0054
0055
0056 static Standard_Boolean IsTrihedronOr2d (Graphic3d_TransModeFlags theMode)
0057 {
0058 return (theMode & (Graphic3d_TMF_TriedronPers | Graphic3d_TMF_2d)) != 0;
0059 }
0060
0061 public:
0062
0063
0064 Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode)
0065 : myMode (theMode)
0066 {
0067 if (IsZoomOrRotate (theMode))
0068 {
0069 SetPersistence (theMode, gp_Pnt(0.0, 0.0, 0.0));
0070 }
0071 else if (IsTrihedronOr2d (theMode))
0072 {
0073 SetPersistence (theMode, Aspect_TOTP_LEFT_LOWER, Graphic3d_Vec2i (0, 0));
0074 }
0075 else if (theMode == Graphic3d_TMF_CameraPers)
0076 {
0077 myMode = theMode;
0078 }
0079 else
0080 {
0081 throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
0082 }
0083 }
0084
0085
0086
0087
0088 Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode,
0089 const gp_Pnt& thePnt)
0090 : myMode (Graphic3d_TMF_None)
0091 {
0092 SetPersistence (theMode, thePnt);
0093 }
0094
0095
0096
0097
0098
0099 Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode,
0100 const Aspect_TypeOfTriedronPosition theCorner,
0101 const Graphic3d_Vec2i& theOffset = Graphic3d_Vec2i (0, 0))
0102 : myMode (Graphic3d_TMF_None)
0103 {
0104 SetPersistence (theMode, theCorner, theOffset);
0105 }
0106
0107
0108 Standard_Boolean IsZoomOrRotate() const { return IsZoomOrRotate (myMode); }
0109
0110
0111 Standard_Boolean IsTrihedronOr2d() const { return IsTrihedronOr2d (myMode); }
0112
0113
0114 Graphic3d_TransModeFlags Mode() const { return myMode; }
0115
0116
0117 Graphic3d_TransModeFlags Flags() const { return myMode; }
0118
0119
0120
0121 void SetPersistence (const Graphic3d_TransModeFlags theMode,
0122 const gp_Pnt& thePnt)
0123 {
0124 if (!IsZoomOrRotate (theMode))
0125 {
0126 throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
0127 }
0128
0129 myMode = theMode;
0130 myParams.Params3d.PntX = thePnt.X();
0131 myParams.Params3d.PntY = thePnt.Y();
0132 myParams.Params3d.PntZ = thePnt.Z();
0133 }
0134
0135
0136
0137 void SetPersistence (const Graphic3d_TransModeFlags theMode,
0138 const Aspect_TypeOfTriedronPosition theCorner,
0139 const Graphic3d_Vec2i& theOffset)
0140 {
0141 if (!IsTrihedronOr2d (theMode))
0142 {
0143 throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
0144 }
0145
0146 myMode = theMode;
0147 myParams.Params2d.Corner = theCorner;
0148 myParams.Params2d.OffsetX = theOffset.x();
0149 myParams.Params2d.OffsetY = theOffset.y();
0150 }
0151
0152 public:
0153
0154
0155 gp_Pnt AnchorPoint() const
0156 {
0157 if (!IsZoomOrRotate())
0158 {
0159 throw Standard_ProgramError("Graphic3d_TransformPers::AnchorPoint(), wrong persistence mode.");
0160 }
0161
0162 return gp_Pnt (myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
0163 }
0164
0165
0166 void SetAnchorPoint (const gp_Pnt& thePnt)
0167 {
0168 if (!IsZoomOrRotate())
0169 {
0170 throw Standard_ProgramError("Graphic3d_TransformPers::SetAnchorPoint(), wrong persistence mode.");
0171 }
0172
0173 myParams.Params3d.PntX = thePnt.X();
0174 myParams.Params3d.PntY = thePnt.Y();
0175 myParams.Params3d.PntZ = thePnt.Z();
0176 }
0177
0178
0179 Aspect_TypeOfTriedronPosition Corner2d() const
0180 {
0181 if (!IsTrihedronOr2d())
0182 {
0183 throw Standard_ProgramError("Graphic3d_TransformPers::Corner2d(), wrong persistence mode.");
0184 }
0185
0186 return myParams.Params2d.Corner;
0187 }
0188
0189
0190 void SetCorner2d (const Aspect_TypeOfTriedronPosition thePos)
0191 {
0192 if (!IsTrihedronOr2d())
0193 {
0194 throw Standard_ProgramError("Graphic3d_TransformPers::SetCorner2d(), wrong persistence mode.");
0195 }
0196
0197 myParams.Params2d.Corner = thePos;
0198 }
0199
0200
0201 Graphic3d_Vec2i Offset2d() const
0202 {
0203 if (!IsTrihedronOr2d())
0204 {
0205 throw Standard_ProgramError("Graphic3d_TransformPers::Offset2d(), wrong persistence mode.");
0206 }
0207
0208 return Graphic3d_Vec2i (myParams.Params2d.OffsetX, myParams.Params2d.OffsetY);
0209 }
0210
0211
0212 void SetOffset2d (const Graphic3d_Vec2i& theOffset)
0213 {
0214 if (!IsTrihedronOr2d())
0215 {
0216 throw Standard_ProgramError("Graphic3d_TransformPers::SetOffset2d(), wrong persistence mode.");
0217 }
0218
0219 myParams.Params2d.OffsetX = theOffset.x();
0220 myParams.Params2d.OffsetY = theOffset.y();
0221 }
0222
0223 public:
0224
0225
0226
0227
0228
0229 virtual Standard_Real persistentScale (const Handle(Graphic3d_Camera)& theCamera,
0230 const Standard_Integer theViewportWidth,
0231 const Standard_Integer theViewportHeight) const
0232 {
0233 (void )theViewportWidth;
0234
0235 const Standard_Integer aVPSizeY = theCamera->Tile().IsValid() ? theCamera->Tile().TotalSize.y() : theViewportHeight;
0236
0237 gp_Vec aVecToEye (theCamera->Direction());
0238 gp_Vec aVecToObj (theCamera->Eye(), gp_Pnt (myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ));
0239 const Standard_Real aFocus = aVecToObj.Dot (aVecToEye);
0240 const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
0241 return Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
0242 }
0243
0244
0245
0246
0247
0248
0249
0250
0251 template<class T>
0252 void Apply (const Handle(Graphic3d_Camera)& theCamera,
0253 const NCollection_Mat4<T>& theProjection,
0254 const NCollection_Mat4<T>& theWorldView,
0255 const Standard_Integer theViewportWidth,
0256 const Standard_Integer theViewportHeight,
0257 Bnd_Box& theBoundingBox) const;
0258
0259
0260
0261
0262
0263
0264
0265
0266 template<class T>
0267 void Apply (const Handle(Graphic3d_Camera)& theCamera,
0268 const NCollection_Mat4<T>& theProjection,
0269 const NCollection_Mat4<T>& theWorldView,
0270 const Standard_Integer theViewportWidth,
0271 const Standard_Integer theViewportHeight,
0272 BVH_Box<T, 3>& theBoundingBox) const;
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 template<class T>
0284 NCollection_Mat4<T> Compute (const Handle(Graphic3d_Camera)& theCamera,
0285 const NCollection_Mat4<T>& theProjection,
0286 const NCollection_Mat4<T>& theWorldView,
0287 const Standard_Integer theViewportWidth,
0288 const Standard_Integer theViewportHeight) const;
0289
0290
0291
0292
0293
0294
0295
0296
0297 template<class T>
0298 void Apply (const Handle(Graphic3d_Camera)& theCamera,
0299 const NCollection_Mat4<T>& theProjection,
0300 NCollection_Mat4<T>& theWorldView,
0301 const Standard_Integer theViewportWidth,
0302 const Standard_Integer theViewportHeight,
0303 const gp_Pnt* theAnchor = NULL) const;
0304
0305
0306 Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0307
0308 private:
0309
0310
0311 struct PersParams3d
0312 {
0313 Standard_Real PntX;
0314 Standard_Real PntY;
0315 Standard_Real PntZ;
0316
0317
0318 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0319 };
0320
0321
0322 struct PersParams2d
0323 {
0324 Standard_Integer OffsetX;
0325 Standard_Integer OffsetY;
0326 Aspect_TypeOfTriedronPosition Corner;
0327
0328
0329 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0330 };
0331
0332 private:
0333
0334 Graphic3d_TransModeFlags myMode;
0335 union
0336 {
0337 PersParams3d Params3d;
0338 PersParams2d Params2d;
0339 } myParams;
0340
0341 };
0342
0343
0344
0345
0346
0347 template<class T>
0348 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
0349 const NCollection_Mat4<T>& theProjection,
0350 NCollection_Mat4<T>& theWorldView,
0351 const Standard_Integer theViewportWidth,
0352 const Standard_Integer theViewportHeight,
0353 const gp_Pnt* theAnchor) const
0354 {
0355 (void )theViewportWidth;
0356 (void )theProjection;
0357 if (myMode == Graphic3d_TMF_None
0358 || theViewportHeight == 0)
0359 {
0360 return;
0361 }
0362
0363
0364 const Standard_Integer aVPSizeY = theCamera->Tile().IsValid() ? theCamera->Tile().TotalSize.y() : theViewportHeight;
0365
0366
0367
0368 const Standard_Real aJitterComp = 0.001;
0369 if (myMode == Graphic3d_TMF_TriedronPers)
0370 {
0371
0372 const Standard_Real aFocus = theCamera->IsOrthographic()
0373 ? theCamera->Distance()
0374 : (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
0375 ? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
0376 : Standard_Real(theCamera->ZFocus()));
0377
0378
0379 const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
0380 const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
0381 const gp_Dir aForward = theCamera->Direction();
0382 gp_XYZ aCenter = theCamera->Center().XYZ() + aForward.XYZ() * (aFocus - theCamera->Distance());
0383 if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
0384 {
0385 const Standard_Real anOffsetX = (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale;
0386 const gp_Dir aSide = aForward.Crossed (theCamera->Up());
0387 const gp_XYZ aDeltaX = aSide.XYZ() * (Abs(aViewDim.X()) * theCamera->NDC2dOffsetX() - anOffsetX);
0388 if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
0389 {
0390 aCenter += aDeltaX;
0391 }
0392 else
0393 {
0394 aCenter -= aDeltaX;
0395 }
0396 }
0397 if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
0398 {
0399 const Standard_Real anOffsetY = (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale;
0400 const gp_XYZ aDeltaY = theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * theCamera->NDC2dOffsetY() - anOffsetY);
0401 if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
0402 {
0403 aCenter += aDeltaY;
0404 }
0405 else
0406 {
0407 aCenter -= aDeltaY;
0408 }
0409 }
0410
0411 NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
0412 Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z());
0413 Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale);
0414 theWorldView.ConvertFrom (aWorldView);
0415 return;
0416 }
0417 else if (myMode == Graphic3d_TMF_2d)
0418 {
0419 const Standard_Real aFocus = theCamera->IsOrthographic()
0420 ? theCamera->Distance()
0421 : (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
0422 ? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
0423 : Standard_Real(theCamera->ZFocus()));
0424
0425
0426 const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
0427 const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
0428 gp_XYZ aCenter (0.0, 0.0, -aFocus);
0429 if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
0430 {
0431 aCenter.SetX (-aViewDim.X() * theCamera->NDC2dOffsetX() + (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale);
0432 if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
0433 {
0434 aCenter.SetX (-aCenter.X());
0435 }
0436 }
0437 if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
0438 {
0439 aCenter.SetY (-aViewDim.Y() * theCamera->NDC2dOffsetY() + (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale);
0440 if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
0441 {
0442 aCenter.SetY (-aCenter.Y());
0443 }
0444 }
0445
0446 theWorldView.InitIdentity();
0447 Graphic3d_TransformUtils::Translate (theWorldView, T(aCenter.X()), T(aCenter.Y()), T(aCenter.Z()));
0448 Graphic3d_TransformUtils::Scale (theWorldView, T(aScale), T(aScale), T(aScale));
0449 return;
0450 }
0451 else if ((myMode & Graphic3d_TMF_CameraPers) != 0)
0452 {
0453 theWorldView.InitIdentity();
0454 }
0455 else
0456 {
0457
0458 NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
0459 if (theAnchor != NULL)
0460 {
0461 Graphic3d_TransformUtils::Translate (aWorldView, theAnchor->X(), theAnchor->Y(), theAnchor->Z());
0462 }
0463 else
0464 {
0465 Graphic3d_TransformUtils::Translate (aWorldView, myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
0466 }
0467
0468 if ((myMode & Graphic3d_TMF_RotatePers) != 0)
0469 {
0470
0471 aWorldView.SetValue (0, 0, 1.0);
0472 aWorldView.SetValue (1, 0, 0.0);
0473 aWorldView.SetValue (2, 0, 0.0);
0474
0475 aWorldView.SetValue (0, 1, 0.0);
0476 aWorldView.SetValue (1, 1, 1.0);
0477 aWorldView.SetValue (2, 1, 0.0);
0478
0479 aWorldView.SetValue (0, 2, 0.0);
0480 aWorldView.SetValue (1, 2, 0.0);
0481 aWorldView.SetValue (2, 2, 1.0);
0482 }
0483
0484 if ((myMode & Graphic3d_TMF_ZoomPers) != 0)
0485 {
0486
0487 Standard_Real aScale = persistentScale (theCamera, theViewportWidth, theViewportHeight);
0488 Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale);
0489 }
0490 theWorldView.ConvertFrom (aWorldView);
0491 return;
0492 }
0493 }
0494
0495
0496
0497
0498
0499 template<class T>
0500 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
0501 const NCollection_Mat4<T>& theProjection,
0502 const NCollection_Mat4<T>& theWorldView,
0503 const Standard_Integer theViewportWidth,
0504 const Standard_Integer theViewportHeight,
0505 Bnd_Box& theBoundingBox) const
0506 {
0507 if (theBoundingBox.IsVoid())
0508 {
0509 return;
0510 }
0511
0512 T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
0513
0514 theBoundingBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
0515
0516 typename BVH_Box<T, 3>::BVH_VecNt aMin (aXmin, aYmin, aZmin);
0517 typename BVH_Box<T, 3>::BVH_VecNt aMax (aXmax, aYmax, aZmax);
0518 BVH_Box<T, 3> aBBox (aMin, aMax);
0519
0520 Apply (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox);
0521
0522 theBoundingBox = Bnd_Box();
0523 theBoundingBox.Update (aBBox.CornerMin().x(), aBBox.CornerMin().y(), aBBox.CornerMin().z(),
0524 aBBox.CornerMax().x(), aBBox.CornerMax().y(), aBBox.CornerMax().z());
0525 }
0526
0527
0528
0529
0530
0531 template<class T>
0532 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
0533 const NCollection_Mat4<T>& theProjection,
0534 const NCollection_Mat4<T>& theWorldView,
0535 const Standard_Integer theViewportWidth,
0536 const Standard_Integer theViewportHeight,
0537 BVH_Box<T, 3>& theBoundingBox) const
0538 {
0539 NCollection_Mat4<T> aTPers = Compute (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight);
0540 if (aTPers.IsIdentity()
0541 || !theBoundingBox.IsValid())
0542 {
0543 return;
0544 }
0545
0546 const typename BVH_Box<T, 3>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
0547 const typename BVH_Box<T, 3>::BVH_VecNt& aMax = theBoundingBox.CornerMax();
0548
0549 typename BVH_Box<T, 4>::BVH_VecNt anArrayOfCorners[8];
0550 anArrayOfCorners[0] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
0551 anArrayOfCorners[1] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
0552 anArrayOfCorners[2] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
0553 anArrayOfCorners[3] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
0554 anArrayOfCorners[4] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
0555 anArrayOfCorners[5] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
0556 anArrayOfCorners[6] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
0557 anArrayOfCorners[7] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
0558
0559 theBoundingBox.Clear();
0560 for (Standard_Integer anIt = 0; anIt < 8; ++anIt)
0561 {
0562 typename BVH_Box<T, 4>::BVH_VecNt& aCorner = anArrayOfCorners[anIt];
0563 aCorner = aTPers * aCorner;
0564 aCorner = aCorner / aCorner.w();
0565 theBoundingBox.Add (typename BVH_Box<T, 3>::BVH_VecNt (aCorner.x(), aCorner.y(), aCorner.z()));
0566 }
0567 }
0568
0569
0570
0571
0572
0573 template<class T>
0574 NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const Handle(Graphic3d_Camera)& theCamera,
0575 const NCollection_Mat4<T>& theProjection,
0576 const NCollection_Mat4<T>& theWorldView,
0577 const Standard_Integer theViewportWidth,
0578 const Standard_Integer theViewportHeight) const
0579 {
0580 if (myMode == Graphic3d_TMF_None)
0581 {
0582 return NCollection_Mat4<T>();
0583 }
0584
0585 NCollection_Mat4<T> aWorldView (theWorldView);
0586 NCollection_Mat4<T> anUnviewMat;
0587 if (!theWorldView.Inverted (anUnviewMat))
0588 {
0589 return NCollection_Mat4<T>();
0590 }
0591
0592
0593
0594 Apply (theCamera, theProjection, aWorldView, theViewportWidth, theViewportHeight);
0595 return anUnviewMat * aWorldView;
0596 }
0597
0598 #endif