0024413: Visualization - get rid of projection shift from orthographic camera definition
authorapl <apl@opencascade.com>
Thu, 6 Mar 2014 11:15:53 +0000 (15:15 +0400)
committerabv <abv@opencascade.com>
Thu, 6 Mar 2014 11:50:33 +0000 (15:50 +0400)
From now on, the panning behavior of V3d_View completely corresponds to equal operations with camera. There is no more confusing "Center" property and "ProjectionShift" which were used to introduce composite panning, while respecting view referential points: At, Eye unchanged. The V3d_View::FitAll approach has been rewritten to do "fit all" geometrically, operating with frustum, to make it working for both orthographic and perspective projections.

1) Getting rid of ProjectionShift and Center property:
- Removed ProjectionShift property of Graphic3d_Camera.
- Removed confusing Center property of V3d_View (related to projection shift).
- Removed redundant code related to the Center property of V3d_View.
- Removed WindowLimit method of Graphic3d_Camera - no more used.

2) Improvements of fit all and selector:
- Improved FitAll operation of V3d_View and reused it in NIS_View - the perspective projection is now handled correctly.
- Revised code of Select3D_Projector class - can be defined with any given projection and model-view matrices.
- Modified StdSelect_ViewerSelector3d and ensured that panning, zooming and going into the view do not lead to unwanted re-projection of sensitives. The handling of perspective selection is revised.
- Take into account graphical boundaries of infinite structure on ZFitAll.

3) Improvements of camera:
- Introduced new z range scale parameter for V3d_View::AutoZFit. See, V3d_View::AutoZFitMode.
- Allow negative ZNear, ZFar for orthographic camera to avoid clipping of viewed model.
- Moved camera ZNear, ZFar validity checks to V3d_View level.
- Use more meaningful Standard_ShortReal relative precision for ZNear, ZFar ranges computed by ZFitAll.
- Use Standard_Real type for camera projection and orientation matrices.
- Extended camera to generate both Standard_Real and Standard_ShortReal transformation matrices using the same matrix evaluation methods and converted input parameters.

Correcting picking tests for perspective view

Modify v3d face test cases for 1px changes in face picking

Modified test cases for new arguments of vviewparams DRAWEXE command

780 files changed:
src/Graphic3d/FILES
src/Graphic3d/Graphic3d.cdl
src/Graphic3d/Graphic3d_Camera.cxx
src/Graphic3d/Graphic3d_Camera.hxx
src/Graphic3d/Graphic3d_Mat4.hxx
src/Graphic3d/Graphic3d_Mat4d.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_Structure.cdl
src/Graphic3d/Graphic3d_Structure.cxx
src/Graphic3d/Graphic3d_Vec.hxx
src/NCollection/NCollection_Mat4.hxx
src/NIS/NIS_View.cxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View_2.cxx
src/QABugs/QABugs_16.cxx
src/Select3D/Select3D.cdl
src/Select3D/Select3D_Projector.cdl
src/Select3D/Select3D_Projector.cxx
src/Select3D/Select3D_Projector.lxx
src/StdSelect/StdSelect_ViewerSelector3d.cdl
src/StdSelect/StdSelect_ViewerSelector3d.cxx
src/StdSelect/StdSelect_ViewerSelector3d.lxx
src/V3d/V3d_View.cdl
src/V3d/V3d_View.cxx
src/V3d/V3d_View_3.cxx
src/ViewerTest/ViewerTest.cdl
src/ViewerTest/ViewerTest.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/Visual3d/Visual3d_View.cdl
src/Visual3d/Visual3d_View.cxx
tests/bugs/modalg_2/bug20785
tests/bugs/modalg_2/bug21255
tests/bugs/modalg_2/bug21261_1
tests/bugs/modalg_2/bug21261_10
tests/bugs/modalg_2/bug21261_11
tests/bugs/modalg_2/bug21261_2
tests/bugs/modalg_2/bug21261_3
tests/bugs/modalg_2/bug21261_4
tests/bugs/modalg_2/bug21261_40
tests/bugs/modalg_2/bug21261_41
tests/bugs/modalg_2/bug21261_42
tests/bugs/modalg_2/bug21261_43
tests/bugs/modalg_2/bug21261_44
tests/bugs/modalg_2/bug21261_5
tests/bugs/modalg_2/bug21261_6
tests/bugs/modalg_2/bug21261_7
tests/bugs/modalg_2/bug21261_8
tests/bugs/modalg_2/bug21261_9
tests/bugs/modalg_2/bug21415
tests/bugs/modalg_2/bug21909
tests/bugs/modalg_4/bug895
tests/bugs/modalg_5/bug24012
tests/bugs/moddata_1/bug20
tests/bugs/vis/buc60688
tests/bugs/vis/bug113
tests/bugs/vis/bug1174
tests/bugs/vis/bug128
tests/bugs/vis/bug137_4
tests/bugs/vis/bug137_5
tests/bugs/vis/bug215
tests/bugs/vis/bug218
tests/bugs/vis/bug22313
tests/bugs/vis/bug22701
tests/bugs/vis/bug23652
tests/bugs/vis/bug280_2
tests/bugs/vis/bug280_3
tests/bugs/vis/bug281_1
tests/bugs/vis/bug319
tests/bugs/vis/bug349
tests/bugs/vis/bug349_1
tests/bugs/vis/bug544
tests/v3d/edge/A3
tests/v3d/edge/A4
tests/v3d/edge/A5
tests/v3d/edge/A6
tests/v3d/edge/A7
tests/v3d/edge/A8
tests/v3d/edge/A9
tests/v3d/edge/B1
tests/v3d/edge/C3
tests/v3d/edge/C4
tests/v3d/edge/C5
tests/v3d/edge/C6
tests/v3d/edge/C7
tests/v3d/edge/C8
tests/v3d/edge/C9
tests/v3d/edge/D1
tests/v3d/edge/D2
tests/v3d/edge/D3
tests/v3d/edge/D4
tests/v3d/edge/D5
tests/v3d/edge/D6
tests/v3d/edge/D7
tests/v3d/edge/D8
tests/v3d/edge/D9
tests/v3d/edge/E1
tests/v3d/edge/E2
tests/v3d/edge/E3
tests/v3d/edge/E4
tests/v3d/edge/E5
tests/v3d/edge/E6
tests/v3d/edge/E7
tests/v3d/edge/E8
tests/v3d/edge/E9
tests/v3d/edge/F1
tests/v3d/edge/F2
tests/v3d/edge_face/A3
tests/v3d/edge_face/A4
tests/v3d/edge_face/A5
tests/v3d/edge_face/A6
tests/v3d/edge_face/A7
tests/v3d/edge_face/A8
tests/v3d/edge_face/A9
tests/v3d/edge_face/B1
tests/v3d/edge_face/C3
tests/v3d/edge_face/C4
tests/v3d/edge_face/C5
tests/v3d/edge_face/C6
tests/v3d/edge_face/C7
tests/v3d/edge_face/C8
tests/v3d/edge_face/C9
tests/v3d/edge_face/D1
tests/v3d/edge_face/D2
tests/v3d/edge_face/D3
tests/v3d/edge_face/D4
tests/v3d/edge_face/D5
tests/v3d/edge_face/D6
tests/v3d/edge_face/D7
tests/v3d/edge_face/D8
tests/v3d/edge_face/D9
tests/v3d/edge_face/E1
tests/v3d/edge_face/E2
tests/v3d/edge_face/E3
tests/v3d/edge_face/E4
tests/v3d/edge_face/E5
tests/v3d/edge_face/E6
tests/v3d/edge_face/E7
tests/v3d/edge_face/E8
tests/v3d/edge_face/E9
tests/v3d/edge_face/F1
tests/v3d/edge_face/F2
tests/v3d/edge_face/F5
tests/v3d/edge_face/F6
tests/v3d/edge_face/F7
tests/v3d/edge_face/F8
tests/v3d/edge_face/F9
tests/v3d/edge_face/G1
tests/v3d/edge_face/G2
tests/v3d/edge_face/G3
tests/v3d/edge_face/H5
tests/v3d/edge_face/H6
tests/v3d/edge_face/H7
tests/v3d/edge_face/H8
tests/v3d/edge_face/H9
tests/v3d/edge_face/I1
tests/v3d/edge_face/I2
tests/v3d/edge_face/I3
tests/v3d/edge_face/I4
tests/v3d/edge_face/I5
tests/v3d/edge_face/I6
tests/v3d/edge_face/I7
tests/v3d/edge_face/I8
tests/v3d/edge_face/I9
tests/v3d/edge_face/J1
tests/v3d/edge_face/J2
tests/v3d/edge_face/J3
tests/v3d/edge_face/J4
tests/v3d/edge_face/J5
tests/v3d/edge_face/J6
tests/v3d/edge_face/J7
tests/v3d/edge_face/J8
tests/v3d/edge_face/J9
tests/v3d/edge_face/K1
tests/v3d/edge_face/K2
tests/v3d/edge_face/K3
tests/v3d/edge_face/K4
tests/v3d/edge_face/K7
tests/v3d/edge_face/K8
tests/v3d/edge_face/K9
tests/v3d/edge_face/L1
tests/v3d/edge_face/L2
tests/v3d/edge_face/L3
tests/v3d/edge_face/L4
tests/v3d/edge_face/L5
tests/v3d/edge_face/M7
tests/v3d/edge_face/M8
tests/v3d/edge_face/M9
tests/v3d/edge_face/N1
tests/v3d/edge_face/N2
tests/v3d/edge_face/N3
tests/v3d/edge_face/N4
tests/v3d/edge_face/N5
tests/v3d/edge_face/N6
tests/v3d/edge_face/N7
tests/v3d/edge_face/N8
tests/v3d/edge_face/N9
tests/v3d/edge_face/O1
tests/v3d/edge_face/O2
tests/v3d/edge_face/O3
tests/v3d/edge_face/O4
tests/v3d/edge_face/O5
tests/v3d/edge_face/O6
tests/v3d/edge_face/O7
tests/v3d/edge_face/O8
tests/v3d/edge_face/O9
tests/v3d/edge_face/P1
tests/v3d/edge_face/P2
tests/v3d/edge_face/P3
tests/v3d/edge_face/P4
tests/v3d/edge_face/P5
tests/v3d/edge_face/P6
tests/v3d/edge_solid/A3
tests/v3d/edge_solid/A4
tests/v3d/edge_solid/A5
tests/v3d/edge_solid/A6
tests/v3d/edge_solid/A7
tests/v3d/edge_solid/A8
tests/v3d/edge_solid/A9
tests/v3d/edge_solid/B1
tests/v3d/edge_solid/C3
tests/v3d/edge_solid/C4
tests/v3d/edge_solid/C5
tests/v3d/edge_solid/C6
tests/v3d/edge_solid/C7
tests/v3d/edge_solid/C8
tests/v3d/edge_solid/C9
tests/v3d/edge_solid/D1
tests/v3d/edge_solid/D2
tests/v3d/edge_solid/D3
tests/v3d/edge_solid/D4
tests/v3d/edge_solid/D5
tests/v3d/edge_solid/D6
tests/v3d/edge_solid/D7
tests/v3d/edge_solid/D8
tests/v3d/edge_solid/D9
tests/v3d/edge_solid/E1
tests/v3d/edge_solid/E2
tests/v3d/edge_solid/E3
tests/v3d/edge_solid/E4
tests/v3d/edge_solid/E5
tests/v3d/edge_solid/E6
tests/v3d/edge_solid/E7
tests/v3d/edge_solid/E8
tests/v3d/edge_solid/E9
tests/v3d/edge_solid/F1
tests/v3d/edge_solid/F2
tests/v3d/edge_solid/F5
tests/v3d/edge_solid/F6
tests/v3d/edge_solid/F7
tests/v3d/edge_solid/F8
tests/v3d/edge_solid/F9
tests/v3d/edge_solid/G1
tests/v3d/edge_solid/G2
tests/v3d/edge_solid/G3
tests/v3d/edge_solid/H5
tests/v3d/edge_solid/H6
tests/v3d/edge_solid/H7
tests/v3d/edge_solid/H8
tests/v3d/edge_solid/H9
tests/v3d/edge_solid/I1
tests/v3d/edge_solid/I2
tests/v3d/edge_solid/I3
tests/v3d/edge_solid/I4
tests/v3d/edge_solid/I5
tests/v3d/edge_solid/I6
tests/v3d/edge_solid/I7
tests/v3d/edge_solid/I8
tests/v3d/edge_solid/I9
tests/v3d/edge_solid/J1
tests/v3d/edge_solid/J2
tests/v3d/edge_solid/J3
tests/v3d/edge_solid/J4
tests/v3d/edge_solid/J5
tests/v3d/edge_solid/J6
tests/v3d/edge_solid/J7
tests/v3d/edge_solid/J8
tests/v3d/edge_solid/J9
tests/v3d/edge_solid/K1
tests/v3d/edge_solid/K2
tests/v3d/edge_solid/K3
tests/v3d/edge_solid/K4
tests/v3d/edge_solid/K7
tests/v3d/edge_solid/K8
tests/v3d/edge_solid/K9
tests/v3d/edge_solid/L1
tests/v3d/edge_solid/L2
tests/v3d/edge_solid/L3
tests/v3d/edge_solid/L4
tests/v3d/edge_solid/L5
tests/v3d/edge_solid/M7
tests/v3d/edge_solid/M8
tests/v3d/edge_solid/M9
tests/v3d/edge_solid/N1
tests/v3d/edge_solid/N2
tests/v3d/edge_solid/N3
tests/v3d/edge_solid/N4
tests/v3d/edge_solid/N5
tests/v3d/edge_solid/N6
tests/v3d/edge_solid/N7
tests/v3d/edge_solid/N8
tests/v3d/edge_solid/N9
tests/v3d/edge_solid/O1
tests/v3d/edge_solid/O2
tests/v3d/edge_solid/O3
tests/v3d/edge_solid/O4
tests/v3d/edge_solid/O5
tests/v3d/edge_solid/O6
tests/v3d/edge_solid/O7
tests/v3d/edge_solid/O8
tests/v3d/edge_solid/O9
tests/v3d/edge_solid/P1
tests/v3d/edge_solid/P2
tests/v3d/edge_solid/P3
tests/v3d/edge_solid/P4
tests/v3d/edge_solid/P5
tests/v3d/edge_solid/P6
tests/v3d/face/A3
tests/v3d/face/A4
tests/v3d/face/A5
tests/v3d/face/A6
tests/v3d/face/A7
tests/v3d/face/A8
tests/v3d/face/A9
tests/v3d/face/B1
tests/v3d/face/B2
tests/v3d/face/B3
tests/v3d/face/B4
tests/v3d/face/B5
tests/v3d/face/B6
tests/v3d/face/B7
tests/v3d/face/B8
tests/v3d/face/B9
tests/v3d/face/C1
tests/v3d/face/C2
tests/v3d/face/C3
tests/v3d/face/C4
tests/v3d/face/C5
tests/v3d/face/C6
tests/v3d/face/C7
tests/v3d/face/C8
tests/v3d/face/C9
tests/v3d/face/D1
tests/v3d/face/D2
tests/v3d/face/D3
tests/v3d/face/D4
tests/v3d/face/D5
tests/v3d/face/D6
tests/v3d/face/D7
tests/v3d/face/D8
tests/v3d/face/D9
tests/v3d/face/E1
tests/v3d/face/E2
tests/v3d/face/E3
tests/v3d/face/E4
tests/v3d/face/E5
tests/v3d/face/E6
tests/v3d/face/E7
tests/v3d/face/E8
tests/v3d/face/E9
tests/v3d/face/F1
tests/v3d/face/F2
tests/v3d/vertex/A3
tests/v3d/vertex/A4
tests/v3d/vertex/A5
tests/v3d/vertex/A6
tests/v3d/vertex/A7
tests/v3d/vertex/A8
tests/v3d/vertex/A9
tests/v3d/vertex/B1
tests/v3d/vertex/C3
tests/v3d/vertex/C4
tests/v3d/vertex/C5
tests/v3d/vertex/C6
tests/v3d/vertex/C7
tests/v3d/vertex/C8
tests/v3d/vertex/C9
tests/v3d/vertex/D1
tests/v3d/vertex/D2
tests/v3d/vertex/D3
tests/v3d/vertex/D4
tests/v3d/vertex/D5
tests/v3d/vertex/D6
tests/v3d/vertex/D7
tests/v3d/vertex/D8
tests/v3d/vertex/D9
tests/v3d/vertex/E1
tests/v3d/vertex/E2
tests/v3d/vertex/E3
tests/v3d/vertex/E4
tests/v3d/vertex/E5
tests/v3d/vertex/E6
tests/v3d/vertex/E7
tests/v3d/vertex/E8
tests/v3d/vertex/E9
tests/v3d/vertex/F1
tests/v3d/vertex/F2
tests/v3d/vertex_edge/A3
tests/v3d/vertex_edge/A4
tests/v3d/vertex_edge/A5
tests/v3d/vertex_edge/A6
tests/v3d/vertex_edge/A7
tests/v3d/vertex_edge/A8
tests/v3d/vertex_edge/A9
tests/v3d/vertex_edge/B1
tests/v3d/vertex_edge/C3
tests/v3d/vertex_edge/C4
tests/v3d/vertex_edge/C5
tests/v3d/vertex_edge/C6
tests/v3d/vertex_edge/C7
tests/v3d/vertex_edge/C8
tests/v3d/vertex_edge/C9
tests/v3d/vertex_edge/D1
tests/v3d/vertex_edge/D2
tests/v3d/vertex_edge/D3
tests/v3d/vertex_edge/D4
tests/v3d/vertex_edge/D5
tests/v3d/vertex_edge/D6
tests/v3d/vertex_edge/D7
tests/v3d/vertex_edge/D8
tests/v3d/vertex_edge/D9
tests/v3d/vertex_edge/E1
tests/v3d/vertex_edge/E2
tests/v3d/vertex_edge/E3
tests/v3d/vertex_edge/E4
tests/v3d/vertex_edge/E5
tests/v3d/vertex_edge/E6
tests/v3d/vertex_edge/E7
tests/v3d/vertex_edge/E8
tests/v3d/vertex_edge/E9
tests/v3d/vertex_edge/F1
tests/v3d/vertex_edge/F2
tests/v3d/vertex_edge/F5
tests/v3d/vertex_edge/F6
tests/v3d/vertex_edge/F7
tests/v3d/vertex_edge/F8
tests/v3d/vertex_edge/F9
tests/v3d/vertex_edge/G1
tests/v3d/vertex_edge/G2
tests/v3d/vertex_edge/G3
tests/v3d/vertex_edge/H5
tests/v3d/vertex_edge/H6
tests/v3d/vertex_edge/H7
tests/v3d/vertex_edge/H8
tests/v3d/vertex_edge/H9
tests/v3d/vertex_edge/I1
tests/v3d/vertex_edge/I2
tests/v3d/vertex_edge/I3
tests/v3d/vertex_edge/I4
tests/v3d/vertex_edge/I5
tests/v3d/vertex_edge/I6
tests/v3d/vertex_edge/I7
tests/v3d/vertex_edge/I8
tests/v3d/vertex_edge/I9
tests/v3d/vertex_edge/J1
tests/v3d/vertex_edge/J2
tests/v3d/vertex_edge/J3
tests/v3d/vertex_edge/J4
tests/v3d/vertex_edge/J5
tests/v3d/vertex_edge/J6
tests/v3d/vertex_edge/J7
tests/v3d/vertex_edge/J8
tests/v3d/vertex_edge/J9
tests/v3d/vertex_edge/K1
tests/v3d/vertex_edge/K2
tests/v3d/vertex_edge/K3
tests/v3d/vertex_edge/K4
tests/v3d/vertex_face/A3
tests/v3d/vertex_face/A4
tests/v3d/vertex_face/A5
tests/v3d/vertex_face/A6
tests/v3d/vertex_face/A7
tests/v3d/vertex_face/A8
tests/v3d/vertex_face/A9
tests/v3d/vertex_face/B1
tests/v3d/vertex_face/C3
tests/v3d/vertex_face/C4
tests/v3d/vertex_face/C5
tests/v3d/vertex_face/C6
tests/v3d/vertex_face/C7
tests/v3d/vertex_face/C8
tests/v3d/vertex_face/C9
tests/v3d/vertex_face/D1
tests/v3d/vertex_face/D2
tests/v3d/vertex_face/D3
tests/v3d/vertex_face/D4
tests/v3d/vertex_face/D5
tests/v3d/vertex_face/D6
tests/v3d/vertex_face/D7
tests/v3d/vertex_face/D8
tests/v3d/vertex_face/D9
tests/v3d/vertex_face/E1
tests/v3d/vertex_face/E2
tests/v3d/vertex_face/E3
tests/v3d/vertex_face/E4
tests/v3d/vertex_face/E5
tests/v3d/vertex_face/E6
tests/v3d/vertex_face/E7
tests/v3d/vertex_face/E8
tests/v3d/vertex_face/E9
tests/v3d/vertex_face/F1
tests/v3d/vertex_face/F2
tests/v3d/vertex_face/F5
tests/v3d/vertex_face/F6
tests/v3d/vertex_face/F7
tests/v3d/vertex_face/F8
tests/v3d/vertex_face/F9
tests/v3d/vertex_face/G1
tests/v3d/vertex_face/G2
tests/v3d/vertex_face/G3
tests/v3d/vertex_face/H5
tests/v3d/vertex_face/H6
tests/v3d/vertex_face/H7
tests/v3d/vertex_face/H8
tests/v3d/vertex_face/H9
tests/v3d/vertex_face/I1
tests/v3d/vertex_face/I2
tests/v3d/vertex_face/I3
tests/v3d/vertex_face/I4
tests/v3d/vertex_face/I5
tests/v3d/vertex_face/I6
tests/v3d/vertex_face/I7
tests/v3d/vertex_face/I8
tests/v3d/vertex_face/I9
tests/v3d/vertex_face/J1
tests/v3d/vertex_face/J2
tests/v3d/vertex_face/J3
tests/v3d/vertex_face/J4
tests/v3d/vertex_face/J5
tests/v3d/vertex_face/J6
tests/v3d/vertex_face/J7
tests/v3d/vertex_face/J8
tests/v3d/vertex_face/J9
tests/v3d/vertex_face/K1
tests/v3d/vertex_face/K2
tests/v3d/vertex_face/K3
tests/v3d/vertex_face/K4
tests/v3d/vertex_solid/A3
tests/v3d/vertex_solid/A4
tests/v3d/vertex_solid/A5
tests/v3d/vertex_solid/A6
tests/v3d/vertex_solid/A7
tests/v3d/vertex_solid/A8
tests/v3d/vertex_solid/A9
tests/v3d/vertex_solid/B1
tests/v3d/vertex_solid/C3
tests/v3d/vertex_solid/C4
tests/v3d/vertex_solid/C5
tests/v3d/vertex_solid/C6
tests/v3d/vertex_solid/C7
tests/v3d/vertex_solid/C8
tests/v3d/vertex_solid/C9
tests/v3d/vertex_solid/D1
tests/v3d/vertex_solid/D2
tests/v3d/vertex_solid/D3
tests/v3d/vertex_solid/D4
tests/v3d/vertex_solid/D5
tests/v3d/vertex_solid/D6
tests/v3d/vertex_solid/D7
tests/v3d/vertex_solid/D8
tests/v3d/vertex_solid/D9
tests/v3d/vertex_solid/E1
tests/v3d/vertex_solid/E2
tests/v3d/vertex_solid/E3
tests/v3d/vertex_solid/E4
tests/v3d/vertex_solid/E5
tests/v3d/vertex_solid/E6
tests/v3d/vertex_solid/E7
tests/v3d/vertex_solid/E8
tests/v3d/vertex_solid/E9
tests/v3d/vertex_solid/F1
tests/v3d/vertex_solid/F2
tests/v3d/vertex_solid/F5
tests/v3d/vertex_solid/F6
tests/v3d/vertex_solid/F7
tests/v3d/vertex_solid/F8
tests/v3d/vertex_solid/F9
tests/v3d/vertex_solid/G1
tests/v3d/vertex_solid/G2
tests/v3d/vertex_solid/G3
tests/v3d/vertex_solid/H5
tests/v3d/vertex_solid/H6
tests/v3d/vertex_solid/H7
tests/v3d/vertex_solid/H8
tests/v3d/vertex_solid/H9
tests/v3d/vertex_solid/I1
tests/v3d/vertex_solid/I2
tests/v3d/vertex_solid/I3
tests/v3d/vertex_solid/I4
tests/v3d/vertex_solid/I5
tests/v3d/vertex_solid/I6
tests/v3d/vertex_solid/I7
tests/v3d/vertex_solid/I8
tests/v3d/vertex_solid/I9
tests/v3d/vertex_solid/J1
tests/v3d/vertex_solid/J2
tests/v3d/vertex_solid/J3
tests/v3d/vertex_solid/J4
tests/v3d/vertex_solid/J5
tests/v3d/vertex_solid/J6
tests/v3d/vertex_solid/J7
tests/v3d/vertex_solid/J8
tests/v3d/vertex_solid/J9
tests/v3d/vertex_solid/K1
tests/v3d/vertex_solid/K2
tests/v3d/vertex_solid/K3
tests/v3d/vertex_solid/K4
tests/v3d/vertex_wire/A3
tests/v3d/vertex_wire/A4
tests/v3d/vertex_wire/A5
tests/v3d/vertex_wire/A6
tests/v3d/vertex_wire/A7
tests/v3d/vertex_wire/A8
tests/v3d/vertex_wire/A9
tests/v3d/vertex_wire/B1
tests/v3d/vertex_wire/C3
tests/v3d/vertex_wire/C4
tests/v3d/vertex_wire/C5
tests/v3d/vertex_wire/C6
tests/v3d/vertex_wire/C7
tests/v3d/vertex_wire/C8
tests/v3d/vertex_wire/C9
tests/v3d/vertex_wire/D1
tests/v3d/vertex_wire/D2
tests/v3d/vertex_wire/D3
tests/v3d/vertex_wire/D4
tests/v3d/vertex_wire/D5
tests/v3d/vertex_wire/D6
tests/v3d/vertex_wire/D7
tests/v3d/vertex_wire/D8
tests/v3d/vertex_wire/D9
tests/v3d/vertex_wire/E1
tests/v3d/vertex_wire/E2
tests/v3d/vertex_wire/E3
tests/v3d/vertex_wire/E4
tests/v3d/vertex_wire/E5
tests/v3d/vertex_wire/E6
tests/v3d/vertex_wire/E7
tests/v3d/vertex_wire/E8
tests/v3d/vertex_wire/E9
tests/v3d/vertex_wire/F1
tests/v3d/vertex_wire/F2
tests/v3d/vertex_wire/F5
tests/v3d/vertex_wire/F6
tests/v3d/vertex_wire/F7
tests/v3d/vertex_wire/F8
tests/v3d/vertex_wire/F9
tests/v3d/vertex_wire/G1
tests/v3d/vertex_wire/G2
tests/v3d/vertex_wire/G3
tests/v3d/vertex_wire/H5
tests/v3d/vertex_wire/H6
tests/v3d/vertex_wire/H7
tests/v3d/vertex_wire/H8
tests/v3d/vertex_wire/H9
tests/v3d/vertex_wire/I1
tests/v3d/vertex_wire/I2
tests/v3d/vertex_wire/I3
tests/v3d/vertex_wire/I4
tests/v3d/vertex_wire/I5
tests/v3d/vertex_wire/I6
tests/v3d/vertex_wire/I7
tests/v3d/vertex_wire/I8
tests/v3d/vertex_wire/I9
tests/v3d/vertex_wire/J1
tests/v3d/vertex_wire/J2
tests/v3d/vertex_wire/J3
tests/v3d/vertex_wire/J4
tests/v3d/vertex_wire/J5
tests/v3d/vertex_wire/J6
tests/v3d/vertex_wire/J7
tests/v3d/vertex_wire/J8
tests/v3d/vertex_wire/J9
tests/v3d/vertex_wire/K1
tests/v3d/vertex_wire/K2
tests/v3d/vertex_wire/K3
tests/v3d/vertex_wire/K4
tests/v3d/wire/A3
tests/v3d/wire/A4
tests/v3d/wire/A5
tests/v3d/wire/A6
tests/v3d/wire/A7
tests/v3d/wire/A8
tests/v3d/wire/A9
tests/v3d/wire/B1
tests/v3d/wire/C3
tests/v3d/wire/C4
tests/v3d/wire/C5
tests/v3d/wire/C6
tests/v3d/wire/C7
tests/v3d/wire/C8
tests/v3d/wire/C9
tests/v3d/wire/D1
tests/v3d/wire/D2
tests/v3d/wire/D3
tests/v3d/wire/D4
tests/v3d/wire/D5
tests/v3d/wire/D6
tests/v3d/wire/D7
tests/v3d/wire/D8
tests/v3d/wire/D9
tests/v3d/wire/E1
tests/v3d/wire/E2
tests/v3d/wire/E3
tests/v3d/wire/E4
tests/v3d/wire/E5
tests/v3d/wire/E6
tests/v3d/wire/E7
tests/v3d/wire/E8
tests/v3d/wire/E9
tests/v3d/wire/F1
tests/v3d/wire/F2
tests/v3d/wire_solid/A3
tests/v3d/wire_solid/A4
tests/v3d/wire_solid/A5
tests/v3d/wire_solid/A6
tests/v3d/wire_solid/A7
tests/v3d/wire_solid/A8
tests/v3d/wire_solid/A9
tests/v3d/wire_solid/B1
tests/v3d/wire_solid/C3
tests/v3d/wire_solid/C4
tests/v3d/wire_solid/C5
tests/v3d/wire_solid/C6
tests/v3d/wire_solid/C7
tests/v3d/wire_solid/C8
tests/v3d/wire_solid/C9
tests/v3d/wire_solid/D1
tests/v3d/wire_solid/D2
tests/v3d/wire_solid/D3
tests/v3d/wire_solid/D4
tests/v3d/wire_solid/D5
tests/v3d/wire_solid/D6
tests/v3d/wire_solid/D7
tests/v3d/wire_solid/D8
tests/v3d/wire_solid/D9
tests/v3d/wire_solid/E1
tests/v3d/wire_solid/E2
tests/v3d/wire_solid/E3
tests/v3d/wire_solid/E4
tests/v3d/wire_solid/E5
tests/v3d/wire_solid/E6
tests/v3d/wire_solid/E7
tests/v3d/wire_solid/E8
tests/v3d/wire_solid/E9
tests/v3d/wire_solid/F1
tests/v3d/wire_solid/F2
tests/v3d/wire_solid/F5
tests/v3d/wire_solid/F6
tests/v3d/wire_solid/F7
tests/v3d/wire_solid/F8
tests/v3d/wire_solid/F9
tests/v3d/wire_solid/G1
tests/v3d/wire_solid/G2
tests/v3d/wire_solid/G3
tests/v3d/wire_solid/H5
tests/v3d/wire_solid/H6
tests/v3d/wire_solid/H7
tests/v3d/wire_solid/H8
tests/v3d/wire_solid/H9
tests/v3d/wire_solid/I1
tests/v3d/wire_solid/I2
tests/v3d/wire_solid/I3
tests/v3d/wire_solid/I4
tests/v3d/wire_solid/I5
tests/v3d/wire_solid/I6
tests/v3d/wire_solid/I7
tests/v3d/wire_solid/I8
tests/v3d/wire_solid/I9
tests/v3d/wire_solid/J1
tests/v3d/wire_solid/J2
tests/v3d/wire_solid/J3
tests/v3d/wire_solid/J4
tests/v3d/wire_solid/J5
tests/v3d/wire_solid/J6
tests/v3d/wire_solid/J7
tests/v3d/wire_solid/J8
tests/v3d/wire_solid/J9
tests/v3d/wire_solid/K1
tests/v3d/wire_solid/K2
tests/v3d/wire_solid/K3
tests/v3d/wire_solid/K4

