File indexing completed on 2025-02-18 10:07:43
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 virtual NCollection_Mat3<Standard_Real> persistentRotationMatrix (const Handle(Graphic3d_Camera)& theCamera,
0251 const Standard_Integer theViewportWidth,
0252 const Standard_Integer theViewportHeight) const
0253 {
0254 (void )theCamera;
0255 (void )theViewportWidth;
0256 (void )theViewportHeight;
0257
0258 NCollection_Mat3<Standard_Real> aRotMat;
0259 return aRotMat;
0260 }
0261
0262
0263
0264
0265
0266
0267
0268
0269 template<class T>
0270 void Apply (const Handle(Graphic3d_Camera)& theCamera,
0271 const NCollection_Mat4<T>& theProjection,
0272 const NCollection_Mat4<T>& theWorldView,
0273 const Standard_Integer theViewportWidth,
0274 const Standard_Integer theViewportHeight,
0275 Bnd_Box& theBoundingBox) const;
0276
0277
0278
0279
0280
0281
0282
0283
0284 template<class T>
0285 void Apply (const Handle(Graphic3d_Camera)& theCamera,
0286 const NCollection_Mat4<T>& theProjection,
0287 const NCollection_Mat4<T>& theWorldView,
0288 const Standard_Integer theViewportWidth,
0289 const Standard_Integer theViewportHeight,
0290 BVH_Box<T, 3>& theBoundingBox) const;
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 template<class T>
0302 NCollection_Mat4<T> Compute (const Handle(Graphic3d_Camera)& theCamera,
0303 const NCollection_Mat4<T>& theProjection,
0304 const NCollection_Mat4<T>& theWorldView,
0305 const Standard_Integer theViewportWidth,
0306 const Standard_Integer theViewportHeight) const;
0307
0308
0309
0310
0311
0312
0313
0314
0315 template<class T>
0316 void Apply (const Handle(Graphic3d_Camera)& theCamera,
0317 const NCollection_Mat4<T>& theProjection,
0318 NCollection_Mat4<T>& theWorldView,
0319 const Standard_Integer theViewportWidth,
0320 const Standard_Integer theViewportHeight,
0321 const gp_Pnt* theAnchor = NULL) const;
0322
0323
0324 Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0325
0326 private:
0327
0328
0329 struct PersParams3d
0330 {
0331 Standard_Real PntX;
0332 Standard_Real PntY;
0333 Standard_Real PntZ;
0334
0335
0336 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0337 };
0338
0339
0340 struct PersParams2d
0341 {
0342 Standard_Integer OffsetX;
0343 Standard_Integer OffsetY;
0344 Aspect_TypeOfTriedronPosition Corner;
0345
0346
0347 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0348 };
0349
0350 private:
0351
0352 Graphic3d_TransModeFlags myMode;
0353 union
0354 {
0355 PersParams3d Params3d;
0356 PersParams2d Params2d;
0357 } myParams;
0358
0359 };
0360
0361
0362
0363
0364
0365 template<class T>
0366 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
0367 const NCollection_Mat4<T>& theProjection,
0368 NCollection_Mat4<T>& theWorldView,
0369 const Standard_Integer theViewportWidth,
0370 const Standard_Integer theViewportHeight,
0371 const gp_Pnt* theAnchor) const
0372 {
0373 (void )theViewportWidth;
0374 (void )theProjection;
0375 if (myMode == Graphic3d_TMF_None
0376 || theViewportHeight == 0)
0377 {
0378 return;
0379 }
0380
0381
0382 const Standard_Integer aVPSizeY = theCamera->Tile().IsValid() ? theCamera->Tile().TotalSize.y() : theViewportHeight;
0383
0384
0385
0386 const Standard_Real aJitterComp = 0.001;
0387 if (myMode == Graphic3d_TMF_TriedronPers)
0388 {
0389
0390 const Standard_Real aFocus = theCamera->IsOrthographic()
0391 ? theCamera->Distance()
0392 : (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
0393 ? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
0394 : Standard_Real(theCamera->ZFocus()));
0395
0396
0397 const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
0398 const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
0399 const gp_Dir aForward = theCamera->Direction();
0400 gp_XYZ aCenter = theCamera->Center().XYZ() + aForward.XYZ() * (aFocus - theCamera->Distance());
0401 if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
0402 {
0403 const Standard_Real anOffsetX = (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale;
0404 const gp_Dir aSide = aForward.Crossed (theCamera->Up());
0405 const gp_XYZ aDeltaX = aSide.XYZ() * (Abs(aViewDim.X()) * theCamera->NDC2dOffsetX() - anOffsetX);
0406 if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
0407 {
0408 aCenter += aDeltaX;
0409 }
0410 else
0411 {
0412 aCenter -= aDeltaX;
0413 }
0414 }
0415 if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
0416 {
0417 const Standard_Real anOffsetY = (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale;
0418 const gp_XYZ aDeltaY = theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * theCamera->NDC2dOffsetY() - anOffsetY);
0419 if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
0420 {
0421 aCenter += aDeltaY;
0422 }
0423 else
0424 {
0425 aCenter -= aDeltaY;
0426 }
0427 }
0428
0429 NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
0430 Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z());
0431 Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale);
0432 theWorldView.ConvertFrom (aWorldView);
0433 return;
0434 }
0435 else if (myMode == Graphic3d_TMF_2d)
0436 {
0437 const Standard_Real aFocus = theCamera->IsOrthographic()
0438 ? theCamera->Distance()
0439 : (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
0440 ? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
0441 : Standard_Real(theCamera->ZFocus()));
0442
0443
0444 const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
0445 const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
0446 gp_XYZ aCenter (0.0, 0.0, -aFocus);
0447 if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
0448 {
0449 aCenter.SetX (-aViewDim.X() * theCamera->NDC2dOffsetX() + (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale);
0450 if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
0451 {
0452 aCenter.SetX (-aCenter.X());
0453 }
0454 }
0455 if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
0456 {
0457 aCenter.SetY (-aViewDim.Y() * theCamera->NDC2dOffsetY() + (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale);
0458 if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
0459 {
0460 aCenter.SetY (-aCenter.Y());
0461 }
0462 }
0463
0464 theWorldView.InitIdentity();
0465 Graphic3d_TransformUtils::Translate (theWorldView, T(aCenter.X()), T(aCenter.Y()), T(aCenter.Z()));
0466 Graphic3d_TransformUtils::Scale (theWorldView, T(aScale), T(aScale), T(aScale));
0467 return;
0468 }
0469 else if ((myMode & Graphic3d_TMF_CameraPers) != 0)
0470 {
0471 theWorldView.InitIdentity();
0472 }
0473 else
0474 {
0475
0476 NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
0477 if (theAnchor != NULL)
0478 {
0479 Graphic3d_TransformUtils::Translate (aWorldView, theAnchor->X(), theAnchor->Y(), theAnchor->Z());
0480 }
0481 else
0482 {
0483 Graphic3d_TransformUtils::Translate (aWorldView, myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
0484 }
0485
0486 if ((myMode & Graphic3d_TMF_RotatePers) != 0)
0487 {
0488 NCollection_Mat3<Standard_Real> aRotMat = persistentRotationMatrix (theCamera, theViewportWidth, theViewportHeight);
0489
0490 aWorldView.SetValue (0, 0, aRotMat.GetColumn (0).x());
0491 aWorldView.SetValue (1, 0, aRotMat.GetColumn (0).y());
0492 aWorldView.SetValue (2, 0, aRotMat.GetColumn (0).z());
0493
0494 aWorldView.SetValue (0, 1, aRotMat.GetColumn (1).x());
0495 aWorldView.SetValue (1, 1, aRotMat.GetColumn (1).y());
0496 aWorldView.SetValue (2, 1, aRotMat.GetColumn (1).z());
0497
0498 aWorldView.SetValue (0, 2, aRotMat.GetColumn (2).x());
0499 aWorldView.SetValue (1, 2, aRotMat.GetColumn (2).y());
0500 aWorldView.SetValue (2, 2, aRotMat.GetColumn (2).z());
0501 }
0502
0503 if ((myMode & Graphic3d_TMF_ZoomPers) != 0)
0504 {
0505
0506 Standard_Real aScale = persistentScale (theCamera, theViewportWidth, theViewportHeight);
0507 Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale);
0508 }
0509 theWorldView.ConvertFrom (aWorldView);
0510 return;
0511 }
0512 }
0513
0514
0515
0516
0517
0518 template<class T>
0519 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
0520 const NCollection_Mat4<T>& theProjection,
0521 const NCollection_Mat4<T>& theWorldView,
0522 const Standard_Integer theViewportWidth,
0523 const Standard_Integer theViewportHeight,
0524 Bnd_Box& theBoundingBox) const
0525 {
0526 if (theBoundingBox.IsVoid())
0527 {
0528 return;
0529 }
0530
0531 T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
0532
0533 theBoundingBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
0534
0535 typename BVH_Box<T, 3>::BVH_VecNt aMin (aXmin, aYmin, aZmin);
0536 typename BVH_Box<T, 3>::BVH_VecNt aMax (aXmax, aYmax, aZmax);
0537 BVH_Box<T, 3> aBBox (aMin, aMax);
0538
0539 Apply (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox);
0540
0541 theBoundingBox = Bnd_Box();
0542 theBoundingBox.Update (aBBox.CornerMin().x(), aBBox.CornerMin().y(), aBBox.CornerMin().z(),
0543 aBBox.CornerMax().x(), aBBox.CornerMax().y(), aBBox.CornerMax().z());
0544 }
0545
0546
0547
0548
0549
0550 template<class T>
0551 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
0552 const NCollection_Mat4<T>& theProjection,
0553 const NCollection_Mat4<T>& theWorldView,
0554 const Standard_Integer theViewportWidth,
0555 const Standard_Integer theViewportHeight,
0556 BVH_Box<T, 3>& theBoundingBox) const
0557 {
0558 NCollection_Mat4<T> aTPers = Compute (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight);
0559 if (aTPers.IsIdentity()
0560 || !theBoundingBox.IsValid())
0561 {
0562 return;
0563 }
0564
0565 const typename BVH_Box<T, 3>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
0566 const typename BVH_Box<T, 3>::BVH_VecNt& aMax = theBoundingBox.CornerMax();
0567
0568 typename BVH_Box<T, 4>::BVH_VecNt anArrayOfCorners[8];
0569 anArrayOfCorners[0] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
0570 anArrayOfCorners[1] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
0571 anArrayOfCorners[2] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
0572 anArrayOfCorners[3] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
0573 anArrayOfCorners[4] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
0574 anArrayOfCorners[5] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
0575 anArrayOfCorners[6] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
0576 anArrayOfCorners[7] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
0577
0578 theBoundingBox.Clear();
0579 for (Standard_Integer anIt = 0; anIt < 8; ++anIt)
0580 {
0581 typename BVH_Box<T, 4>::BVH_VecNt& aCorner = anArrayOfCorners[anIt];
0582 aCorner = aTPers * aCorner;
0583 aCorner = aCorner / aCorner.w();
0584 theBoundingBox.Add (typename BVH_Box<T, 3>::BVH_VecNt (aCorner.x(), aCorner.y(), aCorner.z()));
0585 }
0586 }
0587
0588
0589
0590
0591
0592 template<class T>
0593 NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const Handle(Graphic3d_Camera)& theCamera,
0594 const NCollection_Mat4<T>& theProjection,
0595 const NCollection_Mat4<T>& theWorldView,
0596 const Standard_Integer theViewportWidth,
0597 const Standard_Integer theViewportHeight) const
0598 {
0599 if (myMode == Graphic3d_TMF_None)
0600 {
0601 return NCollection_Mat4<T>();
0602 }
0603
0604 NCollection_Mat4<T> aWorldView (theWorldView);
0605 NCollection_Mat4<T> anUnviewMat;
0606 if (!theWorldView.Inverted (anUnviewMat))
0607 {
0608 return NCollection_Mat4<T>();
0609 }
0610
0611
0612
0613 Apply (theCamera, theProjection, aWorldView, theViewportWidth, theViewportHeight);
0614 return anUnviewMat * aWorldView;
0615 }
0616
0617 #endif