d0b410435b2e81fd40a4ca385f50c48b53603e13
[occt.git] / src / SelectMgr / SelectMgr_TriangularFrustumSet.cxx
1 // Created on: 2014-11-21
2 // Created by: Varvara POSKONINA
3 // Copyright (c) 2005-2014 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 <BRepMesh_DataStructureOfDelaun.hxx>
17 #include <BRepMesh_Delaun.hxx>
18 #include <NCollection_IncAllocator.hxx>
19
20 #include <SelectMgr_TriangularFrustumSet.hxx>
21
22 #define MEMORY_BLOCK_SIZE 512 * 7
23
24 // =======================================================================
25 // function : BuildSelectingVolume
26 // purpose  : Meshes polygon bounded by polyline. Than organizes a set of
27 //            triangular frustums, where each triangle's projection onto
28 //            near and far view frustum planes is considered as a frustum
29 //            base
30 // =======================================================================
31 void SelectMgr_TriangularFrustumSet::Build (const TColgp_Array1OfPnt2d& thePoints)
32 {
33   myFrustums.Clear();
34
35   Handle(NCollection_IncAllocator) anAllocator = new NCollection_IncAllocator (MEMORY_BLOCK_SIZE);
36   Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun(anAllocator);
37   Standard_Integer aPtsLower = thePoints.Lower();
38   Standard_Integer aPtsUpper = thePoints.Upper();
39   BRepMesh::Array1OfInteger anIndexes (0, thePoints.Length() - 1);
40   for (Standard_Integer aPtIdx = aPtsLower; aPtIdx <= aPtsUpper; ++aPtIdx)
41   {
42     BRepMesh_Vertex aVertex (thePoints.Value (aPtIdx).XY(), aPtIdx, BRepMesh_Frontier);
43     anIndexes.ChangeValue (aPtIdx - aPtsLower) = aMeshStructure->AddNode (aVertex);
44   }
45
46   Standard_Real aPtSum = 0;
47   for (Standard_Integer aIdx = aPtsLower; aIdx <= aPtsUpper; ++aIdx)
48   {
49     Standard_Integer aNextIdx = (aIdx % thePoints.Length()) + 1;
50     aPtSum += (thePoints.Value (aNextIdx).Coord().X() - thePoints.Value (aIdx).Coord().X())
51               * (thePoints.Value (aNextIdx).Coord().Y() + thePoints.Value (aIdx).Coord().Y());
52   }
53   Standard_Boolean isClockwiseOrdered = aPtSum < 0;
54
55   for (Standard_Integer aIdx = 0; aIdx < anIndexes.Length(); ++aIdx)
56   {
57     Standard_Integer aPtIdx = isClockwiseOrdered ? aIdx : (aIdx + 1) % anIndexes.Length();
58     Standard_Integer aNextPtIdx = isClockwiseOrdered ? (aIdx + 1) % anIndexes.Length() : aIdx;
59     BRepMesh_Edge anEdge (anIndexes.Value (aPtIdx),
60                           anIndexes.Value (aNextPtIdx),
61                           BRepMesh_Frontier);
62     aMeshStructure->AddLink (anEdge);
63   }
64
65   BRepMesh_Delaun aTriangulation (aMeshStructure, anIndexes);
66   const BRepMesh::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
67   if (aTriangles.Extent() < 1)
68     return;
69
70   BRepMesh::MapOfInteger::Iterator aTriangleIt (aTriangles);
71   for (; aTriangleIt.More(); aTriangleIt.Next())
72   {
73     const Standard_Integer aTriangleId = aTriangleIt.Key();
74     const BRepMesh_Triangle& aCurrentTriangle = aMeshStructure->GetElement (aTriangleId);
75
76     if (aCurrentTriangle.Movability() == BRepMesh_Deleted)
77       continue;
78
79     Standard_Integer aTriangleVerts[3];
80     aMeshStructure->ElementNodes (aCurrentTriangle, aTriangleVerts);
81
82     gp_Pnt2d aPts[3];
83     for (Standard_Integer aVertIdx = 0; aVertIdx < 3; ++aVertIdx)
84     {
85       const BRepMesh_Vertex& aVertex = aMeshStructure->GetNode (aTriangleVerts[aVertIdx]);
86       aPts[aVertIdx] = aVertex.Coord();
87     }
88
89     Handle(SelectMgr_TriangularFrustum) aTrFrustum = new SelectMgr_TriangularFrustum();
90     aTrFrustum->SetBuilder (myBuilder);
91     aTrFrustum->Build (aPts[0], aPts[1], aPts[2]);
92     myFrustums.Append (aTrFrustum);
93   }
94
95   aMeshStructure.Nullify();
96   anAllocator.Nullify();
97 }
98
99 // =======================================================================
100 // function : Transform
101 // purpose  : Returns a copy of the frustum with all sub-volumes transformed
102 //            according to the matrix given
103 // =======================================================================
104 NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustumSet::Transform (const gp_Trsf& theTrsf)
105 {
106   SelectMgr_TriangularFrustumSet* aRes = new SelectMgr_TriangularFrustumSet();
107
108   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
109   {
110     aRes->myFrustums.Append (Handle(SelectMgr_TriangularFrustum)::DownCast (anIter.Value()->Transform (theTrsf)));
111   }
112
113   return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
114 }
115
116 // =======================================================================
117 // function : Overlaps
118 // purpose  :
119 // =======================================================================
120 Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
121                                                            Standard_Real& theDepth)
122 {
123   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
124   {
125     if (anIter.Value()->Overlaps (theBox, theDepth))
126       return Standard_True;
127   }
128
129   return Standard_False;
130 }
131
132 // =======================================================================
133 // function : Overlaps
134 // purpose  :
135 // =======================================================================
136 Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const SelectMgr_Vec3& theMinPnt,
137                                                            const SelectMgr_Vec3& theMaxPnt,
138                                                            Standard_Boolean* /*theInside*/)
139 {
140   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
141   {
142     if (anIter.Value()->Overlaps (theMinPnt, theMaxPnt, NULL))
143       return Standard_True;
144   }
145
146   return Standard_False;
147 }
148
149 // =======================================================================
150 // function : Overlaps
151 // purpose  :
152 // =======================================================================
153 Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt,
154                                                            Standard_Real& theDepth)
155 {
156   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
157   {
158     if (anIter.Value()->Overlaps (thePnt, theDepth))
159       return Standard_True;
160   }
161
162   return Standard_False;
163 }
164
165 // =======================================================================
166 // function : Overlaps
167 // purpose  :
168 // =======================================================================
169 Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts,
170                                                            Select3D_TypeOfSensitivity theSensType,
171                                                            Standard_Real& theDepth)
172 {
173   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
174   {
175     if (anIter.Value()->Overlaps (theArrayOfPts, theSensType, theDepth))
176       return Standard_True;
177   }
178
179   return Standard_False;
180 }
181
182 // =======================================================================
183 // function : Overlaps
184 // purpose  :
185 // =======================================================================
186 Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt1,
187                                                            const gp_Pnt& thePnt2,
188                                                            Standard_Real& theDepth)
189 {
190   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
191   {
192     if (anIter.Value()->Overlaps (thePnt1, thePnt2, theDepth))
193       return Standard_True;
194   }
195
196   return Standard_False;
197 }
198
199 // =======================================================================
200 // function : Overlaps
201 // purpose  :
202 // =======================================================================
203 Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt1,
204                                                            const gp_Pnt& thePnt2,
205                                                            const gp_Pnt& thePnt3,
206                                                            Select3D_TypeOfSensitivity theSensType,
207                                                            Standard_Real& theDepth)
208 {
209   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
210   {
211     if (anIter.Value()->Overlaps (thePnt1, thePnt2, thePnt3, theSensType, theDepth))
212       return Standard_True;
213   }
214
215   return Standard_False;
216 }
217
218 #undef MEMORY_BLOCK_SIZE