index ffe8d9b..f324a12 100755 (executable)
@@ -61,6 +61,7 @@ Graphic3d_Vec2.hxx
 Graphic3d_Vec3.hxx
 Graphic3d_Vec4.hxx
 Graphic3d_Mat4.hxx
+Graphic3d_Mat4d.hxx
 Graphic3d_Vertex.hxx
 Graphic3d_Vertex.cxx
 Graphic3d_MarkerImage.hxx
index 44ac5b1..a9a9a2a 100644 (file)
@@ -417,8 +417,8 @@ is
     primitive Vec2;
     primitive Vec3;
     primitive Vec4;
-    primitive Mat4;
-    primitive Mat4d;
+    imported  Mat4;
+    imported  Mat4d;
 
     --------------------
     -- Category: Classes
index 3211619..b963487 100644 (file)
@@ -20,6 +20,7 @@
 #include <Graphic3d_Camera.hxx>
 
 #include <Standard_Atomic.hxx>
+#include <Standard_Assert.hxx>
 
 IMPLEMENT_STANDARD_HANDLE(Graphic3d_Camera, Standard_Transient)
 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Camera, Standard_Transient)
@@ -27,7 +28,11 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Camera, Standard_Transient)
 namespace
 {
   // (degrees -> radians) * 0.5
-  static const Standard_ShortReal DTR_HALF = 0.5f * 0.0174532925f;
+  static const Standard_Real DTR_HALF = 0.5 * 0.0174532925;
+
+  // default property values
+  static const Standard_Real DEFAULT_ZNEAR = 0.001;
+  static const Standard_Real DEFAULT_ZFAR  = 3000.0;
 
   // atomic state counter
   static volatile Standard_Integer THE_STATE_COUNTER = 0;
@@ -41,30 +46,20 @@ Graphic3d_Camera::Graphic3d_Camera()
 : myUp (0.0, 1.0, 0.0),
   myEye (0.0, 0.0, -1500.0),
   myCenter (0.0, 0.0, 0.0),
-  myProjectionShift (0.0, 0.0, 0.0),
   myAxialScale (1.0, 1.0, 1.0),
   myProjType (Projection_Orthographic),
   myFOVy (45.0),
-  myZNear (0.001),
-  myZFar (3000.0),
+  myZNear (DEFAULT_ZNEAR),
+  myZFar (DEFAULT_ZFAR),
   myAspect (1.0),
   myScale (1000.0),
   myZFocus (1.0),
   myZFocusType (FocusType_Relative),
   myIOD (0.05),
-  myIODType (IODType_Relative),
-  myNbUpdateLocks (0)
+  myIODType (IODType_Relative)
 {
   myProjectionState  = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
   myOrientationState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
-
-  myOrientation.InitIdentity();
-  myMProjection.InitIdentity();
-  myLProjection.InitIdentity();
-  myRProjection.InitIdentity();
-
-  UpdateProjection();
-  UpdateOrientation();
 }
 
 // =======================================================================
@@ -72,7 +67,6 @@ Graphic3d_Camera::Graphic3d_Camera()
 // purpose  :
 // =======================================================================
 Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
-: myNbUpdateLocks (0)
 {
   Copy (theOther);
 }
@@ -83,21 +77,19 @@ Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
 // =======================================================================
 void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOtherCamera)
 {
-  myProjectionShift     = theOtherCamera->myProjectionShift;
-  myFOVy                = theOtherCamera->myFOVy;
-  myZNear               = theOtherCamera->myZNear;
-  myZFar                = theOtherCamera->myZFar;
-  myAspect              = theOtherCamera->myAspect;
-  myScale               = theOtherCamera->myScale;
-  myZFocus              = theOtherCamera->myZFocus;
-  myZFocusType          = theOtherCamera->myZFocusType;
-  myIOD                 = theOtherCamera->myIOD;
-  myIODType             = theOtherCamera->myIODType;
-  myProjType            = theOtherCamera->myProjType;
+  myFOVy            = theOtherCamera->myFOVy;
+  myZNear           = theOtherCamera->myZNear;
+  myZFar            = theOtherCamera->myZFar;
+  myAspect          = theOtherCamera->myAspect;
+  myScale           = theOtherCamera->myScale;
+  myZFocus          = theOtherCamera->myZFocus;
+  myZFocusType      = theOtherCamera->myZFocusType;
+  myIOD             = theOtherCamera->myIOD;
+  myIODType         = theOtherCamera->myIODType;
+  myProjType        = theOtherCamera->myProjType;
+  myProjectionState = theOtherCamera->myProjectionState;
 
-  myProjectionState     = theOtherCamera->myProjectionState;
-
-  UpdateProjection();
+  InvalidateProjection();
 }
 
 // =======================================================================
@@ -106,14 +98,13 @@ void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOther
 // =======================================================================
 void Graphic3d_Camera::CopyOrientationData (const Handle(Graphic3d_Camera)& theOtherCamera)
 {
-  myUp             = theOtherCamera->myUp;
-  myEye            = theOtherCamera->myEye;
-  myCenter         = theOtherCamera->myCenter;
-  myAxialScale     = theOtherCamera->myAxialScale;
-
+  myUp               = theOtherCamera->myUp;
+  myEye              = theOtherCamera->myEye;
+  myCenter           = theOtherCamera->myCenter;
+  myAxialScale       = theOtherCamera->myAxialScale;
   myOrientationState = theOtherCamera->myOrientationState;
 
-  UpdateOrientation();
+  InvalidateOrientation();
 }
 
 // =======================================================================
@@ -122,10 +113,8 @@ void Graphic3d_Camera::CopyOrientationData (const Handle(Graphic3d_Camera)& theO
 // =======================================================================
 void Graphic3d_Camera::Copy (const Handle(Graphic3d_Camera)& theOther)
 {
-  BeginUpdate();
   CopyMappingData (theOther);
   CopyOrientationData (theOther);
-  EndUpdate();
 }
 
 // =======================================================================
@@ -135,7 +124,7 @@ void Graphic3d_Camera::Copy (const Handle(Graphic3d_Camera)& theOther)
 void Graphic3d_Camera::SetEye (const gp_Pnt& theEye)
 {
   myEye = theEye;
-  UpdateOrientation();
+  InvalidateOrientation();
 }
 
 // =======================================================================
@@ -145,7 +134,7 @@ void Graphic3d_Camera::SetEye (const gp_Pnt& theEye)
 void Graphic3d_Camera::SetCenter (const gp_Pnt& theCenter)
 {
   myCenter = theCenter;
-  UpdateOrientation();
+  InvalidateOrientation();
 }
 
 // =======================================================================
@@ -155,27 +144,17 @@ void Graphic3d_Camera::SetCenter (const gp_Pnt& theCenter)
 void Graphic3d_Camera::SetUp (const gp_Dir& theUp)
 {
   myUp = theUp;
-  UpdateOrientation();
-}
-
-// =======================================================================
-// function : SetProjectionShift
-// purpose  :
-// =======================================================================
-void Graphic3d_Camera::SetProjectionShift (const gp_Pnt& theProjShift)
-{
-  myProjectionShift = theProjShift;
-  UpdateProjection();
+  InvalidateOrientation();
 }
 
 // =======================================================================
 // function : SetAxialScale
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::SetAxialScale (const gp_Pnt& theAxialScale)
+void Graphic3d_Camera::SetAxialScale (const gp_XYZ& theAxialScale)
 {
   myAxialScale = theAxialScale;
-  UpdateOrientation();
+  InvalidateOrientation();
 }
 
 // =======================================================================
@@ -243,7 +222,7 @@ void Graphic3d_Camera::SetScale (const Standard_Real theScale)
       break;
   }
 
-  UpdateProjection();
+  InvalidateProjection();
 }
 
 // =======================================================================
@@ -262,7 +241,7 @@ Standard_Real Graphic3d_Camera::Scale() const
     // case Projection_MonoLeftEye  :
     // case Projection_MonoRightEye :
     default :
-      return Distance() * 2.0 * Tan(myFOVy * M_PI / 360.0);
+      return Distance() * 2.0 * Tan (myFOVy * M_PI / 360.0);
   }
 }
 
@@ -279,23 +258,21 @@ void Graphic3d_Camera::SetProjectionType (const Projection theProjectionType)
     return;
   }
 
-  myProjType = theProjectionType;
-
-  switch (myProjType)
+  if (anOldType == Projection_Orthographic)
   {
-    case Projection_Orthographic :
-    case Projection_Perspective  :
-    case Projection_MonoLeftEye  :
-    case Projection_MonoRightEye :
-      myLProjection.InitIdentity();
-      myRProjection.InitIdentity();
-      break;
-
-    default:
-      break;
+    if (myZNear <= RealEpsilon())
+    {
+      myZNear = DEFAULT_ZNEAR;
+    }
+    if (myZFar <= RealEpsilon())
+    {
+      myZFar = DEFAULT_ZFAR;
+    }
   }
 
-  UpdateProjection();
+  myProjType = theProjectionType;
+
+  InvalidateProjection();
 }
 
 // =======================================================================
@@ -305,58 +282,27 @@ void Graphic3d_Camera::SetProjectionType (const Projection theProjectionType)
 void Graphic3d_Camera::SetFOVy (const Standard_Real theFOVy)
 {
   myFOVy = theFOVy;
-  UpdateProjection();
+  InvalidateProjection();
 }
 
 // =======================================================================
-// function : SetZNear
+// function : SetZRange
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::SetZNear (const Standard_Real theZNear)
+void Graphic3d_Camera::SetZRange (const Standard_Real theZNear,
+                                  const Standard_Real theZFar)
 {
-  myZNear = theZNear;
-
-  // it is important to prevent too low ZNear values relatively to ZFar
-  // so we can not just pass Precision::Confusion() to it
-  const Standard_Real aTolerance  = 0.001;
-  const Standard_Real aMinimumZ   = myZFar * aTolerance;
-  const Standard_Real aMinimumGap = aTolerance;
-  // while it is possible to manually set up pretty small ZNear value,
-  // it may affect project / unproject operations dramatically
-  if (myZNear < aMinimumZ)
-  {
-    myZNear = aMinimumZ;
-  }
-
-  if (myZFar < (myZNear + aMinimumGap))
+  Standard_ASSERT_RAISE (theZFar > theZNear, "ZFar should be greater than ZNear");
+  if (!IsOrthographic())
   {
-    myZFar = myZNear + aMinimumGap;
+    Standard_ASSERT_RAISE (theZNear > 0.0, "Only positive Z-Near is allowed for perspective camera");
+    Standard_ASSERT_RAISE (theZFar  > 0.0, "Only positive Z-Far is allowed for perspective camera");
   }
 
-  UpdateProjection();
-}
-
-// =======================================================================
-// function : SetZFar
-// purpose  :
-// =======================================================================
-void Graphic3d_Camera::SetZFar (const Standard_Real theZFar)
-{
-  myZFar = theZFar;
-
-  // it is important to prevent too low ZNear values relatively to ZFar
-  // so we can not just pass Precision::Confusion() to it
-  const Standard_Real aTolerance  = 0.001;
-  const Standard_Real aMinimumGap = aTolerance;
-
-  // while it is possible to manually set up pretty small ZNear value,
-  // it may affect project / unproject operations dramatically
-  if (myZFar < (myZNear + aMinimumGap))
-  {
-    myZFar = myZNear + aMinimumGap;
-  }
+  myZNear = theZNear;
+  myZFar  = theZFar;
 
-  UpdateProjection();
+  InvalidateProjection();
 }
 
 // =======================================================================
@@ -366,7 +312,7 @@ void Graphic3d_Camera::SetZFar (const Standard_Real theZFar)
 void Graphic3d_Camera::SetAspect (const Standard_Real theAspect)
 {
   myAspect = theAspect;
-  UpdateProjection();
+  InvalidateProjection();
 }
 
 // =======================================================================
