1 // Created on: 2014-05-29
2 // Created by: Varvara POSKONINA
3 // Copyright (c) 2005-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Select3D_SensitiveSet.hxx>
17 #include <Select3D_BVHPrimitiveContent.hxx>
20 IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveSet,Select3D_SensitiveEntity)
22 //=======================================================================
23 // function : Select3D_SensitiveSet
24 // purpose : Creates new empty sensitive set and its content
25 //=======================================================================
26 Select3D_SensitiveSet::Select3D_SensitiveSet (const Handle(SelectBasics_EntityOwner)& theOwnerId)
27 : Select3D_SensitiveEntity (theOwnerId)
30 myIsLeftChildQueuedFirst = Standard_False;
31 myContent = new Select3D_BVHPrimitiveContent (this);
34 //=======================================================================
36 // purpose : Builds BVH tree for sensitive set
37 //=======================================================================
38 void Select3D_SensitiveSet::BVH()
43 //=======================================================================
45 // purpose : Checks whether one or more entities of the set overlap
46 // current selecting volume. Implements the traverse of BVH
47 // tree built for the set
48 //=======================================================================
49 Standard_Boolean Select3D_SensitiveSet::Matches (SelectBasics_SelectingVolumeManager& theMgr,
50 SelectBasics_PickResult& thePickResult)
52 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVH = myContent->GetBVH();
54 thePickResult = SelectBasics_PickResult (RealLast(), RealLast());
56 if (myContent->Size() < 1 || !theMgr.Overlaps (aBVH->MinPoint (0),
59 return Standard_False;
62 Standard_Integer aStack[32];
63 Standard_Integer aNode = 0;
64 Standard_Integer aHead = -1;
66 Standard_Integer aMatchesNb = -1;
67 Standard_Real aMinDepth = RealLast();
71 const BVH_Vec4i& aData = aBVH->NodeInfoBuffer()[aNode];
73 if (aData.x() == 0) // is inner node
75 const Standard_Integer aLftIdx = aData.y();
76 const Standard_Integer aRghIdx = aData.z();
78 Standard_Boolean isLftInside = Standard_True;
79 Standard_Boolean isRghInside = Standard_True;
81 Standard_Boolean toCheckLft = theMgr.Overlaps (aBVH->MinPoint (aLftIdx),
82 aBVH->MaxPoint (aLftIdx),
83 theMgr.IsOverlapAllowed() ? NULL : &isLftInside);
85 Standard_Boolean toCheckRgh = theMgr.Overlaps (aBVH->MinPoint (aRghIdx),
86 aBVH->MaxPoint (aRghIdx),
87 theMgr.IsOverlapAllowed() ? NULL : &isRghInside);
89 if (!theMgr.IsOverlapAllowed()) // inclusion test
91 if (!toCheckLft || !toCheckRgh)
93 return Standard_False; // no inclusion
96 toCheckLft &= !isLftInside;
97 toCheckRgh &= !isRghInside;
100 if (toCheckLft || toCheckRgh)
102 aNode = toCheckLft ? aLftIdx : aRghIdx;
104 if (toCheckLft && toCheckRgh)
106 aStack[++aHead] = aRghIdx;
114 aNode = aStack[aHead--];
119 for (Standard_Integer anElemIdx = aData.y(); anElemIdx <= aData.z(); ++anElemIdx)
121 if (!theMgr.IsOverlapAllowed()) // inclusion test
123 if (!elementIsInside (theMgr, anElemIdx))
125 return Standard_False;
130 Standard_Real aCurrentDepth = 0.0;
132 if (!overlapsElement (theMgr, anElemIdx, aCurrentDepth))
137 if (aMinDepth > aCurrentDepth)
139 aMinDepth = aCurrentDepth;
140 myDetectedIdx = anElemIdx;
150 aNode = aStack[aHead--];
154 if (aMatchesNb != -1)
156 thePickResult = SelectBasics_PickResult (aMinDepth, distanceToCOG (theMgr));
159 return !theMgr.IsOverlapAllowed() || aMatchesNb != -1;
162 //=======================================================================
163 // function : BoundingBox
164 // purpose : This method should be redefined in Select3D_SensitiveSet
166 //=======================================================================
167 Select3D_BndBox3d Select3D_SensitiveSet::BoundingBox()
169 return Select3D_BndBox3d (SelectMgr_Vec3 (RealLast()),
170 SelectMgr_Vec3 (RealFirst()));
173 //=======================================================================
174 // function : CenterOfGeometry
175 // purpose : This method should be redefined in Select3D_SensitiveSet
177 //=======================================================================
178 gp_Pnt Select3D_SensitiveSet::CenterOfGeometry() const
180 return gp_Pnt (RealLast(), RealLast(), RealLast());
183 //=======================================================================
184 // function : MarkDirty
185 // purpose : Marks BVH tree of the set as outdated. It will be rebuild
186 // at the next call of BVH()
187 //=======================================================================
188 void Select3D_SensitiveSet::MarkDirty()
190 myContent->MarkDirty();
193 //=======================================================================
195 // purpose : Destroys cross-reference to avoid memory leak
196 //=======================================================================
197 void Select3D_SensitiveSet::Clear()
202 //=======================================================================
203 // function : GetLeafNodeSize
204 // purpose : Returns a number of nodes in 1 BVH leaf
205 //=======================================================================
206 Standard_Integer Select3D_SensitiveSet::GetLeafNodeSize() const
208 return myContent->GetLeafNodeSize();