ef3825592bb631c1c4370a65881f5d58203c74d7
[occt.git] / src / SelectMgr / SelectMgr_SelectableObjectTrsfPersSet.cxx
1 // Created on: 2015-06-30
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2015 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <SelectMgr_SelectableObjectTrsfPersSet.hxx>
17
18 #include <Bnd_Box.hxx>
19 #include <BVH_LinearBuilder.hxx>
20 #include <SelectMgr_VectorTypes.hxx>
21
22 //=======================================================================
23 // function : SelectMgr_SelectableObjectTrsfPersSet
24 // purpose  :
25 //=======================================================================
26 SelectMgr_SelectableObjectTrsfPersSet::SelectMgr_SelectableObjectTrsfPersSet()
27 : myIsDirty (Standard_False),
28   myBVH (new BVH_Tree<Standard_Real, 3>())
29 {
30   myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (1, 32);
31 }
32
33 //=======================================================================
34 // function : Size
35 // purpose  :
36 //=======================================================================
37 Standard_Integer SelectMgr_SelectableObjectTrsfPersSet::Size() const
38 {
39   return myObjects.Size();
40 }
41
42 //=======================================================================
43 // function : Box
44 // purpose  :
45 //=======================================================================
46 Select3D_BndBox3d SelectMgr_SelectableObjectTrsfPersSet::Box (const Standard_Integer theIndex) const
47 {
48   return *myObjectBoxes (theIndex + 1);
49 }
50
51 //=======================================================================
52 // function : Center
53 // purpose  :
54 //=======================================================================
55 Standard_Real SelectMgr_SelectableObjectTrsfPersSet::Center (const Standard_Integer theIndex,
56                                                              const Standard_Integer theAxis) const
57 {
58   const Select3D_BndBox3d& aBndBox = *myObjectBoxes (theIndex + 1);
59
60   return (aBndBox.CornerMin()[theAxis] + aBndBox.CornerMax()[theAxis]) * 0.5;
61 }
62
63 //=======================================================================
64 // function : Swap
65 // purpose  :
66 //=======================================================================
67 void SelectMgr_SelectableObjectTrsfPersSet::Swap (const Standard_Integer theIndex1,
68                                                   const Standard_Integer theIndex2)
69 {
70   const Standard_Integer aStructIdx1 = theIndex1 + 1;
71   const Standard_Integer aStructIdx2 = theIndex2 + 1;
72
73   myObjects.Swap (aStructIdx1, aStructIdx2);
74   myObjectBoxes.Swap (aStructIdx1, aStructIdx2);
75 }
76
77 //=======================================================================
78 // function : Append
79 // purpose  :
80 //=======================================================================
81 Standard_Boolean SelectMgr_SelectableObjectTrsfPersSet::Append (const Handle(SelectMgr_SelectableObject)& theObject)
82 {
83   Standard_Integer aSize = Size();
84
85   if (aSize < myObjects.Add (theObject))
86   {
87     MarkDirty();
88
89     return Standard_True;
90   }
91
92   return Standard_False;
93 }
94
95 //=======================================================================
96 // function : Remove
97 // purpose  :
98 //=======================================================================
99 Standard_Boolean SelectMgr_SelectableObjectTrsfPersSet::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
100 {
101   const Standard_Integer anIndex = myObjects.FindIndex (theObject);
102
103   if (anIndex != 0)
104   {
105     myObjects.Swap (Size(), anIndex);
106     myObjects.RemoveLast();
107     MarkDirty();
108
109     return Standard_True;
110   }
111
112   return Standard_False;
113 }
114
115 //=======================================================================
116 // function : BVH
117 // purpose  :
118 //=======================================================================
119 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >&
120   SelectMgr_SelectableObjectTrsfPersSet::BVH (const Handle(Graphic3d_Camera)& theCamera,
121                                               const Graphic3d_Mat4d& theProjectionMatrix,
122                                               const Graphic3d_Mat4d& theWorldViewMatrix,
123                                               const Standard_Integer theViewportWidth,
124                                               const Standard_Integer theViewportHeight,
125                                               const Graphic3d_WorldViewProjState& theWVPState)
126 {
127   if (!myIsDirty && (myObjectBoxesState.IsValid() && !myObjectBoxesState.IsChanged(theWVPState)))
128   {
129     return myBVH;
130   }
131
132   myObjectBoxes.ReSize (myObjects.Size());
133
134   for (Standard_Integer anObjectIdx = 1; anObjectIdx <= myObjects.Size(); ++anObjectIdx)
135   {
136     const Handle(SelectMgr_SelectableObject)& anObject = myObjects (anObjectIdx);
137
138     Bnd_Box aBoundingBox;
139
140     if (anObject->TransformPersistence().Flags && !(anObject->TransformPersistence().Flags & Graphic3d_TMF_2d))
141     {
142       anObject->BoundingBox (aBoundingBox);
143       if (!aBoundingBox.IsVoid())
144       {
145         anObject->TransformPersistence().Apply (theCamera, theProjectionMatrix, theWorldViewMatrix, theViewportWidth, theViewportHeight, aBoundingBox);
146       }
147     }
148
149     if (aBoundingBox.IsVoid())
150     {
151       myObjectBoxes.Add (new Select3D_BndBox3d());
152     }
153     else
154     {
155       gp_Pnt aMin = aBoundingBox.CornerMin();
156       gp_Pnt aMax = aBoundingBox.CornerMax();
157
158       myObjectBoxes.Add (new Select3D_BndBox3d (Select3D_Vec3 (aMin.X(), aMin.Y(), aMin.Z()),
159                                                 Select3D_Vec3 (aMax.X(), aMax.Y(), aMax.Z())));
160     }
161   }
162
163   myBuilder->Build (this, myBVH.operator->(), BVH_Set<Standard_Real, 3>::Box());
164
165   myObjectBoxesState = theWVPState;
166   myObjectBoxes.Clear();
167   myIsDirty = Standard_False;
168
169   return myBVH;
170 }