@@ -377,7 +323,7 @@ void Graphic3d_Camera::SetZFocus(const FocusType theType, const Standard_Real th
 {
   myZFocusType = theType;
   myZFocus = theZFocus;
-  UpdateProjection();
+  InvalidateProjection();
 }
 
 // =======================================================================
@@ -388,7 +334,7 @@ void Graphic3d_Camera::SetIOD (const IODType theType, const Standard_Real theIOD
 {
   myIODType = theType;
   myIOD = theIOD;
-  UpdateProjection();
+  InvalidateProjection();
 }
 
 // =======================================================================
@@ -397,34 +343,20 @@ void Graphic3d_Camera::SetIOD (const IODType theType, const Standard_Real theIOD
 // =======================================================================
 void Graphic3d_Camera::OrthogonalizeUp()
 {
-  gp_Dir aDir  = Direction();
-  gp_Dir aLeft = aDir.Crossed (Up());
-
-  // recompute up as: up = left x direction
-  SetUp (aLeft.Crossed (aDir));
-}
-
-// =======================================================================
-// function : BeginUpdate
-// purpose  :
-// =======================================================================
-void Graphic3d_Camera::BeginUpdate()
-{
-  myNbUpdateLocks++;
+  SetUp (OrthogonalizedUp());
 }
 
 // =======================================================================
-// function : EndUpdate
+// function : OrthogonalizedUp
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::EndUpdate()
+gp_Dir Graphic3d_Camera::OrthogonalizedUp() const
 {
-  if (myNbUpdateLocks > 0)
-    myNbUpdateLocks--;
+  gp_Dir aDir  = Direction();
+  gp_Dir aLeft = aDir.Crossed (Up());
 
-  // if number of locks > 0, the updates are bypassed
-  UpdateProjection();
-  UpdateOrientation();
+  // recompute up as: up = left x direction
+  return aLeft.Crossed (aDir);
 }
 
 // =======================================================================
@@ -436,17 +368,17 @@ void Graphic3d_Camera::Transform (const gp_Trsf& theTrsf)
   myUp.Transform (theTrsf);
   myEye.Transform (theTrsf);
   myCenter.Transform (theTrsf);
-  UpdateOrientation();
+  InvalidateOrientation();
 }
 
 // =======================================================================
 // function : safePointCast
 // purpose  :
 // =======================================================================
-static Graphic3d_Vec4 safePointCast (const gp_Pnt& thePnt)
+static Graphic3d_Vec4d safePointCast (const gp_Pnt& thePnt)
 {
   Standard_Real aLim = 1e15f;
-  
+
   // have to deal with values greater then max float
   gp_Pnt aSafePoint = thePnt;
   const Standard_Real aBigFloat = aLim * 0.1f;
@@ -458,9 +390,7 @@ static Graphic3d_Vec4 safePointCast (const gp_Pnt& thePnt)
     aSafePoint.SetZ (aSafePoint.Z() >= 0 ? aBigFloat : -aBigFloat);
 
   // convert point
-  Graphic3d_Vec4 aPnt (static_cast<Standard_ShortReal> (aSafePoint.X()),
-                       static_cast<Standard_ShortReal> (aSafePoint.Y()),
-                       static_cast<Standard_ShortReal> (aSafePoint.Z()), 1.0f);
+  Graphic3d_Vec4d aPnt (aSafePoint.X(), aSafePoint.Y(), aSafePoint.Z(), 1.0);
 
   return aPnt;
 }
@@ -471,11 +401,11 @@ static Graphic3d_Vec4 safePointCast (const gp_Pnt& thePnt)
 // =======================================================================
 gp_Pnt Graphic3d_Camera::Project (const gp_Pnt& thePnt) const
 {
-  const Graphic3d_Mat4& aViewMx = OrientationMatrix();
-  const Graphic3d_Mat4& aProjMx = ProjectionMatrix();
+  const Graphic3d_Mat4d& aViewMx = OrientationMatrix();
+  const Graphic3d_Mat4d& aProjMx = ProjectionMatrix();
 
   // use compatible type of point
-  Graphic3d_Vec4 aPnt = safePointCast (thePnt);
+  Graphic3d_Vec4d aPnt = safePointCast (thePnt);
 
   aPnt = aViewMx * aPnt; // convert to view coordinate space
   aPnt = aProjMx * aPnt; // convert to projection coordinate space
@@ -491,11 +421,11 @@ gp_Pnt Graphic3d_Camera::Project (const gp_Pnt& thePnt) const
 // =======================================================================
 gp_Pnt Graphic3d_Camera::UnProject (const gp_Pnt& thePnt) const
 {
-  const Graphic3d_Mat4& aViewMx = OrientationMatrix();
-  const Graphic3d_Mat4& aProjMx = ProjectionMatrix();
+  const Graphic3d_Mat4d& aViewMx = OrientationMatrix();
+  const Graphic3d_Mat4d& aProjMx = ProjectionMatrix();
 
-  Graphic3d_Mat4 aInvView;
-  Graphic3d_Mat4 aInvProj;
+  Graphic3d_Mat4d aInvView;
+  Graphic3d_Mat4d aInvProj;
 
   // this case should never happen
   if (!aViewMx.Inverted (aInvView) || !aProjMx.Inverted (aInvProj))
@@ -504,7 +434,7 @@ gp_Pnt Graphic3d_Camera::UnProject (const gp_Pnt& thePnt) const
   }
 
   // use compatible type of point
-  Graphic3d_Vec4 aPnt = safePointCast (thePnt);
+  Graphic3d_Vec4d aPnt = safePointCast (thePnt);
 
   aPnt = aInvProj * aPnt; // convert to view coordinate space
   aPnt = aInvView * aPnt; // convert to world coordinate space
@@ -520,10 +450,10 @@ gp_Pnt Graphic3d_Camera::UnProject (const gp_Pnt& thePnt) const
 // =======================================================================
 gp_Pnt Graphic3d_Camera::ConvertView2Proj (const gp_Pnt& thePnt) const
 {
-  const Graphic3d_Mat4& aProjMx = ProjectionMatrix();
+  const Graphic3d_Mat4d& aProjMx = ProjectionMatrix();
 
   // use compatible type of point
-  Graphic3d_Vec4 aPnt = safePointCast (thePnt);
+  Graphic3d_Vec4d aPnt = safePointCast (thePnt);
 
   aPnt = aProjMx * aPnt; // convert to projection coordinate space
 
@@ -538,18 +468,18 @@ gp_Pnt Graphic3d_Camera::ConvertView2Proj (const gp_Pnt& thePnt) const
 // =======================================================================
 gp_Pnt Graphic3d_Camera::ConvertProj2View (const gp_Pnt& thePnt) const
 {
-  const Graphic3d_Mat4& aProjMx = ProjectionMatrix();
+  const Graphic3d_Mat4d& aProjMx = ProjectionMatrix();
 
-  Graphic3d_Mat4 aInvProj;
+  Graphic3d_Mat4d aInvProj;
 
   // this case should never happen, but...
   if (!aProjMx.Inverted (aInvProj))
   {
-    return gp_Pnt(0, 0, 0);
+    return gp_Pnt (0, 0, 0);
   }
 
   // use compatible type of point
-  Graphic3d_Vec4 aPnt = safePointCast (thePnt);
+  Graphic3d_Vec4d aPnt = safePointCast (thePnt);
 
   aPnt = aInvProj * aPnt; // convert to view coordinate space
 
@@ -564,10 +494,10 @@ gp_Pnt Graphic3d_Camera::ConvertProj2View (const gp_Pnt& thePnt) const
 // =======================================================================
 gp_Pnt Graphic3d_Camera::ConvertWorld2View (const gp_Pnt& thePnt) const
 {
-  const Graphic3d_Mat4& aViewMx = OrientationMatrix();
+  const Graphic3d_Mat4d& aViewMx = OrientationMatrix();
 
   // use compatible type of point
-  Graphic3d_Vec4 aPnt = safePointCast (thePnt);
+  Graphic3d_Vec4d aPnt = safePointCast (thePnt);
 
   aPnt = aViewMx * aPnt; // convert to view coordinate space
 
@@ -582,9 +512,9 @@ gp_Pnt Graphic3d_Camera::ConvertWorld2View (const gp_Pnt& thePnt) const
 // =======================================================================
 gp_Pnt Graphic3d_Camera::ConvertView2World (const gp_Pnt& thePnt) const
 {
-  const Graphic3d_Mat4& aViewMx = OrientationMatrix();
+  const Graphic3d_Mat4d& aViewMx = OrientationMatrix();
 
-  Graphic3d_Mat4 aInvView;
+  Graphic3d_Mat4d aInvView;
 
   if (!aViewMx.Inverted (aInvView))
   {
@@ -592,7 +522,7 @@ gp_Pnt Graphic3d_Camera::ConvertView2World (const gp_Pnt& thePnt) const
   }
 
   // use compatible type of point
-  Graphic3d_Vec4 aPnt = safePointCast (thePnt);
+  Graphic3d_Vec4d aPnt = safePointCast (thePnt);
 
   aPnt = aInvView * aPnt; // convert to world coordinate space
 
@@ -605,275 +535,392 @@ gp_Pnt Graphic3d_Camera::ConvertView2World (const gp_Pnt& thePnt) const
 // function : ViewDimensions
 // purpose  :
 // =======================================================================
-gp_Pnt Graphic3d_Camera::ViewDimensions () const
+gp_XYZ Graphic3d_Camera::ViewDimensions() const
 {
   // view plane dimensions
   Standard_Real aSizeY = IsOrthographic() ? myScale : (2.0 * Distance() * Tan (DTR_HALF * myFOVy));
   Standard_Real aSizeX = myAspect * aSizeY;
 
   // and frustum depth
-  return gp_Pnt (aSizeX, aSizeY, myZFar - myZNear);
+  return gp_XYZ (aSizeX, aSizeY, myZFar - myZNear);
 }
 
 // =======================================================================
-// function : WindowLimit
+// function : Frustum
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::WindowLimit (Standard_Real& theUMin,
-                                    Standard_Real& theVMin,
-                                    Standard_Real& theUMax,
-                                    Standard_Real& theVMax) const
+void Graphic3d_Camera::Frustum (gp_Pln& theLeft,
+                                gp_Pln& theRight,
+                                gp_Pln& theBottom,
+                                gp_Pln& theTop,
+                                gp_Pln& theNear,
+                                gp_Pln& theFar) const
 {
-  gp_Pnt aViewDims = ViewDimensions();
-  gp_Pnt aShift    = ProjectionShift();
-  theUMin = -aViewDims.X() * 0.5 - aShift.X();
-  theVMin = -aViewDims.Y() * 0.5 - aShift.Y();
-  theUMax = aViewDims.X() * 0.5 - aShift.X();
-  theVMax = aViewDims.Y() * 0.5 - aShift.Y();
+  gp_Vec aProjection = gp_Vec (Direction());
+  gp_Vec anUp        = OrthogonalizedUp();
+  gp_Vec aSide       = aProjection ^ anUp;
+
+  Standard_ASSERT_RAISE (
+    !aProjection.IsParallel (anUp, Precision::Angular()),
+     "Can not derive SIDE = PROJ x UP - directions are parallel");
+
+  theNear = gp_Pln (Eye().Translated (aProjection * ZNear()), aProjection);
+  theFar  = gp_Pln (Eye().Translated (aProjection * ZFar()), -aProjection);
+
+  Standard_Real aHScaleHor = Scale() * 0.5 * Aspect();
+  Standard_Real aHScaleVer = Scale() * 0.5;
+
+  gp_Pnt aPntLeft   = Center().Translated (aHScaleHor * -aSide);
+  gp_Pnt aPntRight  = Center().Translated (aHScaleHor *  aSide);
+  gp_Pnt aPntBottom = Center().Translated (aHScaleVer * -anUp);
+  gp_Pnt aPntTop    = Center().Translated (aHScaleVer *  anUp);
+
+  gp_Vec aDirLeft   =  aSide;
+  gp_Vec aDirRight  = -aSide;
+  gp_Vec aDirBottom =  anUp;
+  gp_Vec aDirTop    = -anUp;
+  if (!IsOrthographic())
+  {
+    Standard_Real aHFOVHor = ATan (Tan (DTR_HALF * FOVy()) * Aspect());
+    Standard_Real aHFOVVer = DTR_HALF * FOVy();
+    aDirLeft.Rotate   (gp_Ax1 (gp::Origin(), anUp),   aHFOVHor);
+    aDirRight.Rotate  (gp_Ax1 (gp::Origin(), anUp),  -aHFOVHor);
+    aDirBottom.Rotate (gp_Ax1 (gp::Origin(), aSide), -aHFOVVer);
+    aDirTop.Rotate    (gp_Ax1 (gp::Origin(), aSide),  aHFOVVer);
+  }
+
+  theLeft   = gp_Pln (aPntLeft,   aDirLeft);
+  theRight  = gp_Pln (aPntRight,  aDirRight);
+  theBottom = gp_Pln (aPntBottom, aDirBottom);
+  theTop    = gp_Pln (aPntTop,    aDirTop);
+}
+
+// =======================================================================
+// function : OrientationMatrix
+// purpose  :
+// =======================================================================
+const Graphic3d_Mat4d& Graphic3d_Camera::OrientationMatrix() const
+{
+  return *UpdateOrientation (myMatricesD).Orientation;
+}
+
+// =======================================================================
+// function : OrientationMatrixF
+// purpose  :
+// =======================================================================
+const Graphic3d_Mat4& Graphic3d_Camera::OrientationMatrixF() const
+{
+  return *UpdateOrientation (myMatricesF).Orientation;
+}
+
+// =======================================================================
+// function : ProjectionMatrix
+// purpose  :
+// =======================================================================
+const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionMatrix() const
+{
+  return *UpdateProjection (myMatricesD).MProjection;
+}
+
+// =======================================================================
+// function : ProjectionMatrixF
+// purpose  :
+// =======================================================================
+const Graphic3d_Mat4& Graphic3d_Camera::ProjectionMatrixF() const
+{
+  return *UpdateProjection (myMatricesF).MProjection;
+}
+
+// =======================================================================
+// function : ProjectionStereoLeft
+// purpose  :
+// =======================================================================
+const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionStereoLeft() const
+{
+  return *UpdateProjection (myMatricesD).LProjection;
+}
+
+// =======================================================================
+// function : ProjectionStereoLeftF
+// purpose  :
+// =======================================================================
+const Graphic3d_Mat4& Graphic3d_Camera::ProjectionStereoLeftF() const
+{
+  return *UpdateProjection (myMatricesF).LProjection;
+}
+
+// =======================================================================
+// function : ProjectionStereoRight
+// purpose  :
+// =======================================================================
+const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionStereoRight() const
+{
+  return *UpdateProjection (myMatricesD).RProjection;
+}
+
+// =======================================================================
+// function : ProjectionStereoRightF
+// purpose  :
+// =======================================================================
+const Graphic3d_Mat4& Graphic3d_Camera::ProjectionStereoRightF() const
+{
+  return *UpdateProjection (myMatricesF).RProjection;
 }
 
 // =======================================================================
 // function : UpdateProjection
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::UpdateProjection()
+template <typename Elem_t>
+Graphic3d_Camera::TransformMatrices<Elem_t>&
+  Graphic3d_Camera::UpdateProjection (TransformMatrices<Elem_t>& theMatrices) const
 {
-  if (myNbUpdateLocks > 0)
+  if (theMatrices.IsProjectionValid())
   {
-    return;
+    return theMatrices; // for inline accessors
   }
 
-  myProjectionState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
+  theMatrices.InitProjection();
 
   // sets top of frustum based on FOVy and near clipping plane
-  Standard_Real aDYHalf;
+  Elem_t aScale   = static_cast<Elem_t> (myScale);
+  Elem_t aZNear   = static_cast<Elem_t> (myZNear);
+  Elem_t aZFar    = static_cast<Elem_t> (myZFar);
+  Elem_t anAspect = static_cast<Elem_t> (myAspect);
+  Elem_t aDYHalf = 0.0;
   if (IsOrthographic())
   {
-     aDYHalf = myScale * 0.5;
+    aDYHalf = aScale * Elem_t (0.5);
   }
   else
   {
-    aDYHalf = myZNear * Tan (DTR_HALF * myFOVy);
+    aDYHalf = aZNear * Elem_t (Tan (DTR_HALF * myFOVy));
   }
 
   // sets right of frustum based on aspect ratio
-  Standard_Real aDXHalf = myAspect * aDYHalf;
+  Elem_t aDXHalf = anAspect * aDYHalf;
+  Elem_t aLeft   = -aDXHalf;
+  Elem_t aRight  =  aDXHalf;
+  Elem_t aBot    = -aDYHalf;
+  Elem_t aTop    =  aDYHalf;
 
-  Standard_ShortReal aLeft      = (Standard_ShortReal) -aDXHalf;
-  Standard_ShortReal aRight     = (Standard_ShortReal)  aDXHalf;
-  Standard_ShortReal aBot       = (Standard_ShortReal) -aDYHalf;
-  Standard_ShortReal aTop       = (Standard_ShortReal)  aDYHalf;
-  Standard_ShortReal aNear      = (Standard_ShortReal)  myZNear;
-  Standard_ShortReal aFar       = (Standard_ShortReal)  myZFar;
-  Standard_ShortReal aShiftX    = (Standard_ShortReal)  myProjectionShift.X();
-  Standard_ShortReal aShiftY    = (Standard_ShortReal)  myProjectionShift.Y();
+  Elem_t aIOD  = myIODType == IODType_Relative 
+    ? static_cast<Elem_t> (myIOD * Distance())
+    : static_cast<Elem_t> (myIOD);
 
-  Standard_ShortReal aIOD = (myIODType == IODType_Relative)
-        ? (Standard_ShortReal)(myIOD * Distance())
-        : (Standard_ShortReal)(myIOD);
-
-  Standard_ShortReal aFocus = (myZFocusType == FocusType_Relative)
-        ? (Standard_ShortReal)(myZFocus * Distance())
-        : (Standard_ShortReal)(myZFocus);
+  Elem_t aFocus = myZFocusType == FocusType_Relative 
+    ? static_cast<Elem_t> (myZFocus * Distance())
+    : static_cast<Elem_t> (myZFocus);
 
   switch (myProjType)
   {
     case Projection_Orthographic :
-      OrthoProj (aLeft, aRight, aBot, aTop, aNear, aFar, aShiftX, aShiftY, myMProjection);
+      OrthoProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, *theMatrices.MProjection);
       break;
 
     case Projection_Perspective :
-      PerspectiveProj (aLeft, aRight, aBot, aTop, aNear, aFar, aShiftX, aShiftY, myMProjection);
+      PerspectiveProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, *theMatrices.MProjection);
       break;
 
     case Projection_MonoLeftEye :
     {
-      StereoEyeProj (aLeft, aRight, aBot, aTop, aNear,
-                     aFar, aIOD, aFocus, aShiftX, aShiftY,
-                     Standard_True, myMProjection);
+      StereoEyeProj (aLeft, aRight, aBot, aTop,
+                     aZNear, aZFar, aIOD, aFocus,
+                     Standard_True, *theMatrices.MProjection);
       break;
     }
 
     case Projection_MonoRightEye :
     {
-      StereoEyeProj (aLeft, aRight, aBot, aTop, aNear,
-                     aFar, aIOD, aFocus, aShiftX, aShiftY,
-                     Standard_False, myMProjection);
+      StereoEyeProj (aLeft, aRight, aBot, aTop,
+                     aZNear, aZFar, aIOD, aFocus,
+                     Standard_False, *theMatrices.MProjection);
       break;
     }
 
     case Projection_Stereo :
     {
-      PerspectiveProj (aLeft, aRight, aBot, aTop, aNear, aFar, aShiftX, aShiftY, myMProjection);
+      PerspectiveProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, *theMatrices.MProjection);
 
-      StereoEyeProj (aLeft, aRight, aBot, aTop, aNear,
-                     aFar, aIOD, aFocus, aShiftX, aShiftY,
-                     Standard_True, myLProjection);
+      StereoEyeProj (aLeft, aRight, aBot, aTop,
+                     aZNear, aZFar, aIOD, aFocus,
+                     Standard_True,
+                     *theMatrices.LProjection);
 
-      StereoEyeProj (aLeft, aRight, aBot, aTop, aNear,
-                     aFar, aIOD, aFocus, aShiftX, aShiftY,
-                     Standard_False, myRProjection);
+      StereoEyeProj (aLeft, aRight, aBot, aTop,
+                     aZNear, aZFar, aIOD, aFocus,
+                     Standard_False,
+                     *theMatrices.RProjection);
       break;
     }
   }
+
+  return theMatrices; // for inline accessors
 }
 
 // =======================================================================
 // function : UpdateOrientation
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::UpdateOrientation()
+template <typename Elem_t>
+Graphic3d_Camera::TransformMatrices<Elem_t>&
+  Graphic3d_Camera::UpdateOrientation (TransformMatrices<Elem_t>& theMatrices) const
 {
-  if (myNbUpdateLocks > 0)
+  if (theMatrices.IsOrientationValid())
   {
-    return;
+    return theMatrices; // for inline accessors
   }
 
-  myOrientationState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
+  theMatrices.InitOrientation();
+
+  NCollection_Vec3<Elem_t> anEye (static_cast<Elem_t> (myEye.X()),
+                                  static_cast<Elem_t> (myEye.Y()),
+                                  static_cast<Elem_t> (myEye.Z()));
+
+  NCollection_Vec3<Elem_t> aCenter (static_cast<Elem_t> (myCenter.X()),
+                                    static_cast<Elem_t> (myCenter.Y()),
+                                    static_cast<Elem_t> (myCenter.Z()));
 
-  Graphic3d_Vec3 anEye ((Standard_ShortReal) myEye.X(),
-                        (Standard_ShortReal) myEye.Y(),
-                        (Standard_ShortReal) myEye.Z());
+  NCollection_Vec3<Elem_t> anUp (static_cast<Elem_t> (myUp.X()),
+                                 static_cast<Elem_t> (myUp.Y()),
+                                 static_cast<Elem_t> (myUp.Z()));
 
-  Graphic3d_Vec3 aCenter ((Standard_ShortReal) myCenter.X(),
-                          (Standard_ShortReal) myCenter.Y(),
-                          (Standard_ShortReal) myCenter.Z());
+  NCollection_Vec3<Elem_t> anAxialScale (static_cast<Elem_t> (myAxialScale.X()),
+                                         static_cast<Elem_t> (myAxialScale.Y()),
+                                         static_cast<Elem_t> (myAxialScale.Z()));
 
-  Graphic3d_Vec3 anUp ((Standard_ShortReal) myUp.X(),
-                       (Standard_ShortReal) myUp.Y(),
-                       (Standard_ShortReal) myUp.Z());
+  LookOrientation (anEye, aCenter, anUp, anAxialScale, *theMatrices.Orientation);
 
-  Graphic3d_Vec3 anAxialScale ((Standard_ShortReal) myAxialScale.X(),
-                               (Standard_ShortReal) myAxialScale.Y(),
-                               (Standard_ShortReal) myAxialScale.Z());  
+  return theMatrices; // for inline accessors
+}
 
-  LookOrientation (anEye, aCenter, anUp, anAxialScale, myOrientation);
+// =======================================================================
+// function : InvalidateProjection
+// purpose  :
+// =======================================================================
+void Graphic3d_Camera::InvalidateProjection()
+{
+  myMatricesD.ResetProjection();
+  myMatricesF.ResetProjection();
+  myProjectionState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
+}
 
-  // Update orthogonalized Up vector
-  myUp = gp_Dir (anUp.x(), anUp.y(), anUp.z());
+// =======================================================================
+// function : InvalidateOrientation
+// purpose  :
+// =======================================================================
+void Graphic3d_Camera::InvalidateOrientation()
+{
+  myMatricesD.ResetOrientation();
+  myMatricesF.ResetOrientation();
+  myOrientationState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
 }
 
 // =======================================================================
 // function : OrthoProj
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::OrthoProj (const Standard_ShortReal theLeft,
-                                  const Standard_ShortReal theRight,
-                                  const Standard_ShortReal theBottom,
-                                  const Standard_ShortReal theTop,
-                                  const Standard_ShortReal theNear,
-                                  const Standard_ShortReal theFar,
-                                  const Standard_ShortReal theShiftX,
-                                  const Standard_ShortReal theShiftY,
-                                  Graphic3d_Mat4& theOutMx)
+template <typename Elem_t>
+void Graphic3d_Camera::OrthoProj (const Elem_t theLeft,
+                                  const Elem_t theRight,
+                                  const Elem_t theBottom,
+                                  const Elem_t theTop,
+                                  const Elem_t theNear,
+                                  const Elem_t theFar,
+                                  NCollection_Mat4<Elem_t>& theOutMx)
 {
   // row 0
-  theOutMx.ChangeValue (0, 0) = 2.0f / (theRight - theLeft);
-  theOutMx.ChangeValue (0, 1) = 0.0f;
-  theOutMx.ChangeValue (0, 2) = 0.0f;
+  theOutMx.ChangeValue (0, 0) = Elem_t (2.0) / (theRight - theLeft);
+  theOutMx.ChangeValue (0, 1) = Elem_t (0.0);
+  theOutMx.ChangeValue (0, 2) = Elem_t (0.0);
   theOutMx.ChangeValue (0, 3) = - (theRight + theLeft) / (theRight - theLeft);
 
   // row 1
-  theOutMx.ChangeValue (1, 0) = 0.0f;
-  theOutMx.ChangeValue (1, 1) = 2.0f / (theTop - theBottom);
-  theOutMx.ChangeValue (1, 2) = 0.0f;
+  theOutMx.ChangeValue (1, 0) = Elem_t (0.0);
+  theOutMx.ChangeValue (1, 1) = Elem_t (2.0) / (theTop - theBottom);
+  theOutMx.ChangeValue (1, 2) = Elem_t (0.0);
   theOutMx.ChangeValue (1, 3) = - (theTop + theBottom) / (theTop - theBottom);
 
   // row 2
-  theOutMx.ChangeValue (2, 0) = 0.0f;
-  theOutMx.ChangeValue (2, 1) = 0.0f;
-  theOutMx.ChangeValue (2, 2) = -2.0f / (theFar - theNear);
+  theOutMx.ChangeValue (2, 0) = Elem_t (0.0);
+  theOutMx.ChangeValue (2, 1) = Elem_t (0.0);
+  theOutMx.ChangeValue (2, 2) = Elem_t (-2.0) / (theFar - theNear);
   theOutMx.ChangeValue (2, 3) = - (theFar + theNear) / (theFar - theNear);
 
   // row 3
-  theOutMx.ChangeValue (3, 0) = 0.0f;
-  theOutMx.ChangeValue (3, 1) = 0.0f;
-  theOutMx.ChangeValue (3, 2) = 0.0f;
-  theOutMx.ChangeValue (3, 3) = 1.0f;
-
-  Graphic3d_Mat4 aViewportShift;
-  aViewportShift.ChangeValue (0, 3) = theShiftX;
-  aViewportShift.ChangeValue (1, 3) = theShiftY;
-
-  theOutMx.Multiply (aViewportShift);
+  theOutMx.ChangeValue (3, 0) = Elem_t (0.0);
+  theOutMx.ChangeValue (3, 1) = Elem_t (0.0);
+  theOutMx.ChangeValue (3, 2) = Elem_t (0.0);
+  theOutMx.ChangeValue (3, 3) = Elem_t (1.0);
 }
 
 // =======================================================================
 // function : PerspectiveProj
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::PerspectiveProj (const Standard_ShortReal theLeft,
-                                        const Standard_ShortReal theRight,
-                                        const Standard_ShortReal theBottom,
-                                        const Standard_ShortReal theTop,
-                                        const Standard_ShortReal theNear,
-                                        const Standard_ShortReal theFar,
-                                        const Standard_ShortReal theShiftX,
-                                        const Standard_ShortReal theShiftY,
-                                        Graphic3d_Mat4& theOutMx)
+template <typename Elem_t>
+void Graphic3d_Camera::PerspectiveProj (const Elem_t theLeft,
+                                        const Elem_t theRight,
+                                        const Elem_t theBottom,
+                                        const Elem_t theTop,
+                                        const Elem_t theNear,
+                                        const Elem_t theFar,
+                                        NCollection_Mat4<Elem_t>& theOutMx)
 {
   // column 0
-  theOutMx.ChangeValue (0, 0) = (2.0f * theNear) / (theRight - theLeft);
-  theOutMx.ChangeValue (1, 0) = 0.0f;
-  theOutMx.ChangeValue (2, 0) = 0.0f;
-  theOutMx.ChangeValue (3, 0) = 0.0f;
+  theOutMx.ChangeValue (0, 0) = (Elem_t (2.0) * theNear) / (theRight - theLeft);
+  theOutMx.ChangeValue (1, 0) = Elem_t (0.0);
+  theOutMx.ChangeValue (2, 0) = Elem_t (0.0);
+  theOutMx.ChangeValue (3, 0) = Elem_t (0.0);
 
   // column 1
-  theOutMx.ChangeValue (0, 1) = 0.0f;
-  theOutMx.ChangeValue (1, 1) = (2.0f * theNear) / (theTop - theBottom);
-  theOutMx.ChangeValue (2, 1) = 0.0f;
-  theOutMx.ChangeValue (3, 1) = 0.0f;
+  theOutMx.ChangeValue (0, 1) = Elem_t (0.0);
+  theOutMx.ChangeValue (1, 1) = (Elem_t (2.0) * theNear) / (theTop - theBottom);
+  theOutMx.ChangeValue (2, 1) = Elem_t (0.0);
+  theOutMx.ChangeValue (3, 1) = Elem_t (0.0);
 
   // column 2
   theOutMx.ChangeValue (0, 2) = (theRight + theLeft) / (theRight - theLeft);
   theOutMx.ChangeValue (1, 2) = (theTop + theBottom) / (theTop - theBottom);
   theOutMx.ChangeValue (2, 2) = -(theFar + theNear) / (theFar - theNear);
-  theOutMx.ChangeValue (3, 2) = -1.0f;
+  theOutMx.ChangeValue (3, 2) = Elem_t (-1.0);
 
   // column 3
-  theOutMx.ChangeValue (0, 3) = 0.0f;
-  theOutMx.ChangeValue (1, 3) = 0.0f;
-  theOutMx.ChangeValue (2, 3) = -(2.0f * theFar * theNear) / (theFar - theNear);
-  theOutMx.ChangeValue (3, 3) = 0.0f;
-
-  Graphic3d_Mat4 aViewportShift;
-  aViewportShift.ChangeValue (0, 3) = theShiftX;
-  aViewportShift.ChangeValue (1, 3) = theShiftY;
-
-  theOutMx.Multiply (aViewportShift);
+  theOutMx.ChangeValue (0, 3) = Elem_t (0.0);
+  theOutMx.ChangeValue (1, 3) = Elem_t (0.0);
+  theOutMx.ChangeValue (2, 3) = -(Elem_t (2.0) * theFar * theNear) / (theFar - theNear);
+  theOutMx.ChangeValue (3, 3) = Elem_t (0.0);
 }
 
 // =======================================================================
 // function : StereoEyeProj
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::StereoEyeProj (const Standard_ShortReal theLeft,
-                                      const Standard_ShortReal theRight,
-                                      const Standard_ShortReal theBottom,
-                                      const Standard_ShortReal theTop,
-                                      const Standard_ShortReal theNear,
-                                      const Standard_ShortReal theFar,
-                                      const Standard_ShortReal theIOD,
-                                      const Standard_ShortReal theZFocus,
-                                      const Standard_ShortReal theShiftX,
-                                      const Standard_ShortReal theShiftY,
-                                      const Standard_Boolean   theIsLeft,
-                                      Graphic3d_Mat4& theOutMx)
+template <typename Elem_t>
+void Graphic3d_Camera::StereoEyeProj (const Elem_t theLeft,
+                                      const Elem_t theRight,
+                                      const Elem_t theBottom,
+                                      const Elem_t theTop,
+                                      const Elem_t theNear,
+                                      const Elem_t theFar,
+                                      const Elem_t theIOD,
+                                      const Elem_t theZFocus,
+                                      const Standard_Boolean theIsLeft,
+                                      NCollection_Mat4<Elem_t>& theOutMx)
 {
-  Standard_ShortReal aDx = theIsLeft ? ( 0.5f * theIOD) : (-0.5f * theIOD);
-  Standard_ShortReal aDXStereoShift = aDx * theNear / theZFocus;
+  Elem_t aDx = theIsLeft ? Elem_t (0.5) * theIOD : Elem_t (-0.5) * theIOD;
+  Elem_t aDXStereoShift = aDx * theNear / theZFocus;
 
   // construct eye projection matrix
   PerspectiveProj (theLeft  + aDXStereoShift,
                    theRight + aDXStereoShift,
                    theBottom, theTop, theNear, theFar,
-                   theShiftX, theShiftY,
                    theOutMx);
 
-  if (theIOD != 0.0f)
+  if (theIOD != Elem_t (0.0))
   {
     // X translation to cancel parallax
-    theOutMx.Translate (Graphic3d_Vec3 (aDx, 0.0f, 0.0f));
+    theOutMx.Translate (NCollection_Vec3<Elem_t> (aDx, Elem_t (0.0), Elem_t (0.0)));
   }
 }
 
@@ -881,34 +928,33 @@ void Graphic3d_Camera::StereoEyeProj (const Standard_ShortReal theLeft,
 // function : LookOrientation
 // purpose  :
 // =======================================================================
-void Graphic3d_Camera::LookOrientation (const Graphic3d_Vec3& theEye,
-                                        const Graphic3d_Vec3& theLookAt,
-                                        Graphic3d_Vec3& theUpDir,
-                                        const Graphic3d_Vec3& theAxialScale,
-                                        Graphic3d_Mat4& theOutMx)
+template <typename Elem_t>
+void Graphic3d_Camera::LookOrientation (const NCollection_Vec3<Elem_t>& theEye,
+                                        const NCollection_Vec3<Elem_t>& theLookAt,
+                                        const NCollection_Vec3<Elem_t>& theUpDir,
+                                        const NCollection_Vec3<Elem_t>& theAxialScale,
+                                        NCollection_Mat4<Elem_t>& theOutMx)
 {
-  Graphic3d_Vec3 aForward = theLookAt - theEye;
+  NCollection_Vec3<Elem_t> aForward = theLookAt - theEye;
   aForward.Normalize();
 
   // side = forward x up
-  Graphic3d_Vec3 aSide = Graphic3d_Vec3::Cross (aForward, theUpDir);
+  NCollection_Vec3<Elem_t> aSide = NCollection_Vec3<Elem_t>::Cross (aForward, theUpDir);
   aSide.Normalize();
 
   // recompute up as: up = side x forward
-  Graphic3d_Vec3 anUp = Graphic3d_Vec3::Cross (aSide, aForward);
-  theUpDir = anUp;
+  NCollection_Vec3<Elem_t> anUp = NCollection_Vec3<Elem_t>::Cross (aSide, aForward);
 
-  Graphic3d_Mat4 aLookMx;
+  NCollection_Mat4<Elem_t> aLookMx;
   aLookMx.SetRow (0, aSide);
   aLookMx.SetRow (1, anUp);
   aLookMx.SetRow (2, -aForward);
 
-  theOutMx.InitIdentity(); 
-  theOutMx.Multiply (aLookMx); 
-
+  theOutMx.InitIdentity();
+  theOutMx.Multiply (aLookMx);
   theOutMx.Translate (-theEye);
 
-  Graphic3d_Mat4 anAxialScaleMx;
+  NCollection_Mat4<Elem_t> anAxialScaleMx;
   anAxialScaleMx.ChangeValue (0, 0) = theAxialScale.x();
   anAxialScaleMx.ChangeValue (1, 1) = theAxialScale.y();
   anAxialScaleMx.ChangeValue (2, 2) = theAxialScale.z();
index 69740cc..2c14fba 100644 (file)
 #ifndef _Graphic3d_Camera_HeaderFile
 #define _Graphic3d_Camera_HeaderFile
 
+#include <Graphic3d_Mat4d.hxx>
 #include <Graphic3d_Mat4.hxx>
 #include <Graphic3d_Vec3.hxx>
 
+#include <NCollection_Handle.hxx>
+
 #include <gp_Dir.hxx>
 #include <gp_Pnt.hxx>
 
@@ -31,6 +34,53 @@ DEFINE_STANDARD_HANDLE (Graphic3d_Camera, Standard_Transient)
 //! and orientation properties of 3D view.
 class Graphic3d_Camera : public Standard_Transient
 {
+private:
+
+  //! Template container for cached matrices or Real/ShortReal types.
+  template<typename Elem_t>
+  struct TransformMatrices
+  {
+    void InitOrientation()
+    {
+      Orientation = new NCollection_Mat4<Elem_t>();
+    }
+
+    void InitProjection()
+    {
+      MProjection = new NCollection_Mat4<Elem_t>();
+      LProjection = new NCollection_Mat4<Elem_t>();
+      RProjection = new NCollection_Mat4<Elem_t>();
+    }
+
+    void ResetOrientation()
+    {
+      Orientation.Nullify();
+    }
+
+    void ResetProjection()
+    {
+      MProjection.Nullify();
+      LProjection.Nullify();
+      RProjection.Nullify();
+    }
+
+    Standard_Boolean IsOrientationValid()
+    {
+      return !Orientation.IsNull();
+    }
+
+    Standard_Boolean IsProjectionValid()
+    {
+      return !MProjection.IsNull() &&
+             !LProjection.IsNull() &&
+             !RProjection.IsNull();
+    }
+
+    NCollection_Handle< NCollection_Mat4<Elem_t> > Orientation;
+    NCollection_Handle< NCollection_Mat4<Elem_t> > MProjection;
+    NCollection_Handle< NCollection_Mat4<Elem_t> > LProjection;
+    NCollection_Handle< NCollection_Mat4<Elem_t> > RProjection;
+  };
 
 public:
 
@@ -75,7 +125,7 @@ public:
   //! Initializes camera with the following properties:
   //! Eye (0, 0, -2); Center (0, 0, 0); Up (0, 1, 0);
   //! Type (Orthographic); FOVy (45); Scale (1000); IsStereo(false);
-  //! ZNear (0.1); ZFar (100); Aspect(1);
+  //! ZNear (0.001); ZFar (3000.0); Aspect(1);
   //! ZFocus(1.0); ZFocusType(Relative); IOD(0.05); IODType(Relative)
   Standard_EXPORT Graphic3d_Camera();
 
@@ -93,17 +143,8 @@ public:
   //! @param theOther [in] the camera to copy from.
   Standard_EXPORT void Copy (const Handle(Graphic3d_Camera)& theOther);
 
-  //! Returns modification state of camera projection matrix
-  Standard_Size ProjectionState() const
-  {
-    return myProjectionState;
-  }
-
-  //! Returns modification state of camera model-view matrix
-  Standard_Size ModelViewState() const
-  {
-    return myOrientationState;
-  }
+//! @name Public camera properties
+public:
 
   //! Sets camera Eye position.
   //! @param theEye [in] the location of camera's Eye.
@@ -127,10 +168,16 @@ public:
     return myCenter;
   }
 
-  //! Sets camera Up direction vector.
+  //! Sets camera Up direction vector, orthogonal to camera direction.
   //! @param theUp [in] the Up direction vector.
   Standard_EXPORT void SetUp (const gp_Dir& theUp);
 
+  //! Orthogonalize up direction vector.
+  Standard_EXPORT void OrthogonalizeUp();
+
+  //! Return a copy of orthogonalized up direction vector.
+  Standard_EXPORT gp_Dir OrthogonalizedUp() const;
+
   //! Get camera Up direction vector.
   //! @return Camera's Up direction vector.
   const gp_Dir& Up() const
@@ -138,26 +185,13 @@ public:
     return myUp;
   }
 
-  //! Set camera projection shift vector.<br>
-  //! Used for compatibility with older view mechanics. Applied after
-  //! view transform and before projection step (P * Shift * V).
-  //! @param theProjShift [in] the projection shift vector.
-  Standard_EXPORT void SetProjectionShift (const gp_Pnt& theProjShift);
-
-  //! Get camera projection shift vector.
-  //! @return Camera's projection shift vector.
-  const gp_Pnt& ProjectionShift() const
-  {
-    return myProjectionShift;
-  }
-
   //! Set camera axial scale.<br>
   //! @param theAxialScale [in] the axial scale vector.
-  Standard_EXPORT void SetAxialScale (const gp_Pnt& theAxialScale);
+  Standard_EXPORT void SetAxialScale (const gp_XYZ& theAxialScale);
 
   //! Get camera axial scale.
   //! @return Camera's axial scale.
-  const gp_Pnt& AxialScale() const
+  const gp_XYZ& AxialScale() const
   {
     return myAxialScale;
   }
@@ -190,9 +224,9 @@ public:
   Standard_EXPORT Standard_Real Scale() const;
 
   //! Change camera projection type.
-  //! While switching between perspective and ortho projection types
-  //! ZNear and ZFar value conversion is performed due to different 
-  //! coordinate systems (made for compatibility, to be improved..)
+  //! When switching to perspective projection from orthographic one,
+  //! the ZNear and ZFar are reset to default values (0.001, 3000.0)
+  //! if less than 0.0.
   //! @param theProjectionType [in] the camera projection type.
   Standard_EXPORT void SetProjectionType (const Projection theProjection);
 
@@ -231,9 +265,14 @@ public:
     return myFOVy;
   }
 
-  //! Change the Near Z-clipping plane position.
+  //! Change the Near and Far Z-clipping plane positions.
+  //! For orthographic projection, theZNear, theZFar can be negative or positive.
+  //! For perspective projection, only positive values are allowed.
+  //! Program error exception is raised if non-positive values are
+  //! specified for perspective projection or theZNear >= theZFar.
   //! @param theZNear [in] the distance of the plane from the Eye.
-  Standard_EXPORT void SetZNear (const Standard_Real theZNear);
+  //! @param theZFar [in] the distance of the plane from the Eye.
+  Standard_EXPORT void SetZRange (const Standard_Real theZNear, const Standard_Real theZFar);
 
   //! Get the Near Z-clipping plane position.
   //! @return the distance of the plane from the Eye.
@@ -242,10 +281,6 @@ public:
     return myZNear;
   }
 
-  //! Change the Far Z-clipping plane position.
-  //! @param theZFar [in] the distance of the plane from the Eye.
-  Standard_EXPORT void SetZFar (const Standard_Real theZFar);
-
   //! Get the Far Z-clipping plane position.
   //! @return the distance of the plane from the Eye.
   Standard_Real ZFar() const
@@ -307,52 +342,7 @@ public:
     return myIODType;
   }
 
-  //! Get orientation matrix.
-  //! @return camera orientation matrix.
-  const Graphic3d_Mat4& OrientationMatrix() const
-  {
-    return myOrientation;
-  }
-
-  //! Get monographic or middle point projection matrix used for monographic
-  //! rendering and for point projection / unprojection.
-  //! @return monographic projection matrix.
-  const Graphic3d_Mat4& ProjectionMatrix() const
-  {
-    return myMProjection;
-  }
-
-  //! @return stereographic matrix computed for left eye. Please note
-  //! that this method is used for rendering for <i>Projection_Stereo</i>.
-  const Graphic3d_Mat4& ProjectionStereoLeft() const
-  {
-    return myLProjection;
-  }
-
-  //! @return stereographic matrix computed for right eye. Please note
-  //! that this method is used for rendering for <i>Projection_Stereo</i>.
-  const Graphic3d_Mat4& ProjectionStereoRight() const
-  {
-    return myRProjection;
-  }
-
-public:
-
-  //! Orthogonalize up direction vector.
-  Standard_EXPORT void OrthogonalizeUp();
-
-  //! Suspend internal data recalculation when changing set of camera
-  //! properties. This method is optional and can be used for pieces
-  //! of code which are critical to performance. Note that the method
-  //! supports stacked calls (carried out by internal counter).
-  Standard_EXPORT void BeginUpdate();
-
-  //! Unset lock set by <i>BeginUpdate</i> and invoke data recalculation when
-  //! there are no more locks left. This method is optional and can be used
-  //! for pieces of code which are critical to performance.
-  Standard_EXPORT void EndUpdate();
-
-  // Basic camera operations
+//! @name Basic camera operations
 public:
 
   //! Transform orientation components of the camera:
@@ -363,20 +353,28 @@ public:
   //! Calculate view plane size at center (target) point
   //! and distance between ZFar and ZNear planes.
   //! @return values in form of gp_Pnt (Width, Height, Depth).
-  Standard_EXPORT gp_Pnt ViewDimensions () const;
-
-  //! Calculate view plane dimensions with projection shift applied.
-  //! Analog to old ViewMapping.WindowLimit() function.
-  //! @param theUMin [out] the u component of min corner of the rect.
-  //! @param theVMin [out] the v component of min corner of the rect.
-  //! @param theUMax [out] the u component of max corner of the rect.
-  //! @param theVMax [out] the v component of max corner of the rect.
-  Standard_EXPORT void WindowLimit (Standard_Real& theUMin,
-                                    Standard_Real& theVMin,
-                                    Standard_Real& theUMax,
-                                    Standard_Real& theVMax) const;
-
-  // Projection methods
+  Standard_EXPORT gp_XYZ ViewDimensions() const;
+
+  //! Calculate WCS frustum planes for the camera projection volume.
+  //! Frustum is a convex volume determined by six planes directing
+  //! inwards.
+  //! The frustum planes are usually used as inputs for camera algorithms.
+  //! Thus, if any changes to projection matrix calculation are necessary,
+  //! the frustum planes calculation should be also touched.
+  //! @param theLeft [out] the frustum plane for left side of view.
+  //! @param theRight [out] the frustum plane for right side of view.
+  //! @param theBottom [out] the frustum plane for bottom side of view.
+  //! @param theTop [out] the frustum plane for top side of view.
+  //! @param theNear [out] the frustum plane for near side of view.
+  //! @param theFar [out] the frustum plane for far side of view.
+  Standard_EXPORT void Frustum (gp_Pln& theLeft,
+                                gp_Pln& theRight,
+                                gp_Pln& theBottom,
+                                gp_Pln& theTop,
+                                gp_Pln& theNear,
+                                gp_Pln& theFar) const;
+
+//! @name Projection methods
 public:
 
   //! Project point from world coordinate space to
@@ -415,14 +413,80 @@ public:
   //! @return point in WCS.
   Standard_EXPORT gp_Pnt ConvertView2World (const gp_Pnt& thePnt) const;
 
-  // managing projection and orientation cache:
+//! @name Camera modification state
 public:
 
-  //! Compute and cache projection matrices.
-  void UpdateProjection();
+  //! Returns modification state of camera projection matrix
+  Standard_Size ProjectionState() const
+  {
+    return myProjectionState;
+  }
+
+  //! Returns modification state of camera model-view matrix
+  Standard_Size ModelViewState() const
+  {
+    return myOrientationState;
+  }
+
+//! @name Lazily-computed orientation and projection matrices derived from camera parameters
+public:
 
-  //! Compute and cache orientation matrix.
-  void UpdateOrientation();
+  //! Get orientation matrix.
+  //! @return camera orientation matrix.
+  Standard_EXPORT const Graphic3d_Mat4d& OrientationMatrix() const;
+
+  //! Get orientation matrix of Standard_ShortReal precision.
+  //! @return camera orientation matrix.
+  Standard_EXPORT const Graphic3d_Mat4& OrientationMatrixF() const;
+
+  //! Get monographic or middle point projection matrix used for monographic
+  //! rendering and for point projection / unprojection.
+  //! @return monographic projection matrix.
+  Standard_EXPORT const Graphic3d_Mat4d& ProjectionMatrix() const;
+
+  //! Get monographic or middle point projection matrix of Standard_ShortReal precision used for monographic
+  //! rendering and for point projection / unprojection.
+  //! @return monographic projection matrix.
+  Standard_EXPORT const Graphic3d_Mat4& ProjectionMatrixF() const;
+
+  //! @return stereographic matrix computed for left eye. Please note
+  //! that this method is used for rendering for <i>Projection_Stereo</i>.
+  Standard_EXPORT const Graphic3d_Mat4d& ProjectionStereoLeft() const;
+
+  //! @return stereographic matrix of Standard_ShortReal precision computed for left eye.
+  //! Please note that this method is used for rendering for <i>Projection_Stereo</i>.
+  Standard_EXPORT const Graphic3d_Mat4& ProjectionStereoLeftF() const;
+
+  //! @return stereographic matrix computed for right eye. Please note
+  //! that this method is used for rendering for <i>Projection_Stereo</i>.
+  Standard_EXPORT const Graphic3d_Mat4d& ProjectionStereoRight() const;
+
+  //! @return stereographic matrix of Standard_ShortReal precision computed for right eye.
+  //! Please note that this method is used for rendering for <i>Projection_Stereo</i>.
+  Standard_EXPORT const Graphic3d_Mat4& ProjectionStereoRightF() const;
+
+//! @name Managing projection and orientation cache
+private:
+
+  //! Compute projection matrices.
+  //! @param theMatrices [in] the matrices data container.
+  template <typename Elem_t>
+  Standard_EXPORT
+    TransformMatrices<Elem_t>& UpdateProjection (TransformMatrices<Elem_t>& theMatrices) const;
+
+  //! Compute orientation matrix.
+  //! @param theMatrices [in] the matrices data container.
+  template <typename Elem_t>
+  Standard_EXPORT
+    TransformMatrices<Elem_t>& UpdateOrientation (TransformMatrices<Elem_t>& theMatrices) const;
+
+  //! Invalidate state of projection matrix.
+  //! The matrix will be updated on request.
+  void InvalidateProjection();
+
+  //! Invalidate orientation matrix.
+  //! The matrix will be updated on request.
+  void InvalidateOrientation();
 
 private:
 
@@ -434,19 +498,16 @@ private:
   //! @param theTop [in] the top mapping (clipping) coordinate.
   //! @param theNear [in] the near mapping (clipping) coordinate.
   //! @param theFar [in] the far mapping (clipping) coordinate.
-  //! @param theShiftX [in] the shift x coordinate.
-  //! @param theShiftY [in] the shift y coordinate.
   //! @param theOutMx [out] the projection matrix.
+  template <typename Elem_t>
   static void 
-    OrthoProj (const Standard_ShortReal theLeft,
-               const Standard_ShortReal theRight,
-               const Standard_ShortReal theBottom,
-               const Standard_ShortReal theTop,
-               const Standard_ShortReal theNear,
-               const Standard_ShortReal theFar,
-               const Standard_ShortReal theShiftX,
-               const Standard_ShortReal theShiftY,
-               Graphic3d_Mat4&          theOutMx);
+    OrthoProj (const Elem_t              theLeft,
+               const Elem_t              theRight,
+               const Elem_t              theBottom,
+               const Elem_t              theTop,
+               const Elem_t              theNear,
+               const Elem_t              theFar,
+               NCollection_Mat4<Elem_t>& theOutMx);
 
   //! Compose perspective projection matrix for
   //! the passed camera volume mapping.
@@ -456,19 +517,16 @@ private:
   //! @param theTop [in] the top mapping (clipping) coordinate.
   //! @param theNear [in] the near mapping (clipping) coordinate.
   //! @param theFar [in] the far mapping (clipping) coordinate.
-  //! @param theShiftX [in] the shift x coordinate.
-  //! @param theShiftY [in] the shift y coordinate.
   //! @param theOutMx [out] the projection matrix.
+  template <typename Elem_t>
   static void
-    PerspectiveProj (const Standard_ShortReal theLeft,
-                     const Standard_ShortReal theRight,
-                     const Standard_ShortReal theBottom,
-                     const Standard_ShortReal theTop,
-                     const Standard_ShortReal theNear,
-                     const Standard_ShortReal theFar,
-                     const Standard_ShortReal theShiftX,
-                     const Standard_ShortReal theShiftY,
-                     Graphic3d_Mat4&          theOutMx);
+    PerspectiveProj (const Elem_t              theLeft,
+                     const Elem_t              theRight,
+                     const Elem_t              theBottom,
+                     const Elem_t              theTop,
+                     const Elem_t              theNear,
+                     const Elem_t              theFar,
+                     NCollection_Mat4<Elem_t>& theOutMx);
 
   //! Compose projection matrix for L/R stereo eyes.
   //! @param theLeft [in] the left mapping (clipping) coordinate.
@@ -480,23 +538,20 @@ private:
   //! @param theIOD [in] the Intraocular distance.
   //! @param theZFocus [in] the z coordinate of off-axis
   //! projection plane with zero parallax.
-  //! @param theShiftX [in] the shift x coordinate.
-  //! @param theShiftY [in] the shift y coordinate.
   //! @param theIsLeft [in] boolean flag to choose between L/R eyes.
   //! @param theOutMx [out] the projection matrix.
+  template <typename Elem_t>
   static void
-    StereoEyeProj (const Standard_ShortReal theLeft,
-                   const Standard_ShortReal theRight,
-                   const Standard_ShortReal theBottom,
-                   const Standard_ShortReal theTop,
-                   const Standard_ShortReal theNear,
-                   const Standard_ShortReal theFar,
-                   const Standard_ShortReal theIOD,
-                   const Standard_ShortReal theZFocus,
-                   const Standard_ShortReal theShiftX,
-                   const Standard_ShortReal theShiftY,
-                   const Standard_Boolean   theIsLeft,
-                   Graphic3d_Mat4&          theOutMx);
+    StereoEyeProj (const Elem_t              theLeft,
+                   const Elem_t              theRight,
+                   const Elem_t              theBottom,
+                   const Elem_t              theTop,
+                   const Elem_t              theNear,
+                   const Elem_t              theFar,
+                   const Elem_t              theIOD,
+                   const Elem_t              theZFocus,
+                   const Standard_Boolean    theIsLeft,
+                   NCollection_Mat4<Elem_t>& theOutMx);
 
   //! Construct "look at" orientation transformation.
   //! Reference point differs for perspective and ortho modes 
@@ -506,12 +561,13 @@ private:
   //! @param theUpDir [in] the up direction vector.
   //! @param theAxialScale [in] the axial scale vector.
   //! @param theOutMx [in/out] the orientation matrix.
+  template <typename Elem_t>
   static void
-    LookOrientation (const Graphic3d_Vec3& theEye,
-                     const Graphic3d_Vec3& theLookAt,
-                     Graphic3d_Vec3& theUpDir,
-                     const Graphic3d_Vec3& theAxialScale,
-                     Graphic3d_Mat4& theOutMx);
+    LookOrientation (const NCollection_Vec3<Elem_t>& theEye,
+                     const NCollection_Vec3<Elem_t>& theLookAt,
+                     const NCollection_Vec3<Elem_t>& theUpDir,
+                     const NCollection_Vec3<Elem_t>& theAxialScale,
+                     NCollection_Mat4<Elem_t>&       theOutMx);
 
 private:
 
@@ -519,14 +575,13 @@ private:
   gp_Pnt myEye;    //!< Camera eye position.
   gp_Pnt myCenter; //!< Camera center.
 
-  gp_Pnt myProjectionShift; //!< Camera projection shift for compatibility.
-  gp_Pnt myAxialScale;      //!< Camera axial scale.
+  gp_XYZ myAxialScale; //!< World axial scale.
 
-  Projection myProjType;  //!< Projection type used for rendering.
-  Standard_Real myFOVy;   //!< Field Of View in y axis.
-  Standard_Real myZNear;  //!< Distance to near clipping plane.
-  Standard_Real myZFar;   //!< Distance to far clipping plane.
-  Standard_Real myAspect; //!< Width to height display ratio.
+  Projection    myProjType; //!< Projection type used for rendering.
+  Standard_Real myFOVy;     //!< Field Of View in y axis.
+  Standard_Real myZNear;    //!< Distance to near clipping plane.
+  Standard_Real myZFar;     //!< Distance to far clipping plane.
+  Standard_Real myAspect;   //!< Width to height display ratio.
 
   Standard_Real myScale;      //!< Specifies parallel scale for orthographic projection.
   Standard_Real myZFocus;     //!< Stereographic focus value.
@@ -535,19 +590,11 @@ private:
   Standard_Real myIOD;     //!< Intraocular distance value.
   IODType       myIODType; //!< Intraocular distance definition type.
 
-  //! Number of locks set up on internal data recalculation by
-  //! <i>(BeginUpdate, EndUpdate)</i> pairs. The counter provides effective
-  //! use of the mentioned methods when camera properties are modified
-  //! in stacked functions.
-  Standard_Integer myNbUpdateLocks;
-
-  Graphic3d_Mat4 myOrientation; //!< Camera orientation matrix.
-  Graphic3d_Mat4 myMProjection; //!< Monographic projection matrix.
-  Graphic3d_Mat4 myLProjection; //!< Projection matrix for left eye.
-  Graphic3d_Mat4 myRProjection; //!< Projection matrix for right eye.
+  mutable TransformMatrices<Standard_Real>      myMatricesD;
+  mutable TransformMatrices<Standard_ShortReal> myMatricesF;
 
-  Standard_Size myProjectionState;
-  Standard_Size myOrientationState;
+  mutable Standard_Size myProjectionState;
+  mutable Standard_Size myOrientationState;
 
 public:
 
index 68c7556..7041253 100755 (executable)
@@ -18,6 +18,5 @@
 #include <Standard_TypeDef.hxx>
 
 typedef NCollection_Mat4<Standard_ShortReal> Graphic3d_Mat4;
-typedef NCollection_Mat4<Standard_Real>      Graphic3d_Mat4d;
 
 #endif // _Graphic3d_Mat4_HeaderFile
diff --git a/src/Graphic3d/Graphic3d_Mat4d.hxx b/src/Graphic3d/Graphic3d_Mat4d.hxx
new file mode 100644 (file)
index 0000000..117d796
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_Mat4d_HeaderFile
+#define _Graphic3d_Mat4d_HeaderFile
+
+#include <NCollection_Mat4.hxx>
+#include <Standard_TypeDef.hxx>
+
+typedef NCollection_Mat4<Standard_Real> Graphic3d_Mat4d;
+
+#endif // _Graphic3d_Mat4d_HeaderFile
index 8025e4d..4e8dd03 100644 (file)
@@ -214,18 +214,14 @@ is
        --          with the highlight method TOHM_COLOR or TOHM_BOUNDBOX.
        ---Category: Methods to modify the class definition
 
-       SetInfiniteState ( me           : mutable;
-                          AFlag        : Boolean from Standard )
-               is static;
-       ---Level: Internal
-       ---Purpose: Modifies the coordinates of the boundary box
-       --          of the structure <me>.
-       --          if <AFlag> is Standard_True then <me> is infinite and
-       --          the MinMaxValues method or the MinMaxCoord method return :
-       --          XMin = YMin = ZMin = RealFirst ().
-       --          XMax = YMax = ZMax = RealLast ().
-       --          By default, <me> is not infinite but empty.
-       ---Category: Methods to modify the class definition
+    SetInfiniteState (me : mutable; theToSet : Boolean from Standard) is static;
+    ---Level: Internal
+    ---Purpose: If <theToSet> is Standard_True then <me> is infinite and
+    --          the MinMaxValues method method return :
+    --          theXMin = theYMin = theZMin = RealFirst().
+    --          theXMax = theYMax = theZMax = RealLast().
+    --          By default, <me> is not infinite but empty.
+    ---Category: Methods to modify the class definition
 
        SetDisplayPriority ( me         : mutable;
                             Priority   : Integer from Standard )
@@ -555,17 +551,23 @@ is
        ---Purpose: Returns the current group of graphic attributes used
        -- for 3d marker primitives.
 
-       MinMaxValues ( me;
-                      XMin, YMin, ZMin : out Real from Standard;
-                      XMax, YMax, ZMax : out Real from Standard )
-               is static;
-       ---Level: Public
-       ---Purpose: Returns the coordinates of the boundary box
-       --          of the structure <me>.
-       --  Warning: If the structure <me> is empty or infinite then :
-       --          XMin = YMin = ZMin = RealFirst ().
-       --          XMax = YMax = ZMax = RealLast ().
-       ---Category: Inquire methods
+    MinMaxValues (me;
+                  theXMin, theYMin, theZMin : out Real from Standard;
+                  theXMax, theYMax, theZMax : out Real from Standard;
+                  theToIgnoreInfiniteFlag   : Boolean from Standard = Standard_False)
+    is static;
+    ---Level: Public
+    ---Purpose: Returns the coordinates of the boundary box of the structure <me>.
+    --          If <theToIgnoreInfiniteFlag> is TRUE, the method returns actual graphical
+    --          boundaries of the Graphic3d_Group components. Otherwise, the
+    --          method returns boundaries taking into account infinite state
+    --          of the structure. This approach generally used for application
+    --          specific fit operation (e.g. fitting the model into screen,
+    --          not taking into accout infinite helper elements).
+    --          Warning: If the structure <me> is empty or infinite then :
+    --            theXMin = theYMin = theZMin = RealFirst ().
+    --            theXMax = theYMax = theZMax = RealLast ().
+    ---Category: Inquire methods
 
        PrimitivesAspect ( me;
                           CTXL : out AspectLine3d from Graphic3d;
@@ -877,17 +879,28 @@ is
        ---Purpose: Returns the identification number of the structure <me>.
        ---Category: Private methods
 
-       MinMaxCoord ( me;
-                     XMin, YMin, ZMin  : out Real from Standard;
-                     XMax, YMax, ZMax  : out Real from Standard )
-               is static private;
-       ---Level: Internal
-       ---Purpose: Returns the extreme coordinates found in the
-       --          structure <me>.
-       --  Warning: If the structure <me> is empty or infinite then :
-       --          XMin = YMin = ZMin = RealFirst ().
-       --          XMax = YMax = ZMax = RealLast ().
-       ---Category: Private methods
+    MinMaxCoord (me;
+                 theXMin, theYMin, theZMin : out Real from Standard;
+                 theXMax, theYMax, theZMax : out Real from Standard)
+    is static private;
+    ---Level: Internal
+    ---Purpose: Returns the extreme coordinates found in the structure <me>.
+    --  Warning: If the structure <me> is empty or infinite then :
+    --    theXMin = theYMin = theZMin = RealFirst().
+    --    theXMax = theYMax = theZMax = RealLast().
+    ---Category: Private methods
+
+    MinMaxCoordWithDescendants (me;
+                                theXMin, theYMin, theZMin : out Real from Standard;
+                                theXMax, theYMax, theZMax : out Real from Standard)
+    is static private;
+    ---Level: Internal
+    ---Purpose: Returns the extreme coordinates found in the structure <me>
+    -- and its descendants with transformation applied.
+    --  Warning: If the structure <me> is empty or infinite then :
+    --    theXMin = theYMin = theZMin = RealFirst().
+    --    theXMax = theYMax = theZMax = RealLast().
+    ---Category: Private methods
 
        Plot ( me       : mutable;
               aPlotter : Plotter from Graphic3d )
@@ -957,6 +970,15 @@ is
        ---Purpose: Transforms <Coord> with the transformation <ATrsf>.
        ---Category: Private methods
 
+    TransformBoundaries (myclass;
+                         theTrsf : Array2OfReal from TColStd;
+                         theXMin, theYMin, theZMin : in out Real from Standard;
+                         theXMax, theYMax, theZMax : in out Real from Standard)
+    is protected;
+    ---Level: Internal
+    ---Purpose: Transforms boundaries with <theTrsf> transformation.
+    ---Category: Private methods
+
        Update ( me )
                is static private;
        ---Level: Internal
index c435617..d8de3bd 100644 (file)
@@ -683,10 +683,13 @@ void Graphic3d_Structure::ReCompute (const Handle(Graphic3d_DataStructureManager
 
 }
 
-void Graphic3d_Structure::SetInfiniteState (const Standard_Boolean AValue) {
-
-  MyCStructure.IsInfinite = AValue ? 1:0;
-
+//=============================================================================
+//function : SetInfiniteState
+//purpose  :
+//=============================================================================
+void Graphic3d_Structure::SetInfiniteState (const Standard_Boolean theToSet)
+{
+  MyCStructure.IsInfinite = theToSet ? 1 : 0;
 }
 
 Standard_Boolean Graphic3d_Structure::IsInfinite () const {
@@ -1645,70 +1648,120 @@ void Graphic3d_Structure::Transform (TColStd_Array2OfReal& AMatrix) const {
 
 }
 
-void Graphic3d_Structure::MinMaxValues (Standard_Real& XMin, Standard_Real& YMin, Standard_Real& ZMin, Standard_Real& XMax, Standard_Real& YMax, Standard_Real& ZMax) const {
-
-  Standard_Real RL = RealLast ();
-  Standard_Real RF = RealFirst ();
+//=============================================================================
+//function : MinMaxValues
+//purpose  :
+//=============================================================================
+void Graphic3d_Structure::MinMaxValues (Standard_Real& theXMin,
+                                        Standard_Real& theYMin,
+                                        Standard_Real& theZMin,
+                                        Standard_Real& theXMax,
+                                        Standard_Real& theYMax,
+                                        Standard_Real& theZMax,
+                                        const Standard_Boolean theToIgnoreInfiniteFlag) const
+{
+  if (IsEmpty())
+  {
+    return;
+  }
 
-  Standard_Real XTMin, YTMin, ZTMin, XTMax, YTMax, ZTMax, U, V, W;
+  Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
+  MinMaxCoord (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
 
-  MinMaxCoord (XTMin, YTMin, ZTMin, XTMax, YTMax, ZTMax);
-  if ((XTMin == RF) && (YTMin == RF) &&
-      (ZTMin == RF) && (XTMax == RL) &&
-      (YTMax == RL) && (ZTMax == RL)) {
-      // Case impossible as it would mean that
-      // the structure is empty
-      XMin = RF;
-      YMin = RF;
-      ZMin = RF;
+  // Infinite boundaries corresponding to empty structure or
+  // non-empty structure, without any primitives specified
+  if (aXMin == RealFirst() && aYMin == RealFirst() && aZMin == RealFirst() &&
+      aXMax == RealLast()  && aYMax == RealLast()  && aZMax == RealLast())
+  {
+    theXMin = RealFirst();
+    theYMin = RealFirst();
+    theZMin = RealFirst();
+    theXMax = RealLast();
+    theYMax = RealLast();
+    theZMax = RealLast();
+    return;
+  }
 
-      XMax = RL;
-      YMax = RL;
-      ZMax = RL;
+  // Handle flag, which specifies that structure should be considered as infinite
+  if (IsInfinite() && !theToIgnoreInfiniteFlag)
+  {
+    Graphic3d_Vertex aVertexMin (aXMin, aYMin, aZMin);
+    Graphic3d_Vertex aVertexMax (aXMax, aYMax, aZMax);
+    const Standard_Real aDistance = aVertexMin.Distance (aVertexMax);
+
+    // Special case for infinite line:
+    // Bounding borders of infinite line has been
+    // calculated as own point in center of this line
+    if (aDistance >= 500000.0)
+    {
+      theXMin = theXMax = 0.5 * (aXMin + aXMax);
+      theYMin = theYMax = 0.5 * (aYMin + aYMax);
+      theZMin = theZMax = 0.5 * (aZMin + aZMax);
+      return;
     }
-  else {
-    Standard_Integer i, j;
-    TColStd_Array2OfReal TheTrsf (0, 3, 0, 3);
 
-    for (i=0; i<=3; i++)
-      for (j=0; j<=3; j++)
-        TheTrsf (i, j) = MyCStructure.Transformation[i][j];
-
-    Graphic3d_Structure::Transforms
-      (TheTrsf, XTMin, YTMin, ZTMin, XMin, YMin, ZMin);
-    Graphic3d_Structure::Transforms
-      (TheTrsf, XTMax, YTMax, ZTMax, XMax, YMax, ZMax);
-    Graphic3d_Structure::Transforms
-      (TheTrsf, XTMin, YTMin, ZTMax, U, V, W);
-    XMin = Min(U,XMin) ; XMax = Max(U,XMax) ;
-    YMin = Min(V,YMin) ; YMax = Max(V,YMax) ;
-    ZMin = Min(W,ZMin) ; ZMax = Max(W,ZMax) ;
-    Graphic3d_Structure::Transforms
-      (TheTrsf, XTMax, YTMin, ZTMax, U, V, W);
-    XMin = Min(U,XMin) ; XMax = Max(U,XMax) ;
-    YMin = Min(V,YMin) ; YMax = Max(V,YMax) ;
-    ZMin = Min(W,ZMin) ; ZMax = Max(W,ZMax) ;
-    Graphic3d_Structure::Transforms
-      (TheTrsf, XTMax, YTMin, ZTMin, U, V, W);
-    XMin = Min(U,XMin) ; XMax = Max(U,XMax) ;
-    YMin = Min(V,YMin) ; YMax = Max(V,YMax) ;
-    ZMin = Min(W,ZMin) ; ZMax = Max(W,ZMax) ;
-    Graphic3d_Structure::Transforms
-      (TheTrsf, XTMax, YTMax, ZTMin, U, V, W);
-    XMin = Min(U,XMin) ; XMax = Max(U,XMax) ;
-    YMin = Min(V,YMin) ; YMax = Max(V,YMax) ;
-    ZMin = Min(W,ZMin) ; ZMax = Max(W,ZMax) ;
-    Graphic3d_Structure::Transforms
-      (TheTrsf, XTMin, YTMax, ZTMax, U, V, W);
-    XMin = Min(U,XMin) ; XMax = Max(U,XMax) ;
-    YMin = Min(V,YMin) ; YMax = Max(V,YMax) ;
-    ZMin = Min(W,ZMin) ; ZMax = Max(W,ZMax) ;
-    Graphic3d_Structure::Transforms
-      (TheTrsf, XTMin, YTMax, ZTMin, U, V, W);
-    XMin = Min(U,XMin) ; XMax = Max(U,XMax) ;
-    YMin = Min(V,YMin) ; YMax = Max(V,YMax) ;
-    ZMin = Min(W,ZMin) ; ZMax = Max(W,ZMax) ;
+    theXMin = RealFirst();
+    theYMin = RealFirst();
+    theZMin = RealFirst();
+    theXMax = RealLast();
+    theYMax = RealLast();
+    theZMax = RealLast();
+    return;
+  }
+
+  // Min-Max values of the descendant structures
+  Standard_Real aDescXMin = RealLast();
+  Standard_Real aDescYMin = RealLast();
+  Standard_Real aDescZMin = RealLast();
+  Standard_Real aDescXMax = RealFirst();
+  Standard_Real aDescYMax = RealFirst();
+  Standard_Real aDescZMax = RealFirst();
+  for (Standard_Integer aStructIt = 1; aStructIt <= MyDescendants.Length(); aStructIt++)
+  {
+    Graphic3d_Structure* aStructure = (Graphic3d_Structure*) MyDescendants.Value (aStructIt);
+    aStructure->MinMaxValues (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
+    aDescXMin = Min (aXMin, aDescXMin);
+    aDescYMin = Min (aYMin, aDescYMin);
+    aDescZMin = Min (aZMin, aDescZMin);
+    aDescXMax = Max (aXMax, aDescXMax);
+    aDescYMax = Max (aYMax, aDescYMax);
+    aDescZMax = Max (aZMax, aDescZMax);
+  }
+
+  if (aDescXMin != RealLast()  || aDescYMin != RealLast()  ||
+      aDescZMin != RealLast()  || aDescXMax != RealFirst() ||
+      aDescYMax != RealFirst() || aDescZMax != RealFirst())
+  {
+    aXMin = Min (aDescXMin, aXMin);
+    aYMin = Min (aDescYMin, aYMin);
+    aZMin = Min (aDescZMin, aZMin);
+    aXMax = Max (aDescXMax, aXMax);
+    aYMax = Max (aDescYMax, aYMax);
+    aZMax = Max (aDescZMax, aZMax);
+  }
+
+  // Case impossible as it would mean that the structure is empty or infinite
+  if (aXMin == RealFirst() && aYMin == RealFirst() && aZMin == RealFirst() &&
+      aXMax == RealLast()  && aYMax == RealLast()  && aZMax == RealLast())
+  {
+    theXMin = RealFirst();
+    theYMin = RealFirst();
+    theZMin = RealFirst();
+    theXMax = RealLast();
+    theYMax = RealLast();
+    theZMax = RealLast();
+    return;
   }
+
+  TColStd_Array2OfReal aTrsf(0, 3, 0, 3);
+  Transform (aTrsf);
+  TransformBoundaries (aTrsf, aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
+  theXMin = aXMin;
+  theYMin = aYMin;
+  theZMin = aZMin;
+  theXMax = aXMax;
+  theYMax = aYMax;
+  theZMax = aZMax;
 }
 
 Standard_Integer Graphic3d_Structure::Identification () const {
@@ -1825,93 +1878,156 @@ Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager () cons
 
 }
 
+//=============================================================================
+//function : MinMaxCoord
+//purpose  :
+//=============================================================================
+void Graphic3d_Structure::MinMaxCoord (Standard_Real& theXMin,
+                                       Standard_Real& theYMin,
+                                       Standard_Real& theZMin,
+                                       Standard_Real& theXMax,
+                                       Standard_Real& theYMax,
+                                       Standard_Real& theZMax) const
+{
+  if (IsEmpty())
+  {
+    theXMin = RealFirst();
+    theYMin = RealFirst();
+    theZMin = RealFirst();
+    theXMax = RealLast();
+    theYMax = RealLast();
+    theZMax = RealLast();
+    return;
+  }
 
-void Graphic3d_Structure::MinMaxCoord (Standard_Real& XMin, Standard_Real& YMin, Standard_Real& ZMin, Standard_Real& XMax, Standard_Real& YMax, Standard_Real& ZMax) const {
+  Standard_Real aXMin = RealLast();
+  Standard_Real aYMin = RealLast();
+  Standard_Real aZMin = RealLast();
+  Standard_Real aXMax = RealFirst();
+  Standard_Real aYMax = RealFirst();
+  Standard_Real aZMax = RealFirst();
+  Standard_Real aGroupXMin, aGroupYMin, aGroupZMin, aGroupXMax, aGroupYMax, aGroupZMax;
+  for (Standard_Integer aGroupIt = 1; aGroupIt <= MyGroups.Length(); aGroupIt++)
+  {
+    const Handle(Graphic3d_Group)& aGroup = MyGroups.Value (aGroupIt);
 
-  Standard_Real RL = RealLast ();
-  Standard_Real RF = RealFirst ();
+    if (aGroup->IsEmpty())
+    {
+      continue;
+    }
 
-  Standard_Real Xm, Ym, Zm, XM, YM, ZM;
+    aGroup->MinMaxValues (aGroupXMin, aGroupYMin, aGroupZMin, aGroupXMax, aGroupYMax, aGroupZMax);
+    aXMin = Min (aXMin, aGroupXMin);
+    aYMin = Min (aYMin, aGroupYMin);
+    aZMin = Min (aZMin, aGroupZMin);
+    aXMax = Max (aXMax, aGroupXMax);
+    aYMax = Max (aYMax, aGroupYMax);
+    aZMax = Max (aZMax, aGroupZMax);
+  }
 
-  //Bounding borders of infinite line has been calculated as own point
-  //in center of this line
-  if (IsEmpty () || IsInfinite ()) {
-    if( IsInfinite ()){
-      for (int i=1; i<=MyGroups.Length (); i++)
-        if (! (MyGroups.Value (i))->IsEmpty () ) {
-          (MyGroups.Value (i))->MinMaxValues(Xm, Ym, Zm, XM, YM, ZM);
-          Graphic3d_Vertex vertex1(Xm, Ym, Zm);
-          Graphic3d_Vertex vertex2(XM, YM, ZM);
-          const Standard_Real distance = vertex1.Distance( vertex2 );
-          if( distance >= 500000.0){
-            XMin = XMax = 0.5*(Xm+ XM);
-            YMin = YMax = 0.5*(Ym+ YM);
-            ZMin = ZMax = 0.5*(Zm+ ZM);
-            return;
-          }
-        }
-    }
-    XMin = RF;
-    YMin = RF;
-    ZMin = RF;
+  // Case impossible as it would mean that the structure is empty
+  if (aXMin == RealLast()  && aYMin == RealLast()  && aZMin == RealLast() &&
+      aXMax == RealFirst() && aYMax == RealFirst() && aZMax == RealFirst())
+  {
+    theXMin = RealFirst();
+    theYMin = RealFirst();
+    theZMin = RealFirst();
+    theXMax = RealLast();
+    theYMax = RealLast();
+    theZMax = RealLast();
+  }
+
+  theXMin = aXMin;
+  theYMin = aYMin;
+  theZMin = aZMin;
+  theXMax = aXMax;
+  theYMax = aYMax;
+  theZMax = aZMax;
+}
 
-    XMax = RL;
-    YMax = RL;
-    ZMax = RL;
+//=============================================================================
+//function : MinMaxCoordWithDescendants
+//purpose  :
+//=============================================================================
+void Graphic3d_Structure::MinMaxCoordWithDescendants (Standard_Real& theXMin,
+                                                      Standard_Real& theYMin,
+                                                      Standard_Real& theZMin,
+                                                      Standard_Real& theXMax,
+                                                      Standard_Real& theYMax,
+                                                      Standard_Real& theZMax) const
+{
+  if (IsEmpty())
+  {
+    theXMin = RealFirst();
+    theYMin = RealFirst();
+    theZMin = RealFirst();
+    theXMax = RealLast();
+    theYMax = RealLast();
+    theZMax = RealLast();
+    return;
   }
-  else {
-    XMin = RL;
-    YMin = RL;
-    ZMin = RL;
 
-    XMax = RF;
-    YMax = RF;
-    ZMax = RF;
-    Standard_Integer i, Length;
+  Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
+  MinMaxCoord (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
+
+  // Min-Max of the descendant structures
+  Standard_Real aDescXMin = RealLast();
+  Standard_Real aDescYMin = RealLast();
+  Standard_Real aDescZMin = RealLast();
+  Standard_Real aDescXMax = RealFirst();
+  Standard_Real aDescYMax = RealFirst();
+  Standard_Real aDescZMax = RealFirst();
+  for (Standard_Integer aStructIt = 1; aStructIt <= MyDescendants.Length(); aStructIt++)
+  {
+    Graphic3d_Structure* aStructure = (Graphic3d_Structure*) MyDescendants.Value (aStructIt);
+    if (aStructure->IsEmpty())
+    {
+      continue;
+    }
 
-    Length  = MyGroups.Length ();
-    for (i=1; i<=Length; i++)
-      if (! (MyGroups.Value (i))->IsEmpty () ) {
-        (MyGroups.Value (i))->MinMaxValues(Xm, Ym, Zm, XM, YM, ZM);
-        if (Xm < XMin) XMin = Xm;
-        if (Ym < YMin) YMin = Ym;
-        if (Zm < ZMin) ZMin = Zm;
-        if (XM > XMax) XMax = XM;
-        if (YM > YMax) YMax = YM;
-        if (ZM > ZMax) ZMax = ZM;
-      }
+    aStructure->MinMaxCoordWithDescendants (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
+    aDescXMin = Min (aXMin, aDescXMin);
+    aDescYMin = Min (aYMin, aDescYMin);
+    aDescZMin = Min (aZMin, aDescZMin);
+    aDescXMax = Max (aXMax, aDescXMax);
+    aDescYMax = Max (aYMax, aDescYMax);
+    aDescZMax = Max (aZMax, aDescZMax);
+  }
 
-      Length  = MyDescendants.Length ();
-      for (i=1; i<=Length; i++)
-        if (! ((Graphic3d_Structure *)
-          (MyDescendants.Value (i)))->IsEmpty () ) {
-            ((Graphic3d_Structure *)
-              (MyDescendants.Value (i)))->MinMaxValues (Xm, Ym, Zm, XM, YM, ZM);
-
-            if (Xm < XMin) XMin = Xm;
-            if (Ym < YMin) YMin = Ym;
-            if (Zm < ZMin) ZMin = Zm;
-            if (XM > XMax) XMax = XM;
-            if (YM > YMax) YMax = YM;
-            if (ZM > ZMax) ZMax = ZM;
-          }
-
-          if ((XMin == RL) && (YMin == RL) &&
-              (ZMin == RL) && (XMax == RF) &&
-              (YMax == RF) && (ZMax == RF)) {
-              // Case impossible as it would mean
-              // that the structure is empty
-              XMin    = RF;
-              YMin    = RF;
-              ZMin    = RF;
-
-              XMax    = RL;
-              YMax    = RL;
-              ZMax    = RL;
-            }
+  if (aDescXMin != RealLast()  || aDescYMin != RealLast()  ||
+      aDescZMin != RealLast()  || aDescXMax != RealFirst() ||
+      aDescYMax != RealFirst() || aDescZMax != RealFirst())
+  {
+    TColStd_Array2OfReal aTrsf(0, 3, 0, 3);
+    Transform (aTrsf);
+    TransformBoundaries (aTrsf, aDescXMin, aDescYMin, aDescZMin, aDescXMax, aDescYMax, aDescZMax);
+
+    aXMin = Min (aDescXMin, aXMin);
+    aYMin = Min (aDescYMin, aYMin);
+    aZMin = Min (aDescZMin, aZMin);
+    aXMax = Max (aDescXMax, aXMax);
+    aYMax = Max (aDescYMax, aYMax);
+    aZMax = Max (aDescZMax, aZMax);
+  }
 
+  // Case impossible as it would mean that the structure is empty
+  if (aXMin == RealLast()  && aYMin == RealLast()  && aZMin == RealLast() &&
+      aXMax == RealFirst() && aYMax == RealFirst() && aZMax == RealFirst())
+  {
+    theXMin = RealFirst();
+    theYMin = RealFirst();
+    theZMin = RealFirst();
+    theXMax = RealLast();
+    theYMax = RealLast();
+    theZMax = RealLast();
   }
 
+  theXMin = aXMin;
+  theYMin = aYMin;
+  theZMin = aZMin;
+  theXMax = aXMax;
+  theYMax = aYMax;
+  theZMax = aZMax;
 }
 
 void Graphic3d_Structure::Transforms (const TColStd_Array2OfReal& ATrsf, const Standard_Real X, const Standard_Real Y, const Standard_Real Z, Standard_Real& NewX, Standard_Real& NewY, Standard_Real& NewZ) {
@@ -1973,6 +2089,61 @@ Graphic3d_Vertex Graphic3d_Structure::Transforms (const TColStd_Array2OfReal& AT
 
 }
 
+//=============================================================================
+//function : Transforms
+//purpose  :
+//=============================================================================
+void Graphic3d_Structure::TransformBoundaries (const TColStd_Array2OfReal& theTrsf,
+                                               Standard_Real& theXMin,
+                                               Standard_Real& theYMin,
+                                               Standard_Real& theZMin,
+                                               Standard_Real& theXMax,
+                                               Standard_Real& theYMax,
+                                               Standard_Real& theZMax)
+{
+  Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax, anU, aV, aW;
+
+  Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMin, aXMin, aYMin, aZMin);
+  Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMax, aXMax, aYMax, aZMax);
+
+  Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMax, anU, aV, aW);
+  aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
+  aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
+  aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
+
+  Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMax, anU, aV, aW);
+  aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
+  aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
+  aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
+
+  Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMin, anU, aV, aW);
+  aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
+  aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
+  aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
+
+  Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMin, anU, aV, aW);
+  aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
+  aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
+  aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
+
+  Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMax, anU, aV, aW);
+  aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
+  aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
+  aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
+
+  Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMin, anU, aV, aW);
+  aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
+  aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
+  aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
+
+  theXMin = aXMin;
+  theYMin = aYMin;
+  theZMin = aZMin;
+  theXMax = aXMax;
+  theYMax = aYMax;
+  theZMax = aZMax;
+}
+
 void Graphic3d_Structure::Network (const Handle(Graphic3d_Structure)& AStructure, const Graphic3d_TypeOfConnection AType, Graphic3d_MapOfStructure& ASet) {
 
 
@@ -2308,7 +2479,7 @@ void Graphic3d_Structure::GraphicHighlight (const Aspect_TypeOfHighlightMethod A
       XMax = YMax = ZMax = 0.;
     }
     else {
-      MinMaxCoord
+      MinMaxCoordWithDescendants
         (XMin, YMin, ZMin, XMax, YMax, ZMax);
     }
     MyCStructure.BoundBox.Pmin.x    = float (XMin);
index ee3a89f..a2608d9 100755 (executable)
@@ -20,5 +20,6 @@
 #include <Graphic3d_Vec3.hxx>
 #include <Graphic3d_Vec4.hxx>
 #include <Graphic3d_Mat4.hxx>
+#include <Graphic3d_Mat4d.hxx>
 
 #endif // _Graphic3d_Vec_H__
index 61d05ad..d7596c1 100755 (executable)
@@ -191,13 +191,13 @@ public:
   //! Initialize the identity matrix.
   void InitIdentity()
   {
-    static const Element_t anIdentity[] =
-      {1, 0, 0, 0,
-       0, 1, 0, 0,
-       0, 0, 1, 0,
-       0, 0, 0, 1};
+    std::memcpy (this, myIdentityArray, sizeof (NCollection_Mat4));
+  }
 
-    std::memcpy (this, anIdentity, sizeof (NCollection_Mat4));
+  //! Checks the matrix for identity.
+  bool IsIdentity() const
+  {
+    return std::memcmp (this, myIdentityArray, sizeof (NCollection_Mat4)) == 0;
   }
 
   //! Raw access to the data (for OpenGL exchange).
@@ -429,6 +429,16 @@ private:
 
   Element_t myMat[16];
 
+private:
+
+  static Element_t myIdentityArray[16];
 };
 
+template<typename Element_t>
+Element_t NCollection_Mat4<Element_t>::myIdentityArray[] =
+  {1, 0, 0, 0,
+   0, 1, 0, 0,
+   0, 0, 1, 0,
+   0, 0, 0, 1};
+
 #endif // _NCollection_Mat4_HeaderFile
index f816752..b5c6c18 100644 (file)
@@ -106,114 +106,26 @@ void NIS_View::RemoveContext (NIS_InteractiveContext * theCtx)
 
 Standard_Boolean NIS_View::FitAll3d (const Quantity_Coefficient theCoef)
 {
-  Standard_Boolean aResult(Standard_False);
-
   Bnd_B3f aBox = GetBndBox();
 
-  // Check that the box is not empty
-  if (aBox.IsVoid() == Standard_False && MyView->IsDefined() == Standard_True)
+  if (aBox.IsVoid() || MyView->IsDefined() == Standard_False)
   {
-    // Convert the 3D box to 2D representation in view coordinates
-    gp_XYZ aCoord;
-
-    const gp_XYZ aCorner[2] = { aBox.CornerMin(), aBox.CornerMax() };
-
-    // Fit depth
-    const gp_XYZ& aBMin = aCorner[0];
-    const gp_XYZ& aBMax = aCorner[1];
-
-    gp_Pnt anAABBCenter ((aBMin.X() + aBMax.X()) * 0.5,
-                         (aBMin.Y() + aBMax.Y()) * 0.5,
-                         (aBMin.Z() + aBMax.Z()) * 0.5);
-
-    gp_Vec aCenter2AABB (myCamera->Center(), anAABBCenter);
-    gp_Dir aDir = myCamera->Direction();
-
-    // distance projection onto camera direction
-    Standard_Real aDistToBox = -aCenter2AABB.Dot (aDir);
-    gp_Vec aZShift = gp_Vec (aDir).Reversed().Scaled (aDistToBox);
+    return Standard_False;
+  }
 
-    gp_Pnt anEyeBefore   = myCamera->Eye();
-    gp_Pnt aCenterBefore = myCamera->Center();
+  gp_XYZ aMin = aBox.CornerMin();
+  gp_XYZ aMax = aBox.CornerMax();
 
-    myCamera->BeginUpdate();
-    myCamera->SetEye (myCamera->Eye().Translated (aZShift));
-    myCamera->SetCenter (myCamera->Center().Translated (aZShift));
-    myCamera->EndUpdate();
+  if (!FitMinMax (myCamera, aMin, aMax, theCoef, 0.0, Standard_False))
+  {
+    return Standard_False;
+  }
 
-    Standard_Real Umin = RealLast();
-    Standard_Real Umax = RealFirst();
-    Standard_Real Vmin = RealLast();
-    Standard_Real Vmax = RealFirst();
-    Standard_Real U, V, W;
+  AutoZFit();
 
-    Standard_Boolean doFit = Standard_True;
-    while (doFit) 
-    {
-      for (Standard_Integer i = 0; i < 8; i++) {
-        if (i & 0x1) aCoord.SetX (aCorner[0].X());
-        else         aCoord.SetX (aCorner[1].X());
-        if (i & 0x2) aCoord.SetY (aCorner[0].Y());
-        else         aCoord.SetY (aCorner[1].Y());
-        if (i & 0x4) aCoord.SetZ (aCorner[0].Z());
-        else         aCoord.SetZ (aCorner[1].Z());
-
-        MyView->Projects(aCoord.X(), aCoord.Y(), aCoord.Z(), U, V, W);
-        if (i) {
-          Umin = Min(Umin, U); Umax = Max(Umax, U);
-          Vmin = Min(Vmin, V); Vmax = Max(Vmax, V);
-        }
-        else {
-          Umin = Umax = U;
-          Vmin = Vmax = V;
-        }
-      }
-
-      if ( (Umax > Umin) && (Vmax > Vmin) )
-      {
-        gp_Pnt ViewDims = myCamera->ViewDimensions();
-        Standard_Real DxvOld = ViewDims.X();
-
-        Standard_Real Xrp, Yrp, DxvNew, DyvNew;
-
-        DxvNew = Abs(Umax - Umin); DyvNew = Abs(Vmax - Vmin);
-        DxvNew *= (1. + theCoef);
-        DyvNew *= (1. + theCoef);
-
-        Standard_Real aRatio = DxvNew / DxvOld;
-
-        Xrp = (Umin + Umax)/2. ; Yrp = (Vmin + Vmax)/2. ;
-        Umin = Xrp - DxvNew/2. ; Umax = Xrp + DxvNew/2. ;
-        Vmin = Yrp - DyvNew/2. ; Vmax = Yrp + DyvNew/2. ;
-
-        // fit view
-        FitAll (Umin, Vmin, Umax, Vmax);
-
-        // ratio 1e+6 often gives calculation error(s), reduce it
-        // if (aRatio < 1e+6) doFit = Standard_False;
-        if (aRatio < 100)
-        {
-          doFit = Standard_False;
-        }
-
-        aResult = Standard_True;
-      }
-      else
-      {
-        doFit = Standard_False;
-      }
-    }
-
-    if (!aResult)
-    {
-      myCamera->BeginUpdate();
-      myCamera->SetCenter (aCenterBefore);
-      myCamera->SetEye (anEyeBefore);
-      myCamera->EndUpdate();
-    }
-  }
+  ImmediateUpdate();
 
-  return aResult;
+  return Standard_True;
 }
 
 //=======================================================================
index 29b710b..6d4db6c 100644 (file)
@@ -32,6 +32,7 @@
 #include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_TextureEnv.hxx>
+#include <Graphic3d_Mat4d.hxx>
 
 IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
@@ -470,16 +471,15 @@ const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const H
 void OpenGl_View::GetMatrices (TColStd_Array2OfReal&  theMatOrient,
                                TColStd_Array2OfReal&  theMatMapping) const
 {
-  const OpenGl_Matrix* aProj =   (const OpenGl_Matrix*) &myCamera->ProjectionMatrix();
-  const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrix();
+  const Graphic3d_Mat4d& aProj   = myCamera->ProjectionMatrix();
+  const Graphic3d_Mat4d& aOrient = myCamera->OrientationMatrix();
 
-  int i, j;
-  for (i = 0; i < 4; ++i)
+  for (Standard_Integer aRow = 0; aRow < 4; ++aRow)
   {
-    for (j = 0; j < 4; ++j)
+    for (Standard_Integer aCol = 0; aCol < 4; ++aCol)
     {
-      theMatOrient  (i, j) = aOrient->mat[j][i];
-      theMatMapping (i, j) = aProj->  mat[j][i];
+      theMatOrient  (aRow, aCol) = aOrient.GetValue (aRow, aCol);
+      theMatMapping (aRow, aCol) = aProj  .GetValue (aRow, aCol);
     }
   }
 }
index e039bb6..9513ad8 100644 (file)
@@ -401,13 +401,13 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     if (myProjectionState != myCamera->ProjectionState())
     {
       myProjectionState = myCamera->ProjectionState();
-      aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrix().GetData());
+      aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
     }
 
     if (myModelViewState != myCamera->ModelViewState())
     {
       myModelViewState = myCamera->ModelViewState();
-      aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrix().GetData());
+      aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
     }
 
     if (aManager->ModelWorldState().Index() == 0)
@@ -515,9 +515,9 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
   {
     // single-pass monographic rendering
-    const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrix();
+    const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrixF();
 
-    const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrix();
+    const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
 
     // redraw scene with normal orientation and projection
     RedrawScene (thePrintContext, theWorkspace, aProj, aOrient);
@@ -525,9 +525,9 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   else
   {
     // two stereographic passes
-    const OpenGl_Matrix* aLProj  = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeft();
-    const OpenGl_Matrix* aRProj  = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRight();
-    const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrix();
+    const OpenGl_Matrix* aLProj  = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeftF();
+    const OpenGl_Matrix* aRProj  = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRightF();
+    const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
 
     // safely switch to left Eye buffer
     aContext->SetDrawBufferLeft();
index da93d7c..cda8f97 100644 (file)
 #include <gp_Ax2.hxx>
 #include <Geom_Circle.hxx>
 #include <AIS_Circle.hxx>
-#include <V3d_View.hxx>
 #include <TopoDS.hxx>
 #include <Geom_Plane.hxx>
 #include <gp_Pln.hxx>
 #include <AIS_AngleDimension.hxx>
 
+#include <Aspect_Window.hxx>
+#include <V3d_View.hxx>
+
 #include <TopExp_Explorer.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <GC_MakePlane.hxx>
@@ -163,66 +165,64 @@ static Standard_Integer  BUC60814(Draw_Interpretor& di, Standard_Integer argc, c
   return 0;
 }
 
-static Standard_Integer  BUC60774(Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
+//=======================================================================
+//function : BUC60774
+//purpose  : 
+//=======================================================================
+static Standard_Integer BUC60774 (Draw_Interpretor& theDi,
+                                  Standard_Integer theArgNb,
+                                  const char** theArgv)
 {
-  if(argc!=1)
+  if (theArgNb != 1)
   {
-    di << "Usage : " << argv[0] << "\n";
+    std::cout << "Usage : " << theArgv[0] << "\n";
     return -1;
   }
 
-  Handle(AIS_InteractiveContext) myAISContext = ViewerTest::GetAISContext();
-  if(myAISContext.IsNull()) 
+  const Handle(AIS_InteractiveContext)& anAISContext = ViewerTest::GetAISContext();
+  if (anAISContext.IsNull())
   {
-    di << "use 'vinit' command before " << argv[0] << "\n";
+    std::cout << "use 'vinit' command before " << theArgv[0] << "\n";
     return -1;
   }
 
-  Handle(V3d_View) myV3dView = ViewerTest::CurrentView();
-  
-  double Xc,Yc,Width, Height;
-  myV3dView->Center(Xc,Yc);
-  myV3dView-> Size (Width, Height);
-  
-  double Xmin,Ymin;
-  Xmin=Xc-Width/2;
-  Ymin=Yc-Height/2;
-  double Xmax,Ymax;
-  Xmax=Xc+Width/2;
-  Ymax=Yc+Height/2;
-    
-  Standard_Integer XPmin,YPmin;
-  myV3dView->Convert(Xmin,Ymin,XPmin,YPmin);
-//  cout<<Xmin<<"\t"<<Ymin<<endl;
-//  cout<<XPmin<<"\t"<<YPmin<<endl;
-
-  Standard_Integer XPmax,YPmax;
-  myV3dView->Convert(Xmax,Ymax,XPmax,YPmax);
-//  cout<<Xmax<<"\t"<<Ymax<<endl;
-//  cout<<XPmax<<"\t"<<YPmax<<endl;
-  
-  AIS_StatusOfPick status;
-  if ((status=myAISContext->Select(XPmin,YPmin,XPmax,YPmax,myV3dView))==AIS_SOP_NothingSelected)
-             di << "status = AIS_SOP_NothingSelected : OK"   << "\n";
-  else       di << "status = AIS_SOP_NothingSelected : bugged - Faulty "   << "\n";
-  
-  di.Eval("box b 10 10 10");
-  di.Eval(" vdisplay b");
+  const Handle(V3d_View)& aV3dView = ViewerTest::CurrentView();
 
-  if ((status=myAISContext->Select(XPmin,YPmin,XPmax,YPmax,myV3dView))==AIS_SOP_OneSelected)
-             di << "status = AIS_SOP_OneSelected : OK"   << "\n";
-  else       di << "status = AIS_SOP_OneSelected : bugged - Faulty "   << "\n";
+  Standard_Integer aWinWidth  = 0;
+  Standard_Integer aWinHeight = 0;
+  aV3dView->Window()->Size (aWinWidth, aWinHeight);
 
-  di.Eval("box w 20 20 20 20 20 20");
-  di.Eval(" vdisplay w");
+  Standard_Integer aXPixMin = 0;
+  Standard_Integer aYPixMin = 0;
+  Standard_Integer aXPixMax = aWinWidth;
+  Standard_Integer aYPixMax = aWinHeight;
 
-  if ((status=myAISContext->Select(XPmin,YPmin,XPmax,YPmax,myV3dView))==AIS_SOP_SeveralSelected)
-             di << "status = AIS_SOP_SeveralSelected : OK"   << "\n";
-  else       di << "status = AIS_SOP_SeveralSelected : bugged - Faulty "   << "\n";
-  
-  return 0;
+  AIS_StatusOfPick aPickStatus = anAISContext->Select (aXPixMin, aYPixMin, aXPixMax, aYPixMax, aV3dView);
+  theDi << (aPickStatus == AIS_SOP_NothingSelected
+    ? "status = AIS_SOP_NothingSelected : OK"
+    : "status = AIS_SOP_NothingSelected : bugged - Faulty ");
+  theDi << "\n";
+
+  theDi.Eval ("box b 10 10 10");
+  theDi.Eval (" vdisplay b");
 
-}  
+  aPickStatus = anAISContext->Select (aXPixMin, aYPixMin, aXPixMax, aYPixMax, aV3dView);
+  theDi << (aPickStatus == AIS_SOP_OneSelected
+    ? "status = AIS_SOP_OneSelected : OK"
+    : "status = AIS_SOP_OneSelected : bugged - Faulty ");
+  theDi << "\n";
+
+  theDi.Eval ("box w 20 20 20 20 20 20");
+  theDi.Eval (" vdisplay w");
+
+  aPickStatus = anAISContext->Select (aXPixMin, aYPixMin, aXPixMax, aYPixMax, aV3dView);
+  theDi << (aPickStatus == AIS_SOP_SeveralSelected
+    ? "status = AIS_SOP_SeveralSelected : OK"
+    : "status = AIS_SOP_SeveralSelected : bugged - Faulty ");
+  theDi << "\n";
+
+  return 0;
+}
 
 static Standard_Integer BUC60972 (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
 {
index 3c06dea..840afa5 100644 (file)
@@ -37,7 +37,8 @@ uses
     TopLoc,
     Geom,
     SelectBasics,
-    V3d
+    V3d,
+    Graphic3d
 
 is
     
index 38c84ea..b821f14 100644 (file)
@@ -45,169 +45,205 @@ uses
     Vec2d   from gp,
     Pnt2d   from gp,
     Box     from Bnd,
-    View    from V3d
+    View    from V3d,
+    Mat4    from Graphic3d,
+    Mat4d   from Graphic3d
 
 raises
     NoSuchObject from Standard
 
 is
 
-    Create(aView:View from V3d) returns Projector from Select3D;
-    --- Purpose: Constructs the 3D projector object defined by the 3D view aView.
-    Create returns Projector from Select3D;
+    Create (theView : View from V3d) returns Projector from Select3D;
+    --- Purpose: Constructs the 3D projector object from the passed view.
+    -- The projector captures current model-view and projection transformation
+    -- of the passed view.
 
-    Create(CS : Ax2 from gp)
-    ---Purpose: Creates an axonometric projector. <CS> represents viewing coordinate 
-    -- system and could be constructed from x direction, view plane normal direction, 
-    -- and view point location in world-coordinate space.
+    Create returns Projector from Select3D;
+    --- Purpose: Constructs identity projector.
+
+    Create (theCS : Ax2 from gp)
+    ---Purpose: Builds the Projector from the model-view transformation specified
+    -- by the passed viewing coordinate system <theCS>. The Projector has
+    -- identity projection transformation, is orthogonal.
+    -- The viewing coordinate system could be constructed from x direction,
+    -- view plane normal direction, and view point location in
+    -- world-coordinate space.
     returns Projector from Select3D;
 
-    Create(CS    : Ax2  from gp;
-           Focus : Real from Standard)
-    ---Purpose: Creates  a  perspective  projector. <CS> represents viewing
-    -- coordinate system and could be constructed from x direction, 
+    Create (theCS    : Ax2  from gp;
+            theFocus : Real from Standard)
+    ---Purpose: Builds the Projector from the model-view transformation specified
+    -- by the passed view coordinate system <theCS> and simplified perspective
+    -- projection transformation defined by <theFocus> parameter.
+    -- The viewing coordinate system could be constructed from x direction,
     -- view plane normal direction, and focal point location in world-coordinate
-    -- space. <Focus> should represent distance of an eye from view plane
+    -- space. <theFocus> should represent distance of an eye from view plane
     -- in world-coordinate space (focal distance).
     returns Projector from Select3D;
 
-    Create(T         : Trsf    from gp;
-           Persp     : Boolean from Standard;
-           Focus     : Real    from Standard)
-    ---Purpose: build a Projector from the given transformation.
-    -- In case, when <T> transformation should represent custom view projection,
-    -- it could be constructed from two separate components: transposed view
-    -- orientation matrix and translation of focal point in view-coordiante
-    -- system. <T> could be built up from x direction, up direction,
+    Create (theViewTrsf : Trsf    from gp;
+            theIsPersp  : Boolean from Standard;
+            theFocus    : Real    from Standard)
+    ---Purpose: Build the Projector from the model-view transformation passed
+    -- as <theViewTrsf> and simplified perspective projection transformation
+    -- parameters passed as <theIsPersp> and <theFocus>.
+    -- In case, when <theViewTrsf> transformation should represent custom view
+    -- projection, it could be constructed from two separate components:
+    -- transposed view orientation matrix and translation of focal point
+    -- in view-coordinate system.
+    -- <theViewTrsf> could be built up from x direction, up direction,
     -- view plane normal direction vectors and translation with SetValues(...)
     -- method, where first row arguments (a11, a12, a13, a14)  are x, y, z
     -- component of x direction vector, and x value of reversed translation
     -- vector. Second row arguments, are x y z for up direction and y value of
     -- reversed translation, and the third row defined in the same manner.
-    -- This also suits for simple perspective view, where <Focus> is the focale
-    -- distance of an eye from view plane in world-space coordiantes.
+    -- This also suits for simple perspective view, where <theFocus> is the focale
+    -- distance of an eye from view plane in world-space coordinates.
     -- Note, that in that case amount of perspective distortion (perspective
     -- angle) should be defined through focal distance.
     returns Projector from Select3D;
 
-    Create(GT        : GTrsf   from gp;
-           Persp     : Boolean from Standard;
-           Focus     : Real    from Standard)
-    ---Purpose: build a Projector from the given transformation.
-    -- In case, when <GT> transformation should represent custom view
+    Create (theViewTrsf : GTrsf   from gp;
+            theIsPersp  : Boolean from Standard;
+            theFocus    : Real    from Standard)
+    ---Purpose: Builds the Projector from the model-view transformation passed
+    -- as <theViewTrsf> and projection transformation for <theIsPersp> and
+    -- <theFocus> parameters.
+    -- In case, when <theViewTrsf> transformation should represent custom view
     -- projection, it could be constructed from two separate components:
     -- transposed view orientation matrix and translation of a focal point
     -- in view-coordinate system.
-    -- This also suits for perspective view, with <Focus> that could be
+    -- This also suits for perspective view, with <theFocus> that could be
     -- equal to distance from an eye to a view plane in 
     -- world-coordinates (focal distance).
     -- The 3x3 transformation matrix is built up from three vectors:
     -- x direction, up direction and view plane normal vectors, where each
-    -- vector is a matrix row. Then <GT> is constructed from matrix and
+    -- vector is a matrix row. Then <theViewTrsf> is constructed from matrix and
     -- reversed translation with methods SetTranslationPart(..) and
     -- SetVectorialPart(..).
     -- Note, that in that case amount of perspective distortion (perspective
     -- angle) should be defined through focal distance.
     returns Projector from Select3D;
 
+    Create (theViewTrsf : Mat4d from Graphic3d;
+            theProjTrsf : Mat4d from Graphic3d)
+    ---Purpose: Builds the Projector from the passed model-view <theViewTrsf>
+    -- and projection <theProjTrsf> transformation matrices.
+    returns Projector from Select3D;
+
     Set (me : mutable;
-         T         : Trsf    from gp;
-         Persp     : Boolean from Standard;
-         Focus     : Real    from Standard)
-    is static;
+         theViewTrsf : Trsf    from gp;
+         theIsPersp  : Boolean from Standard;
+         theFocus    : Real    from Standard);
+    ---Purpose: Sets new parameters for the Projector.
 
-    SetView(me : mutable; V : View from V3d);
-    ---Purpose: Sets the 3D view V used at the time of construction.
+    Set (me : mutable;
+         theViewTrsf : Mat4d from Graphic3d;
+         theProjTrsf : Mat4d from Graphic3d);
+    ---Purpose: Sets new parameters for the Projector.
+
+    SetView (me : mutable;
+             theView : View from V3d);
+    ---Purpose: Sets new parameters for the Projector
+    -- captured from the passed view.
+
+    Scaled (me : mutable; theToCheckOptimized : Boolean from Standard = Standard_False)
+    ---Purpose: Pre-compute inverse transformation and ensure whether it is possible
+    -- to use optimized transformation for the common view-orientation type or not
+    -- if <theToCheckOptimized> is TRUE.
+    is virtual;
 
-    View(me) returns any View from V3d;
-    ---Purpose: Returns the 3D view used at the time of construction.
-    ---C++: return const&
+    Perspective (me) returns Boolean
+    ---Purpose: Returns True if there is simplified perspective
+    -- projection approach is used. Distortion defined by Focus.
     ---C++: inline
-
-    Scaled(me : mutable; On : Boolean from Standard = Standard_False)
-    ---Purpose: to compute with the given scale and translation.
     is virtual;
 
-    Perspective(me) returns Boolean
-    ---Purpose: Returns True if there is a perspective transformation.
+    Focus (me) returns Real from Standard
+    ---Purpose: Returns the focal length of simplified perspective
+    -- projection approach. Raises program error exception if the
+    -- the projection transformation is not specified as simplified
+    -- Perspective (for example, custom projection transformation is defined
+    -- or the orthogonal Projector is defined).
     ---C++: inline
     is virtual;
 
-    Transformation(me) returns GTrsf from gp
-    ---Purpose: Returns the active transformation.
+    Projection (me) returns Mat4d from Graphic3d;
+    ---Purpose: Returns projection transformation. Please note that for
+    -- simplified perspective projection approach, defined by Focus, the
+    -- returned transformation is identity.
     ---C++: inline
     ---C++: return const &
-    is virtual;
 
-    InvertedTransformation(me) returns GTrsf from gp
-    ---Purpose: Returns the active inverted transformation.
+    Transformation (me) returns GTrsf from gp
+    ---Purpose: Returns the view transformation.
     ---C++: inline
     ---C++: return const &
     is virtual;
 
-    FullTransformation(me) returns Trsf from gp
-    ---Purpose: Returns the original transformation.
+    InvertedTransformation (me) returns GTrsf from gp
+    ---Purpose: Returns the inverted view transformation.
     ---C++: inline
     ---C++: return const &
     is virtual;
 
-    Focus(me) returns Real from Standard
-    ---Purpose: Returns the focal length.
+    FullTransformation (me) returns Trsf from gp
+    ---Purpose: Returns the uniform-scaled view transformation.
     ---C++: inline
-    raises
-        NoSuchObject from Standard -- if there is no perspective
+    ---C++: return const &
     is virtual;
 
-    Transform(me; D : in out Vec from gp)
+    Transform (me; theD : in out Vec from gp)
+    ---Purpose: Transforms the vector into view-coordinate space.
     ---C++: inline
     is virtual;
 
-    Transform(me; Pnt : in out Pnt from gp)
-        ---C++: inline
+    Transform (me; thePnt : in out Pnt from gp)
+    ---Purpose: Transforms the point into view-coordinate space.
+    ---C++: inline
     is virtual;
 
-    Project(me; P    :     Pnt   from gp;
-                Pout : out Pnt2d from gp)
-    ---Purpose: Transform and apply perspective if needed.
+    Project (me; theP : Pnt from gp; thePout : out Pnt2d from gp)
+    ---Purpose: Transforms the point into view-coordinate space
+    -- and applies projection transformation.
     is virtual;
 
-    Project(me; P     :     Pnt  from gp;
-                X,Y,Z : out Real from Standard)
-    ---Purpose: Transform and apply perspective if needed.
+    Project (me; theP : Pnt  from gp; theX, theY, theZ : out Real from Standard)
+    ---Purpose: Transforms the point into view-coordinate space
+    -- and applies projection transformation.
     is static;
 
-    Project(me; P     :     Pnt   from gp;
-                D1    :     Vec   from gp;
-                Pout  : out Pnt2d from gp;
-        D1out : out Vec2d from gp)
-    ---Purpose: Transform and apply perspective if needed.
+    Project (me; theP     : Pnt   from gp;
+                 theD1    : Vec from gp;
+                 thePout  : out Pnt2d from gp;
+                 theD1out : out Vec2d from gp)
+    ---Purpose: Transforms the point and vector passed from its location
+    -- into view-coordinate space and applies projection transformation.
     is virtual;
 
-    Shoot(me; X , Y : Real from Standard)
-    returns Lin from gp
-    ---Purpose: return a line going through the eye towards the
-    --          2d point <X,Y>.
+    Shoot (me; theX, theY : Real from Standard) returns Lin from gp
+    ---Purpose: Return projection line going through the 2d point <theX, theY>
     is virtual;
 
-    Transform(me; P : in out Pnt from gp;
-                  T : GTrsf from gp)
+    Transform(me; thePnt  : in out Pnt from gp;
+                  theTrsf : GTrsf from gp)
     ---C++: inline
     is virtual;
 
-    Transform(me; D : in out Lin from gp;
-                  T : GTrsf from gp)
+    Transform(me; theLin : in out Lin from gp;
+                  theTrsf : GTrsf from gp)
     ---C++: inline
     is virtual;
 
 fields
-    myType       : Integer from Standard;
 
+    myType       : Integer from Standard;
     myPersp      : Boolean from Standard is protected;
     myFocus      : Real    from Standard is protected;
-    myScaledTrsf : Trsf    from gp is protected;
     myGTrsf      : GTrsf   from gp is protected;
     myInvTrsf    : GTrsf   from gp is protected;
-
-    myView       : View    from V3d;
+    myScaledTrsf : Trsf    from gp is protected;
+    myProjTrsf   : Mat4d   from Graphic3d is protected;
 
 end Projector;
index 32e25c8..6b7eb65 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#define IMP240100      //GG
-//                     Change RefToPix()/Convert() to Project() method.
-
 #include <Select3D_Projector.ixx>
 #include <Precision.hxx>
 #include <gp_Ax3.hxx>
 #include <gp_Vec.hxx>
 #include <gp_Vec2d.hxx>
+#include <gp_Mat.hxx>
+#include <Graphic3d_Vec4.hxx>
+
+namespace
+{
+  //=======================================================================
+  //function : TrsfType
+  //purpose  :
+  //=======================================================================
+  static Standard_Integer TrsfType(const gp_GTrsf& theTrsf)
+  {
+    const gp_Mat& aMat = theTrsf.VectorialPart();
+    if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15)
+     && (Abs (aMat.Value (2, 2) - 1.0) < 1e-15)
+     && (Abs (aMat.Value (3, 3) - 1.0) < 1e-15))
+    {
+      return 1; // top
+    }
+    else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15)
+          && (Abs (aMat.Value (1, 2) + 0.5) < 1e-15)
+          && (Abs (aMat.Value (1, 3) - 0.5) < 1e-15)
+          && (Abs (aMat.Value (2, 1) - 0.7071067811865476) < 1e-15)
+          && (Abs (aMat.Value (2, 2) - 0.5) < 1e-15)
+          && (Abs (aMat.Value (2, 3) + 0.5) < 1e-15)
+          && (Abs (aMat.Value (3, 1)) < 1e-15)
+          && (Abs (aMat.Value (3, 2) - 0.7071067811865476) < 1e-15)
+          && (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15))
+    {
+      return 0; // inverse axo
+    }
+    else if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15)
+          && (Abs (aMat.Value (2, 3) - 1.0) < 1e-15)
+          && (Abs (aMat.Value (3, 2) + 1.0) < 1e-15))
+    {
+      return 2; // front
+    }
+    else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15)
+          && (Abs (aMat.Value (1, 2) - 0.7071067811865476) < 1e-15)
+          && (Abs (aMat.Value (1, 3)) < 1e-15)
+          && (Abs (aMat.Value (2, 1) + 0.5) < 1e-15)
+          && (Abs (aMat.Value (2, 2) - 0.5) < 1e-15)
+          && (Abs (aMat.Value (2, 3) - 0.7071067811865476) < 1e-15)
+          && (Abs (aMat.Value (3, 1) - 0.5) < 1e-15)
+          && (Abs (aMat.Value (3, 2) + 0.5) < 1e-15)
+          && (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15))
+    {
+      return 3; // axo
+    }
+
+    return -1;
+  }
+
+   //====== TYPE 0 (inverse axonometric)
+   // (0.7071067811865476, -0.5               ,  0.4999999999999999)
+   // (0.7071067811865475,  0.5000000000000001, -0.5              )
+   // (0.0,                 0.7071067811865475,  0.7071067811865476)
+
+   // ====== TYPE 1 (top)
+   // (1.0, 0.0, 0.0)
+   // (0.0, 1.0, 0.0)
+   // (0.0, 0.0, 1.0)
+
+   // ======= TYPE 2 (front)
+   // (1.0,  0.0                   , 0.0)
+   // (0.0,  1.110223024625157e-16 , 1.0)
+   // (0.0, -1.0                   , 1.110223024625157e-16)
+
+   // ======= TYPE 3 (axonometric)
+   // ( 0.7071067811865476, 0.7071067811865475, 0.0)
+   // (-0.5               , 0.5000000000000001, 0.7071067811865475)
+   // ( 0.4999999999999999, -0.5              , 0.7071067811865476)
+}
 
 // formula for derivating a perspective, from Mathematica
 
 //function : Select3D_Projector
 //purpose  :
 //=======================================================================
-
-Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou)
-  : myView (aViou)
+Select3D_Projector::Select3D_Projector (const Handle(V3d_View)& theView)
+: myPersp (Standard_False),
+  myFocus (0.0),
+  myType (-1)
 {
+  SetView (theView);
 }
 
 //=======================================================================
 //function : Select3D_Projector
 //purpose  :
 //=======================================================================
-
 Select3D_Projector::Select3D_Projector()
-: myPersp(Standard_False),
-  myFocus(0)
+: myPersp (Standard_False),
+  myFocus (0.0),
+  myType (-1)
 {
   Scaled();
 }
@@ -57,13 +128,13 @@ Select3D_Projector::Select3D_Projector()
 //function : Select3D_Projector
 //purpose  :
 //=======================================================================
-
-Select3D_Projector::Select3D_Projector (const gp_Ax2& CS)
-: myPersp(Standard_False),
-  myFocus(0)
+Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS)
+: myPersp (Standard_False),
+  myFocus (0.0),
+  myType (-1)
 {
-  myScaledTrsf.SetTransformation(CS);
-  myGTrsf.SetTrsf(myScaledTrsf);
+  myScaledTrsf.SetTransformation (theCS);
+  myGTrsf.SetTrsf (myScaledTrsf);
   Scaled();
 }
 
@@ -71,14 +142,13 @@ Select3D_Projector::Select3D_Projector (const gp_Ax2& CS)
 //function : Select3D_Projector
 //purpose  :
 //=======================================================================
-
-Select3D_Projector::Select3D_Projector (const gp_Ax2& CS,
-                                        const Standard_Real Focus)
-: myPersp(Standard_True),
-  myFocus(Focus)
+Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS, const Standard_Real theFocus)
+: myPersp (Standard_True),
+  myFocus (theFocus),
+  myType (-1)
 {
-  myScaledTrsf.SetTransformation(CS);
-  myGTrsf.SetTrsf(myScaledTrsf);
+  myScaledTrsf.SetTransformation (theCS);
+  myGTrsf.SetTrsf (myScaledTrsf);
   Scaled();
 }
 
@@ -86,15 +156,15 @@ Select3D_Projector::Select3D_Projector (const gp_Ax2& CS,
 //function : Select3D_Projector
 //purpose  :
 //=======================================================================
-
-Select3D_Projector::Select3D_Projector (const gp_Trsf& T,
-                                        const Standard_Boolean Persp,
-                                        const Standard_Real Focus)
-: myPersp(Persp),
-  myFocus(Focus),
-  myScaledTrsf(T)
+Select3D_Projector::Select3D_Projector (const gp_Trsf& theViewTrsf,
+                                        const Standard_Boolean theIsPersp,
+                                        const Standard_Real theFocus)
+: myPersp (theIsPersp),
+  myFocus (theFocus),
+  myGTrsf (theViewTrsf),
+  myScaledTrsf (theViewTrsf),
+  myType (-1)
 {
-  myGTrsf.SetTrsf(myScaledTrsf);
   Scaled();
 }
 
@@ -102,361 +172,300 @@ Select3D_Projector::Select3D_Projector (const gp_Trsf& T,
 //function : Select3D_Projector
 //purpose  :
 //=======================================================================
-
-Select3D_Projector::Select3D_Projector (const gp_GTrsf& GT,
-                                        const Standard_Boolean Persp,
-                                        const Standard_Real Focus)
-: myPersp(Persp),
-  myFocus(Focus),
-  myGTrsf(GT)
+Select3D_Projector::Select3D_Projector (const gp_GTrsf& theViewTrsf,
+                                        const Standard_Boolean theIsPersp,
+                                        const Standard_Real theFocus)
+: myPersp (theIsPersp),
+  myFocus (theFocus),
+  myGTrsf (theViewTrsf),
+  myScaledTrsf (theViewTrsf.Trsf()),
+  myType (-1)
 {
   Scaled();
 }
 
 //=======================================================================
-//function : Set
+//function : Select3D_Projector
 //purpose  :
 //=======================================================================
-
-void Select3D_Projector::Set
-  (const gp_Trsf& T,
-   const Standard_Boolean Persp,
-   const Standard_Real Focus)
+Select3D_Projector::Select3D_Projector (const Graphic3d_Mat4d& theViewTrsf,
+                                        const Graphic3d_Mat4d& theProjTrsf)
+: myPersp (Standard_False),
+  myFocus (0.0),
+  myType (-1)
 {
-  myPersp      = Persp;
-  myFocus      = Focus;
-  myScaledTrsf = T;
-  Scaled();
+  Set (theViewTrsf, theProjTrsf);
 }
 
 //=======================================================================
-//function : Scaled
+//function : Set
 //purpose  :
 //=======================================================================
-
-#include <gp_Mat.hxx>
-
-static Standard_Integer TrsfType(const gp_GTrsf& Trsf) {
-  const gp_Mat& Mat = Trsf.VectorialPart();
-  if(   (Abs(Mat.Value(1,1)-1.0) < 1e-15)
-     && (Abs(Mat.Value(2,2)-1.0) < 1e-15)
-     && (Abs(Mat.Value(3,3)-1.0) < 1e-15)) {
-    return(1); //-- top
-  }
-  else if(   (Abs(Mat.Value(1,1)-0.7071067811865476) < 1e-15)
-         && (Abs(Mat.Value(1,2)+0.5) < 1e-15)
-         && (Abs(Mat.Value(1,3)-0.5) < 1e-15)
-
-         && (Abs(Mat.Value(2,1)-0.7071067811865476) < 1e-15)
-         && (Abs(Mat.Value(2,2)-0.5) < 1e-15)
-         && (Abs(Mat.Value(2,3)+0.5) < 1e-15)
-
-         && (Abs(Mat.Value(3,1)) < 1e-15)
-         && (Abs(Mat.Value(3,2)-0.7071067811865476) < 1e-15)
-         && (Abs(Mat.Value(3,3)-0.7071067811865476) < 1e-15)) {
-    return(0); //--
-  }
-  else if(   (Abs(Mat.Value(1,1)-1.0) < 1e-15)
-         && (Abs(Mat.Value(2,3)-1.0) < 1e-15)
-         && (Abs(Mat.Value(3,2)+1.0) < 1e-15)) {
-    return(2); //-- front
-  }
-  else if(   (Abs(Mat.Value(1,1)-0.7071067811865476) < 1e-15)
-         && (Abs(Mat.Value(1,2)-0.7071067811865476) < 1e-15)
-         && (Abs(Mat.Value(1,3)) < 1e-15)
-
-         && (Abs(Mat.Value(2,1)+0.5) < 1e-15)
-         && (Abs(Mat.Value(2,2)-0.5) < 1e-15)
-         && (Abs(Mat.Value(2,3)-0.7071067811865476) < 1e-15)
-
-         && (Abs(Mat.Value(3,1)-0.5) < 1e-15)
-         && (Abs(Mat.Value(3,2)+0.5) < 1e-15)
-         && (Abs(Mat.Value(3,3)-0.7071067811865476) < 1e-15)) {
-    return(3); //-- axo
-  }
-  return(-1);
+void Select3D_Projector::Set (const gp_Trsf& theViewTrsf,
+                              const Standard_Boolean theIsPersp,
+                              const Standard_Real theFocus)
+{
+  myPersp      = theIsPersp;
+  myFocus      = theFocus;
+  myScaledTrsf = theViewTrsf;
+  myProjTrsf.InitIdentity();
+  Scaled();
 }
 
-void Select3D_Projector::Scaled (const Standard_Boolean On)
+//=======================================================================
+//function : Set
+//purpose  :
+//=======================================================================
+void Select3D_Projector::Set (const Graphic3d_Mat4d& theViewTrsf,
+                              const Graphic3d_Mat4d& theProjTrsf)
 {
-  myType=-1;
-  if (!On) {
-    if (!myPersp) {
-      //myGTrsf.SetTranslationPart(gp_XYZ(0.,0.,0.));
-      myType=TrsfType(myGTrsf);
+  // Copy elements corresponding to common view-transformation
+  for (Standard_Integer aRowIt = 0; aRowIt < 3; ++aRowIt)
+  {
+    for (Standard_Integer aColIt = 0; aColIt < 4; ++aColIt)
+    {
+      myGTrsf.SetValue (aRowIt + 1, aColIt + 1, theViewTrsf.GetValue (aRowIt, aColIt));
     }
   }
-  myInvTrsf = myGTrsf;
-  myInvTrsf.Invert();
+
+  // Adapt scaled transformation for compatibilty
+  gp_Dir aViewY (theViewTrsf.GetValue (0, 1), theViewTrsf.GetValue (1, 1), theViewTrsf.GetValue (2, 1));
+  gp_Dir aViewZ (theViewTrsf.GetValue (0, 2), theViewTrsf.GetValue (1, 2), theViewTrsf.GetValue (2, 2));
+  gp_XYZ aViewT (theViewTrsf.GetValue (0, 3), theViewTrsf.GetValue (1, 3), theViewTrsf.GetValue (2, 3));
+  gp_Dir aViewX = aViewY ^ aViewZ;
+  gp_Ax3 aViewAx3 (gp_Pnt (aViewT), aViewZ, aViewX);
+  myScaledTrsf.SetTransformation (aViewAx3);
+
+  myPersp    = Standard_False;
+  myFocus    = 0.0;
+  myProjTrsf = theProjTrsf;
+  Scaled();
 }
 
 //=======================================================================
-//function : Project
+//function : SetView
 //purpose  :
 //=======================================================================
-
-void Select3D_Projector::Project (const gp_Pnt& P, gp_Pnt2d& Pout) const
+void Select3D_Projector::SetView (const Handle(V3d_View)& theView)
 {
+  const Graphic3d_Mat4d& aViewTrsf = theView->Camera()->OrientationMatrix();
+  const Graphic3d_Mat4d& aProjTrsf = theView->Camera()->ProjectionMatrix();
 
-  if(!myView.IsNull()){
-    Standard_Real Xout,Yout;
-//    V3d_View
-#ifdef IMP240100
-    myView->Project(P.X(),P.Y(),P.Z(),Xout,Yout);
-#else
-    Standard_Integer Xp,Yp;
-    myView->RefToPix(P.X(),P.Y(),P.Z(),Xp,Yp);
-    myView->Convert(Xp,Yp,Xout,Yout);
-#endif
-    Pout.SetCoord(Xout,Yout);
-  }
-  else{
-    if(myType!=-1) {
-      Standard_Real X,Y;
-      switch (myType) {
-      case 0: {  //-- axono standard
-       Standard_Real x07 = P.X()*0.7071067811865475;
-       Standard_Real y05 = P.Y()*0.5;
-       Standard_Real z05 = P.Z()*0.5;
-       X=x07-y05+z05;
-       Y=x07+y05-z05;
-       //-- Z=0.7071067811865475*(P.Y()+P.Z());
-       break;
-      }
-      case 1: { //-- top
-       X=P.X(); Y=P.Y(); //-- Z=P.Z();
-       Pout.SetCoord(X,Y);
-       break;
-      }
-      case 2: {
-       X=P.X(); Y=P.Z(); //-- Z=-P.Y();
-       Pout.SetCoord(X,Y);
-       break;
-      }
-      case 3: {
-       Standard_Real xmy05 = (P.X()-P.Y())*0.5;
-       Standard_Real z07 = P.Z()*0.7071067811865476;
-       X=0.7071067811865476*(P.X()+P.Y());
-       Y=-xmy05+z07;
-       Pout.SetCoord(X,Y);
-       //-- Z= xmy05+z07;
-       break;
-      }
-      default: {
-       gp_Pnt P2 = P;
-       Transform(P2);
-       if (myPersp) {
-         Standard_Real R = 1.-P2.Z()/myFocus;
-         Pout.SetCoord(P2.X()/R,P2.Y()/R);
-       }
-       else
-         Pout.SetCoord(P2.X(),P2.Y());
-       break;
-      }
-      }
-    }
-    else {
-      gp_Pnt P2 = P;
-      Transform(P2);
-      if (myPersp) {
-       Standard_Real R = 1.-P2.Z()/myFocus;
-       Pout.SetCoord(P2.X()/R,P2.Y()/R);
-      }
-      else
-       Pout.SetCoord(P2.X(),P2.Y());
-    }
-  }
-
+  gp_XYZ aFrameScale = theView->Camera()->ViewDimensions();
+  Graphic3d_Mat4d aScale;
+  aScale.ChangeValue (0, 0) = aFrameScale.X();
+  aScale.ChangeValue (1, 1) = aFrameScale.Y();
+  aScale.ChangeValue (2, 2) = aFrameScale.Z();
+  Graphic3d_Mat4d aScaledProjTrsf = aScale * aProjTrsf;
 
+  Set (aViewTrsf, aScaledProjTrsf);
 }
 
 //=======================================================================
-//function : Project
+//function : Scaled
 //purpose  :
 //=======================================================================
-/*  ====== TYPE 0  (??)
-   (0.7071067811865476, -0.5               ,  0.4999999999999999)
-   (0.7071067811865475,  0.5000000000000001, -0.5              )
-   (0.0,                 0.7071067811865475,  0.7071067811865476)
-
-  ====== TYPE 1 (top)
-(1.0, 0.0, 0.0)
-(0.0, 1.0, 0.0)
-(0.0, 0.0, 1.0)
-
- ======= TYPE 2 (front)
-(1.0,  0.0                   , 0.0)
-(0.0,  1.110223024625157e-16 , 1.0)
-(0.0, -1.0                   , 1.110223024625157e-16)
-
- ======= TYPE 3
-( 0.7071067811865476, 0.7071067811865475, 0.0)
-(-0.5               , 0.5000000000000001, 0.7071067811865475)
-( 0.4999999999999999, -0.5              , 0.7071067811865476)
-*/
-void Select3D_Projector::Project (const gp_Pnt& P,
-                                Standard_Real& X,
-                                Standard_Real& Y,
-                                Standard_Real& Z) const
+void Select3D_Projector::Scaled (const Standard_Boolean theToCheckOptimized)
 {
-  if(!myView.IsNull()){
-//    Standard_Real Xout,Yout;
-//    V3d_View
-#ifdef IMP240100
-    myView->Project(P.X(),P.Y(),P.Z(),X,Y);
-#else
-    Standard_Integer Xp,Yp;
-    myView->RefToPix(P.X(),P.Y(),P.Z(),Xp,Yp);
-    myView->Convert(Xp,Yp,X,Y);
-#endif
-  }
-  else{
-    if(myType!=-1) {
-      switch (myType) {
-      case 0: {  //-- axono standard
-       Standard_Real x07 = P.X()*0.7071067811865475;
-       Standard_Real y05 = P.Y()*0.5;
-       Standard_Real z05 = P.Z()*0.5;
-       X=x07-y05+z05;
-       Y=x07+y05-z05;
-       Z=0.7071067811865475*(P.Y()+P.Z());
-       break;
-      }
-      case 1: { //-- top
-       X=P.X(); Y=P.Y(); Z=P.Z();
-       break;
-      }
-      case 2: {
-       X=P.X(); Y=P.Z(); Z=-P.Y();
-       break;
-      }
-      case 3: {
-       Standard_Real xmy05 = (P.X()-P.Y())*0.5;
-       Standard_Real z07 = P.Z()*0.7071067811865476;
-       X=0.7071067811865476*(P.X()+P.Y());
-       Y=-xmy05+z07;
-       Z= xmy05+z07;
-       break;
-      }
-      default: {
-       gp_Pnt P2 = P;
-       Transform(P2);
-       P2.Coord(X,Y,Z);
-       break;
-      }
-      }
-    }
-    else {
-      gp_Pnt P2 = P;
-      Transform(P2);
-      P2.Coord(X,Y,Z);
-      if (myPersp) {
-       Standard_Real R = 1 - Z / myFocus;
-       X = X / R;
-       Y = Y / R;
-      }
-    }
+  myType = -1;
+
+  if (!theToCheckOptimized && !myPersp && myProjTrsf.IsIdentity())
+  {
+    myType = TrsfType (myGTrsf);
   }
+
+  myInvTrsf = myGTrsf.Inverted();
 }
+
 //=======================================================================
 //function : Project
 //purpose  :
 //=======================================================================
-
-void Select3D_Projector::Project (const gp_Pnt& P,
-                                const gp_Vec& D1,
-                                gp_Pnt2d& Pout,
-                                gp_Vec2d& D1out) const
+void Select3D_Projector::Project (const gp_Pnt& theP, gp_Pnt2d& thePout) const
 {
-  gp_Pnt PP = P;
-  Transform(PP);
-  gp_Vec DD1 = D1;
-  Transform(DD1);
-  if (myPersp) {
-    Standard_Real R = 1. - PP.Z() / myFocus;
-    Pout .SetCoord(PP .X()/R , PP.Y()/R);
-    D1out.SetCoord(DD1.X()/R + PP.X()*DD1.Z()/(myFocus * R*R),
-                  DD1.Y()/R + PP.Y()*DD1.Z()/(myFocus * R*R));
-  }
-  else {
-    Pout .SetCoord(PP .X(),PP .Y());
-    D1out.SetCoord(DD1.X(),DD1.Y());
-  }
+  Standard_Real aXout = 0.0;
+  Standard_Real aYout = 0.0;
+  Standard_Real aZout = 0.0;
+  Project (theP, aXout, aYout, aZout);
+  thePout.SetCoord (aXout, aYout);
 }
 
-
 //=======================================================================
-//function : Shoot
+//function : Project
 //purpose  :
 //=======================================================================
-
-gp_Lin Select3D_Projector::Shoot
-  (const Standard_Real X,
-   const Standard_Real Y) const
+void Select3D_Projector::Project (const gp_Pnt& theP,
+                                  Standard_Real& theX,
+                                  Standard_Real& theY,
+                                  Standard_Real& theZ) const
 {
-  gp_Lin L;
+  Graphic3d_Vec4d aTransformed (0.0, 0.0, 0.0, 1.0);
 
-  if (!myView.IsNull())
+  // view transformation
+  switch (myType)
   {
-    Handle(Graphic3d_Camera) aCamera = myView->Camera();
-
-    Standard_Real aUMin, aVMin, aUMax, aVMax;  
-    aCamera->WindowLimit (aUMin, aVMin, aUMax, aVMax);
+    case 0 : // inverse axo
+    {
+      Standard_Real aX07 = theP.X() * 0.7071067811865475;
+      Standard_Real aY05 = theP.Y() * 0.5;
+      Standard_Real aZ05 = theP.Z() * 0.5;
+      aTransformed.x() = aX07 - aY05 + aZ05;
+      aTransformed.y() = aX07 + aY05 - aZ05;
+      aTransformed.z() = 0.7071067811865475 * (theP.Y() + theP.Z());
+      break;
+    }
 
-    gp_Pnt aPos = aCamera->ConvertView2World (gp_Pnt (X, Y, 1.0));
-    gp_Pnt aEyePos = aCamera->Eye();
+    case 1 : // top
+    {
+      aTransformed.x() = theP.X();
+      aTransformed.y() = theP.Y();
+      aTransformed.z() = theP.Z();
+      break;
+    }
 
-    gp_Dir aDir;
+    case 2 : // front
+    {
+      aTransformed.x() =  theP.X();
+      aTransformed.y() =  theP.Z();
+      aTransformed.z() = -theP.Y();
+      break;
+    }
 
-    if (aCamera->IsOrthographic())
+    case 3 : // axo
     {
-      aDir = aCamera->Direction();
+      Standard_Real aXmy05 = (theP.X() - theP.Y()) * 0.5;
+      Standard_Real aZ07 = theP.Z() * 0.7071067811865476;
+      aTransformed.x() = 0.7071067811865476 * (theP.X() + theP.Y());
+      aTransformed.y() = -aXmy05 + aZ07;
+      aTransformed.z() =  aXmy05 + aZ07;
+      break;
     }
-    else
+
+    default :
     {
-      aDir = gp_Dir (aPos.X() - aEyePos.X(),
-                     aPos.Y() - aEyePos.Y(), 
-                     aPos.Z() - aEyePos.Z());
+      gp_Pnt aTransformPnt = theP;
+      Transform (aTransformPnt);
+      aTransformed.x() = aTransformPnt.X();
+      aTransformed.y() = aTransformPnt.Y();
+      aTransformed.z() = aTransformPnt.Z();
     }
+  }
 
-    L = gp_Lin (aPos, aDir);
+  // projection transformation
+  if (myPersp)
+  {
+    // simplified perspective
+    Standard_Real aDistortion = 1.0 - aTransformed.z() / myFocus;
+    theX = aTransformed.x() / aDistortion;
+    theY = aTransformed.y() / aDistortion;
+    theZ = aTransformed.z();
+    return;
   }
-  else
+
+  if (myProjTrsf.IsIdentity())
   {
-     if (myPersp) {
-       L = gp_Lin(gp_Pnt(0,0, myFocus),
-                  gp_Dir(X,Y,-myFocus));
-     }
-     else {
-       L = gp_Lin(gp_Pnt(X,Y,0),
-                  gp_Dir(0,0,-1));
-     }
-
-     Transform(L, myInvTrsf);
+    // no projection transformation
+    theX = aTransformed.x();
+    theY = aTransformed.y();
+    theZ = aTransformed.z();
+    return;
   }
 
+  Graphic3d_Vec4d aProjected = myProjTrsf * aTransformed;
 
-  return L;
+  theX = aProjected.x() / aProjected.w();
+  theY = aProjected.y() / aProjected.w();
+  theZ = aProjected.z() / aProjected.w();
 }
 
+//=======================================================================
+//function : Project
+//purpose  :
+//=======================================================================
+void Select3D_Projector::Project (const gp_Pnt& theP,
+                                  const gp_Vec& theD1,
+                                  gp_Pnt2d& thePout,
+                                  gp_Vec2d& theD1out) const
+{
+  // view transformation
+  gp_Pnt aTP = theP;
+  Transform (aTP);
 
-void Select3D_Projector::SetView(const Handle(V3d_View)& aViou)
+  gp_Vec aTD1 = theD1;
+  Transform (aTD1);
+
+  // projection transformation
+  if (myPersp)
+  {
+    // simplified perspective
+    Standard_Real aDist = 1.0 - aTP.Z() / myFocus;
+    thePout.SetCoord (aTP.X() / aDist, aTP.Y() / aDist);
+    theD1out.SetCoord (aTD1.X() / aDist + aTP.X() * aTD1.Z() / (myFocus * aDist * aDist),
+                       aTD1.Y() / aDist + aTP.Y() * aTD1.Z() / (myFocus * aDist * aDist));
+    return;
+  }
+
+  if (myProjTrsf.IsIdentity())
+  {
+    // no projection transformation
+    thePout.SetCoord (aTP.X(), aTP.Y());
+    theD1out.SetCoord (aTD1.X(), aTD1.Y());
+  }
+
+  Graphic3d_Vec4d aTransformedPnt1 (aTP.X(), aTP.Y(), aTP.Z(), 1.0);
+  Graphic3d_Vec4d aTransformedPnt2 (aTP.X() + aTD1.X(), aTP.Y() + aTD1.Y(), aTP.Z() + aTD1.Z(), 1.0);
+
+  Graphic3d_Vec4d aProjectedPnt1 = myProjTrsf * aTransformedPnt1;
+  Graphic3d_Vec4d aProjectedPnt2 = myProjTrsf * aTransformedPnt2;
+
+  aProjectedPnt1 /= aProjectedPnt1.w();
+  aProjectedPnt2 /= aProjectedPnt2.w();
+
+  Graphic3d_Vec4d aProjectedD1 = aProjectedPnt2 - aProjectedPnt1;
+
+  thePout.SetCoord (aProjectedPnt1.x(), aProjectedPnt1.y());
+  theD1out.SetCoord (aProjectedD1.x(), aProjectedD1.y());
+}
+
+//=======================================================================
+//function : Shoot
+//purpose  :
+//=======================================================================
+gp_Lin Select3D_Projector::Shoot (const Standard_Real theX, const Standard_Real theY) const
 {
-  myView = aViou;
-  myPersp = aViou->Type()==V3d_PERSPECTIVE;
-  myFocus= aViou->Focale();
-  Standard_Real Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ;
-  //Standard_Boolean Pers=Standard_False;
-
-  aViou->At(Xat,Yat,Zat);
-  aViou->Up(XUp,YUp,ZUp);
-  aViou->Proj(DX,DY,DZ);
-  gp_Pnt At (Xat,Yat,Zat);
-  gp_Dir Zpers (DX,DY,DZ);
-  gp_Dir Ypers (XUp,YUp,ZUp);
-  gp_Dir Xpers = Ypers.Crossed(Zpers);
-  gp_Ax3 Axe (At, Zpers, Xpers);
-  myScaledTrsf.SetTransformation(Axe);
-  Scaled();
+  gp_Lin aViewLin;
+
+  if (myPersp)
+  {
+    // simplified perspective
+    aViewLin = gp_Lin (gp_Pnt (0.0, 0.0, myFocus), gp_Dir (theX, theY, -myFocus));
+  }
+  else if (myProjTrsf.IsIdentity())
+  {
+    // no projection transformation
+    aViewLin = gp_Lin (gp_Pnt (theX, theY, 0.0), gp_Dir (0.0, 0.0, -1.0));
+  }
+  else
+  {
+    // get direction of projection over the point in view space
+    Graphic3d_Mat4d aProjInv;
+    if (!myProjTrsf.Inverted (aProjInv))
+    {
+      return gp_Lin();
+    }
+
+    Graphic3d_Vec4d aVPnt1 = aProjInv * Graphic3d_Vec4d (theX, theY, 0.0, 1.0);
+    Graphic3d_Vec4d aVPnt2 = aProjInv * Graphic3d_Vec4d (theX, theY, 10.0, 1.0);
+    aVPnt1 /= aVPnt1.w();
+    aVPnt2 /= aVPnt1.w();
+
+    gp_Vec aViewDir (aVPnt2.x() - aVPnt1.x(), aVPnt2.y() - aVPnt1.y(), aVPnt2.z() - aVPnt1.z());
+
+    aViewLin = gp_Lin (gp_Pnt (aVPnt1.x(), aVPnt1.y(), aVPnt1.z()), gp_Dir (aViewDir));
+  }
+
+  // view transformation
+  Transform (aViewLin, myInvTrsf);
 
+  return aViewLin;
 }
index 2dfca5e..f62cf41 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Standard_NoSuchObject.hxx>
+#include <Graphic3d_Mat4d.hxx>
+#include <Standard_Assert.hxx>
 #include <gp_Vec.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Lin.hxx>
-#include <V3d_View.hxx>
-#include <V3d.hxx>
 
 //=======================================================================
 //function : Perspective
 //purpose  :
 //=======================================================================
-
 inline Standard_Boolean Select3D_Projector::Perspective() const
-{ return myPersp; }
+{
+  return myPersp;
+}
 
 //=======================================================================
-//function : Transformation
+//function : ProjectionTransformation
 //purpose  :
 //=======================================================================
+inline const Graphic3d_Mat4d& Select3D_Projector::Projection() const
+{
+  return myProjTrsf;
+}
 
+//=======================================================================
+//function : Transformation
+//purpose  :
+//=======================================================================
 inline const gp_GTrsf& Select3D_Projector::Transformation() const
-{ return myGTrsf; }
+{
+  return myGTrsf;
+}
 
 //=======================================================================
 //function : InvertedTransformation
 //purpose  :
 //=======================================================================
-
 inline const gp_GTrsf& Select3D_Projector::InvertedTransformation() const
-{ return myInvTrsf; }
+{
+  return myInvTrsf;
+}
 
 //=======================================================================
 //function : FullTransformation
 //purpose  :
 //=======================================================================
-
 inline const gp_Trsf& Select3D_Projector::FullTransformation() const
-{ return myScaledTrsf; }
+{
+  return myScaledTrsf;
+}
 
 //=======================================================================
 //function : Focus
 //purpose  :
 //=======================================================================
-
 inline Standard_Real Select3D_Projector::Focus() const
 {
-  Standard_NoSuchObject_Raise_if(!myPersp,
-                                "Select3D_Projector::Not a Perpective");
+  Standard_ASSERT_RAISE (myPersp, "Not a simplified Perspective.");
   return myFocus;
 }
 
@@ -69,55 +79,67 @@ inline Standard_Real Select3D_Projector::Focus() const
 //function : Transform
 //purpose  :
 //=======================================================================
-
-inline void Select3D_Projector::Transform (gp_Vec& D) const
+inline void Select3D_Projector::Transform (gp_Vec& theD) const
 {
-  gp_XYZ coord = D.XYZ();
-  if (myGTrsf.Form() == gp_Identity || myGTrsf.Form() == gp_Translation) { }
-  else if (myGTrsf.Form() == gp_PntMirror) { coord.Reverse(); }
-  else { coord.Multiply (myGTrsf.VectorialPart()); }
-  D.SetXYZ(coord);
+  gp_XYZ aXYZ = theD.XYZ();
+
+  if (myGTrsf.Form() == gp_PntMirror)
+  {
+    aXYZ.Reverse();
+  }
+  else if (myGTrsf.Form() != gp_Identity && myGTrsf.Form() != gp_Translation)
+  {
+    aXYZ.Multiply (myGTrsf.VectorialPart());
+  }
+
+  theD.SetXYZ (aXYZ);
 }
 
 //=======================================================================
 //function : Transform
 //purpose  :
 //=======================================================================
-
-inline void Select3D_Projector::Transform (gp_Pnt& Pnt) const
+inline void Select3D_Projector::Transform (gp_Pnt& thePnt) const
 {
-  gp_XYZ xyz = Pnt.XYZ();
-  myGTrsf.Transforms(xyz);
-  Pnt = gp_Pnt(xyz);
+  Transform (thePnt, myGTrsf);
 }
 
-
-inline const Handle(V3d_View)& Select3D_Projector::View() const
-{return myView;}
-
-inline void Select3D_Projector::Transform (gp_Lin& Lin, const gp_GTrsf& T) const
+//=======================================================================
+//function : Transform
+//purpose  :
+//=======================================================================
+inline void Select3D_Projector::Transform (gp_Lin& theLin, const gp_GTrsf& theTrsf) const
 {
-  gp_Ax1 ax1 = Lin.Position();
-  gp_XYZ xyz = ax1.Location().XYZ();
-  T.Transforms(xyz);
-  ax1.SetLocation(gp_Pnt(xyz));
-  gp_Dir dir = ax1.Direction();
-  gp_XYZ coord = dir.XYZ();
-  if (T.Form() == gp_Identity ||  T.Form() == gp_Translation)    { }
-  else if (T.Form() == gp_PntMirror) { coord.Reverse(); }
-  else {
-    coord.Multiply (T.VectorialPart());
-    Standard_Real D = coord.Modulus();
-    coord.Divide(D);
+  gp_Ax1 anAx1 = theLin.Position();
+  gp_XYZ aXYZ = anAx1.Location().XYZ();
+  theTrsf.Transforms (aXYZ);
+  anAx1.SetLocation (gp_Pnt (aXYZ));
+  gp_Dir aDir = anAx1.Direction();
+  gp_XYZ aDirXYZ = aDir.XYZ();
+
+  if (theTrsf.Form() == gp_PntMirror) 
+  {
+    aDirXYZ.Reverse();
   }
-  dir.SetXYZ(coord);
-  ax1.SetDirection(dir);
-  Lin.SetPosition(ax1);
+  else if (theTrsf.Form() != gp_Identity && theTrsf.Form() != gp_Translation)
+  {
+    aDirXYZ.Multiply (theTrsf.VectorialPart());
+    Standard_Real aModulus = aDirXYZ.Modulus();
+    aDirXYZ.Divide (aModulus);
+  }
+
+  aDir.SetXYZ (aDirXYZ);
+  anAx1.SetDirection (aDir);
+  theLin.SetPosition (anAx1);
 }
 
-inline void Select3D_Projector::Transform (gp_Pnt& Pnt, const gp_GTrsf& T) const
+//=======================================================================
+//function : Transform
+//purpose  :
+//=======================================================================
+inline void Select3D_Projector::Transform (gp_Pnt& thePnt, const gp_GTrsf& theTrsf) const
 {
-  gp_XYZ xyz = Pnt.XYZ();
-  T.Transforms(xyz);
-  Pnt = gp_Pnt(xyz);
+  gp_XYZ aXYZ = thePnt.XYZ();
+  theTrsf.Transforms (aXYZ);
+  thePnt = gp_Pnt (aXYZ);
 }
index 68b447d..dbee19e 100644 (file)
 -- Alternatively, this file may be used under the terms of Open CASCADE
 -- commercial license or contractual agreement.
 
--- Modified by rob jun 25 98 : Add Method : Reactivate projector...            
-
-
+-- Modified by rob jun 25 98 : Add Method : Reactivate projector...
 
 class ViewerSelector3d from StdSelect inherits ViewerSelector from SelectMgr
 
-       ---Purpose: Selector Usable by Viewers from V3d 
-       --          
+    ---Purpose: Selector Usable by Viewers from V3d
 
 uses
     View                 from V3d,
@@ -34,119 +31,108 @@ uses
     Array1OfReal         from TColStd, 
     Array1OfPnt2d        from TColgp,
     SensitivityMode      from StdSelect,
-    Lin                  from gp
+    Lin                  from gp,
+    Pnt                  from gp,
+    Dir                  from gp,
+    XYZ                  from gp
 
 is
 
     Create  returns mutable ViewerSelector3d from StdSelect;
-       ---Purpose: Constructs an empty 3D selector object.
-    Create(aProj : Projector from Select3D) returns mutable ViewerSelector3d from StdSelect;
-       ---Purpose: Constructs a 3D selector object defined by the projector aProj. 
+    ---Purpose: Constructs an empty 3D selector object.
 
-    Convert(me:mutable;aSelection:mutable Selection from SelectMgr)
+    Create (theProj : Projector from Select3D) returns mutable ViewerSelector3d from StdSelect;
+    ---Purpose: Constructs a 3D selector object defined by the projector <theProj>.
+
+    Convert (me : mutable; theSel : mutable Selection from SelectMgr)
     is redefined static;
-       ---Level: Public 
-       ---Purpose: Processes the projection of the sensitive  primitives
-       --          in the active view ; to be done before the selection action...
+        ---Level: Public 
+        ---Purpose: Processes the projection of the sensitive  primitives
+        --          in the active view ; to be done before the selection action...
 
+    Set (me : mutable; theProj : Projector from Select3D) is static;
+    ---Purpose: Sets the new projector <theProj> to replace the one used at construction time.
 
-    Set(me:mutable; aProj: Projector from Select3D) is static;
-       ---Purpose: Sets the new projector aProj to replace the one used at construction time.
-    
-
-    SetSensitivityMode(me    : mutable;
-                       aMode : SensitivityMode from StdSelect) is static;
+    SetSensitivityMode (me      : mutable;
+                        theMode : SensitivityMode from StdSelect) is static;
         ---Purpose: Sets the selection sensitivity mode. SM_WINDOW mode
         -- uses the specified pixel tolerance to compute the sensitivity
         -- value, SM_VIEW mode allows to define the sensitivity manually.
 
-    SensitivityMode(me) returns SensitivityMode from StdSelect;
+    SensitivityMode (me) returns SensitivityMode from StdSelect;
         ---C++: inline
         ---Purpose: Returns the selection sensitivity mode.
 
-    SetPixelTolerance(me         : mutable;
-                      aTolerance : Integer) is static;
-       ---Purpose: Sets the pixel tolerance aTolerance.
+    SetPixelTolerance (me           : mutable;
+                       theTolerance : Integer) is static;
+    ---Purpose: Sets the pixel tolerance <theTolerance>.
 
-    PixelTolerance(me) returns Integer from Standard;
+    PixelTolerance (me) returns Integer from Standard;
         ---C++: inline
         ---Purpose: Returns the pixel tolerance.
 
+    Pick (me           : mutable; theXPix, theYPix : Integer;
+          theView      : View from V3d) is static;
+    ---Level: Public 
+    ---Purpose: Picks the sensitive entity at the pixel coordinates of
+    -- the mouse <theXPix> and <theYPix>. The selector looks for touched areas and owners.
 
-    Pick (me           : mutable;XPix,YPix:Integer;
-         aView        : View from V3d) is static;
-       ---Level: Public 
-       ---Purpose: Picks the sensitive entity at the pixel coordinates of
-       -- the mouse Xpix and Ypix.   The selector looks for touched areas and owners.
-
-
-    Pick (me:mutable;XPMin,YPMin,XPMax,YPMax:Integer;aView:View from V3d) is static;
-       ---Purpose: Picks the sensitive entity according to the minimum
-       -- and maximum pixel values XPMin, YPMin, XPMax
-       -- and YPMax   defining a 2D area for selection in the 3D view aView.
-        
-    Pick (me:mutable;Polyline:Array1OfPnt2d from TColgp;aView:View from V3d) is static;
-       ---Level: Public 
-       ---Purpose: pick action  - input pixel values for polyline selection for selection.
-
-
+    Pick (me : mutable; theXPMin, theYPMin, theXPMax, theYPMax : Integer; theView : View from V3d) is static;
+    ---Purpose: Picks the sensitive entity according to the minimum
+    -- and maximum pixel values <theXPMin>, <theYPMin>, <theXPMax>
+    -- and <theYPMax> defining a 2D area for selection in the 3D view aView.
 
+    Pick (me : mutable; thePolyline : Array1OfPnt2d from TColgp; theView : View from V3d) is static;
+    ---Level: Public 
+    ---Purpose: pick action - input pixel values for polyline selection for selection.
 
     ---Category: Inquire Methods
 
     Projector (me) returns Projector from Select3D;
-       ---Level: Public 
-       ---Purpose: Returns the current Projector.
-       ---C++: inline
-       ---C++: return const&
-
-
+    ---Level: Public 
+    ---Purpose: Returns the current Projector.
+    ---C++: inline
+    ---C++: return const&
 
     ---Category: Internal Methods
     --           -----------------
 
-    UpdateProj(me   :mutable;
-              aView: View from V3d) returns Boolean is static private;
-       ---Level: Internal 
-
-
-    DisplayAreas(me   :mutable;
-                aView: View from V3d) is static;
-       ---Purpose: Displays sensitive areas found in the view aView.
+    UpdateProj (me      : mutable;
+                theView : View from V3d) returns Boolean is static private;
+    ---Level: Internal
 
-    ClearAreas (me   :mutable;
-               aView: View from V3d) is static;
-       ---Purpose: Clears the view aView of sensitive areas found in it.
-    
-    DisplaySensitive(me:mutable;aView : View from V3d) is static; 
-  
-       --- Purpose: Displays the selection aSel found in the view aView.
-        
-    ClearSensitive(me:mutable;aView:View from V3d) is static;
+    DisplayAreas (me      : mutable;
+                  theView : View from V3d) is static;
+    ---Purpose: Displays sensitive areas found in the view <theView>.
 
+    ClearAreas (me      : mutable;
+                theView : View from V3d) is static;
+    ---Purpose: Clears the view aView of sensitive areas found in it.
 
+    DisplaySensitive (me : mutable; theView : View from V3d) is static;
+    --- Purpose: Displays sensitives in view <theView>.
 
+    ClearSensitive (me : mutable; theView : View from V3d) is static;
 
-    DisplaySensitive(me:mutable;
-                    aSel        : Selection from SelectMgr;
-                    aView       : View from V3d;
-                    ClearOthers : Boolean from Standard = Standard_True)
+    DisplaySensitive (me               : mutable;
+                      theSel           : Selection from SelectMgr;
+                      theView          : View from V3d;
+                      theToClearOthers : Boolean from Standard = Standard_True)
     is static;
-    
-    DisplayAreas(me:mutable;
-                aSel        :Selection from SelectMgr;
-                aView       : View from V3d;
-                ClearOthers : Boolean from Standard = Standard_True)
+
+    DisplayAreas (me               : mutable;
+                  theSel           : Selection from SelectMgr;
+                  theView          : View from V3d;
+                  theToClearOthers : Boolean from Standard = Standard_True)
     is static;
-    
-    
-    ComputeSensitivePrs(me:mutable;aSel: Selection from SelectMgr)
+
+    ComputeSensitivePrs (me : mutable; theSel: Selection from SelectMgr)
     is static private;
-       ---Level: Internal 
+    ---Level: Internal
 
-    ComputeAreasPrs(me:mutable;aSel:Selection from SelectMgr)
-     is static private;
-       ---Level: Internal 
+    ComputeAreasPrs (me : mutable; theSel : Selection from SelectMgr)
+    is static private;
+    ---Level: Internal
 
     SetClipping (me : mutable; thePlanes : SequenceOfHClipPlane from Graphic3d) is protected;
     ---Level: Internal
@@ -190,18 +176,19 @@ is
     
 fields
 
-    myprj         : Projector    from Select3D;
-    mycoeff       : Real from Standard[14];
-    myprevcoeff   : Real from Standard[14];
-    mycenter      : Real from Standard[2];
-    myprevcenter  : Real from Standard[2];
-    mylastzoom    : Real from Standard;
-    mysensmode    : SensitivityMode from StdSelect;
-    mypixtol      : Integer ;
-    myupdatetol   : Boolean;
-    
-    
-             --areas verification...
+    myProjector         : Projector from Select3D;
+    myPrevAt            : Real from Standard[3];
+    myPrevUp            : Real from Standard[3];
+    myPrevProj          : Real from Standard[3];
+    myPrevAxialScale    : Real from Standard[3];
+    myPrevFOV           : Real from Standard;
+    myPrevScale         : Real from Standard;
+    myPrevOrthographic  : Boolean from Standard;
+    mySensMode          : SensitivityMode from StdSelect;
+    myPixelTolerance    : Integer from Standard;
+    myToUpdateTolerance : Boolean from Standard;
+
+    --areas verification...
 
     myareagroup  : Group                from Graphic3d;
     mysensgroup  : Group                from Graphic3d;
index 3e82c45..2187831 100644 (file)
@@ -79,491 +79,596 @@ static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulatio
   return nFree;
 }
 
-static Standard_Boolean ReadIsDebugMode()
-{
-  OSD_Environment StdSelectdb ("SELDEBUGMODE");
-  return !StdSelectdb.Value().IsEmpty();
-}
-
-static Standard_Boolean StdSelectDebugModeOn()
-{
-  static const Standard_Boolean isDebugMode = ReadIsDebugMode();
-  return isDebugMode;
-}
-
-//==================================================
-// Function:
-// Purpose :
-//==================================================
-
-StdSelect_ViewerSelector3d
-::StdSelect_ViewerSelector3d():
-myprj(new Select3D_Projector()),
-mylastzoom(0.0),
-mysensmode(StdSelect_SM_WINDOW),
-mypixtol(2),
-myupdatetol(Standard_True)
+//=======================================================================
+// Function : Constructor
+// Purpose  :
+//=======================================================================
+StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d()
+: myProjector (new Select3D_Projector()),
+  myPrevFOV (0.0),
+  myPrevScale (0.0),
+  myPrevOrthographic (Standard_True),
+  mySensMode (StdSelect_SM_WINDOW),
+  myPixelTolerance (2),
+  myToUpdateTolerance (Standard_True)
 {
-  for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
-  for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
+  myPrevAt[0]         = 0.0;
+  myPrevAt[1]         = 0.0;
+  myPrevAt[2]         = 0.0;
+  myPrevUp[0]         = 0.0;
+  myPrevUp[1]         = 0.0;
+  myPrevUp[2]         = 0.0;
+  myPrevProj[0]       = 0.0;
+  myPrevProj[1]       = 0.0;
+  myPrevProj[2]       = 0.0;
+  myPrevAxialScale[0] = 0.0;
+  myPrevAxialScale[1] = 0.0;
+  myPrevAxialScale[2] = 0.0;
 }
 
-
-//==================================================
-// Function:
-// Purpose :
-//==================================================
-
-StdSelect_ViewerSelector3d
-::StdSelect_ViewerSelector3d(const Handle(Select3D_Projector)& aProj):
-myprj(aProj),
-mylastzoom(0.0),
-mysensmode(StdSelect_SM_WINDOW),
-mypixtol(2),
-myupdatetol(Standard_True)
+//=======================================================================
+// Function : Constructor
+// Purpose  :
+//=======================================================================
+StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d (const Handle(Select3D_Projector)& theProj)
+: myProjector (theProj),
+  myPrevFOV (0.0),
+  myPrevScale (0.0),
+  myPrevOrthographic (Standard_True),
+  mySensMode (StdSelect_SM_WINDOW),
+  myPixelTolerance (2),
+  myToUpdateTolerance (Standard_True)
 {
-  for (Standard_Integer i=0;i<=13;i++) {mycoeff [i] = 0.;myprevcoeff[i]=0.0;}
-  for (Standard_Integer j=0;j<2;j++) {mycenter [j] = 0.;myprevcenter[j]=0.0;}
+  myPrevAt[0]         = 0.0;
+  myPrevAt[1]         = 0.0;
+  myPrevAt[2]         = 0.0;
+  myPrevUp[0]         = 0.0;
+  myPrevUp[1]         = 0.0;
+  myPrevUp[2]         = 0.0;
+  myPrevProj[0]       = 0.0;
+  myPrevProj[1]       = 0.0;
+  myPrevProj[2]       = 0.0;
+  myPrevAxialScale[0] = 0.0;
+  myPrevAxi