0033018: Coding - get rid of unused headers [Plugin to ShapeAnalysis]
[occt.git] / src / Select3D / Select3D_SensitiveGroup.cxx
1 // Created on: 1998-04-16
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Select3D_SensitiveGroup.hxx>
18
19 IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveGroup,Select3D_SensitiveSet)
20
21 //=======================================================================
22 //function : Creation
23 //purpose  :
24 //=======================================================================
25 Select3D_SensitiveGroup::Select3D_SensitiveGroup (const Handle(SelectMgr_EntityOwner)& theOwnerId,
26                                                   const Standard_Boolean theIsMustMatchAll)
27 : Select3D_SensitiveSet (theOwnerId),
28   myMustMatchAll (theIsMustMatchAll),
29   myToCheckOverlapAll (Standard_False),
30   myCenter (0.0, 0.0, 0.0) {}
31
32 //=======================================================================
33 //function : Creation
34 //purpose  :
35 //=======================================================================
36 Select3D_SensitiveGroup::Select3D_SensitiveGroup (const Handle(SelectMgr_EntityOwner)& theOwnerId,
37                                                   Select3D_EntitySequence& theEntities,
38                                                   const Standard_Boolean theIsMustMatchAll)
39 : Select3D_SensitiveSet (theOwnerId),
40   myEntities (Max (1, theEntities.Size())),
41   myMustMatchAll (theIsMustMatchAll),
42   myToCheckOverlapAll (Standard_False),
43   myCenter (0.0, 0.0, 0.0)
44 {
45   for (Select3D_EntitySequenceIter anIter (theEntities); anIter.More(); anIter.Next())
46   {
47     const Handle(Select3D_SensitiveEntity)& anEntity = anIter.Value();
48     const Standard_Integer aPrevExtent = myEntities.Extent();
49     if (myEntities.Add (anEntity) <= aPrevExtent)
50     {
51       continue;
52     }
53
54     myBndBox.Combine (anEntity->BoundingBox());
55     myBVHPrimIndexes.Append (myEntities.Extent());
56     myCenter.ChangeCoord() += anEntity->CenterOfGeometry().XYZ();
57   }
58
59   myCenter.ChangeCoord().Divide (static_cast<Standard_Real> (myEntities.Extent()));
60
61   MarkDirty();
62 }
63
64 //=======================================================================
65 //function : Add
66 //purpose  : No control of entities inside
67 //=======================================================================
68 void Select3D_SensitiveGroup::Add (Select3D_EntitySequence& theEntities)
69 {
70   if (theEntities.IsEmpty())
71   {
72     return;
73   }
74
75   gp_Pnt aCent (0.0, 0.0, 0.0);
76   myEntities.ReSize (myEntities.Extent() + theEntities.Size());
77   for (Select3D_EntitySequenceIter anIter (theEntities); anIter.More(); anIter.Next())
78   {
79     const Handle(Select3D_SensitiveEntity)& anEntity = anIter.Value();
80     const Standard_Integer aPrevExtent = myEntities.Extent();
81     if (myEntities.Add (anEntity) <= aPrevExtent)
82     {
83       continue;
84     }
85
86     myBndBox.Combine (anEntity->BoundingBox());
87     myBVHPrimIndexes.Append (myEntities.Extent());
88     aCent.ChangeCoord() += anEntity->CenterOfGeometry().XYZ();
89   }
90   aCent.ChangeCoord().Divide (myEntities.Extent());
91   myCenter = (myCenter.XYZ() + aCent.XYZ()).Multiplied (0.5);
92 }
93
94 //=======================================================================
95 //function : Add
96 //purpose  :
97 //=======================================================================
98 void Select3D_SensitiveGroup::Add (const Handle(Select3D_SensitiveEntity)& theSensitive)
99 {
100   const Standard_Integer aPrevExtent = myEntities.Extent();
101   if (myEntities.Add (theSensitive) <= aPrevExtent)
102   {
103     return;
104   }
105
106   myBVHPrimIndexes.Append (myEntities.Extent());
107   myBndBox.Combine (theSensitive->BoundingBox());
108   myCenter.ChangeCoord() += theSensitive->CenterOfGeometry().XYZ();
109   if (myEntities.Extent() >= 2)
110   {
111     myCenter.ChangeCoord().Multiply (0.5);
112   }
113 }
114
115 //=======================================================================
116 //function : Remove
117 //purpose  :
118 //=======================================================================
119 void Select3D_SensitiveGroup::Remove (const Handle(Select3D_SensitiveEntity)& theSensitive)
120 {
121   if (!myEntities.RemoveKey (theSensitive))
122   {
123     return;
124   }
125
126   myBndBox.Clear();
127   myCenter = gp_Pnt (0.0, 0.0, 0.0);
128   myBVHPrimIndexes.Clear();
129   for (Standard_Integer anIdx = 1; anIdx <= myEntities.Size(); ++anIdx)
130   {
131     const Handle(Select3D_SensitiveEntity)& anEntity = myEntities.FindKey (anIdx);
132     myBndBox.Combine (anEntity->BoundingBox());
133     myCenter.ChangeCoord() += anEntity->CenterOfGeometry().XYZ();
134     myBVHPrimIndexes.Append (anIdx);
135   }
136   myCenter.ChangeCoord().Divide (static_cast<Standard_Real> (myEntities.Extent()));
137 }
138
139 //=======================================================================
140 //function : IsIn
141 //purpose  :
142 //=======================================================================
143 Standard_Boolean Select3D_SensitiveGroup::IsIn (const Handle(Select3D_SensitiveEntity)& theSensitive) const
144 {
145   return myEntities.Contains (theSensitive);
146 }
147
148 //=======================================================================
149 //function : Clear
150 //purpose  :
151 //=======================================================================
152
153 void Select3D_SensitiveGroup::Clear()
154 {
155   myEntities.Clear();
156   myBndBox.Clear();
157   myCenter = gp_Pnt (0.0, 0.0, 0.0);
158   myBVHPrimIndexes.Clear();
159 }
160
161 //=======================================================================
162 // function : NbSubElements
163 // purpose  : Returns the amount of sub-entities
164 //=======================================================================
165 Standard_Integer Select3D_SensitiveGroup::NbSubElements() const
166 {
167   return myEntities.Size();
168 }
169
170 //=======================================================================
171 //function : GetConnected
172 //purpose  :
173 //=======================================================================
174
175 Handle(Select3D_SensitiveEntity) Select3D_SensitiveGroup::GetConnected()
176 {
177   Handle(Select3D_SensitiveGroup) aNewEntity = new Select3D_SensitiveGroup (myOwnerId, myMustMatchAll);
178   Select3D_EntitySequence aConnectedEnt;
179   for (Select3D_IndexedMapOfEntity::Iterator anEntityIter (myEntities); anEntityIter.More(); anEntityIter.Next())
180   {
181     aConnectedEnt.Append (anEntityIter.Value()->GetConnected());
182   }
183   aNewEntity->Add (aConnectedEnt);
184   return aNewEntity;
185 }
186
187 //=======================================================================
188 //function : Matches
189 //purpose  :
190 //=======================================================================
191 Standard_Boolean Select3D_SensitiveGroup::Matches (SelectBasics_SelectingVolumeManager& theMgr,
192                                                    SelectBasics_PickResult& thePickResult)
193 {
194   const Standard_Boolean toMatchAll = theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Point
195                                    && myMustMatchAll;
196   const Standard_Boolean toCheckAll = theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Point
197                                    && myToCheckOverlapAll;
198   if (!toMatchAll && !toCheckAll)
199   {
200     return Select3D_SensitiveSet::Matches (theMgr, thePickResult);
201   }
202
203   SelectBasics_PickResult aPickResult;
204   Standard_Boolean isFailed = Standard_False;
205   for (Select3D_IndexedMapOfEntity::Iterator anEntityIter (myEntities); anEntityIter.More(); anEntityIter.Next())
206   {
207     const Handle(Select3D_SensitiveEntity)& aChild = anEntityIter.Value();
208     if (!aChild->Matches (theMgr, aPickResult))
209     {
210       if (toMatchAll)
211       {
212         isFailed = Standard_True;
213         if (!toCheckAll)
214         {
215           break;
216         }
217       }
218     }
219     else
220     {
221       thePickResult = SelectBasics_PickResult::Min (thePickResult, aPickResult);
222     }
223   }
224   if (isFailed)
225   {
226     return Standard_False;
227   }
228
229   thePickResult.SetDistToGeomCenter(distanceToCOG(theMgr));
230   return Standard_True;
231 }
232
233 //=======================================================================
234 //function : Set
235 //purpose  :
236 //=======================================================================
237 void Select3D_SensitiveGroup::Set (const Handle(SelectMgr_EntityOwner)& theOwnerId)
238
239   Select3D_SensitiveEntity::Set (theOwnerId);
240   for (Select3D_IndexedMapOfEntity::Iterator anEntityIter (myEntities); anEntityIter.More(); anEntityIter.Next())
241   {
242     anEntityIter.Value()->Set (theOwnerId);
243   }
244 }
245
246 //=======================================================================
247 // function : BoundingBox
248 // purpose  : Returns bounding box of the group. If location
249 //            transformation is set, it will be applied
250 //=======================================================================
251 Select3D_BndBox3d Select3D_SensitiveGroup::BoundingBox()
252 {
253   if (myBndBox.IsValid())
254     return myBndBox;
255
256   // do not apply the transformation because sensitives AABBs
257   // are already transformed
258   for (Select3D_IndexedMapOfEntity::Iterator anEntityIter (myEntities); anEntityIter.More(); anEntityIter.Next())
259   {
260     myBndBox.Combine (anEntityIter.Value()->BoundingBox());
261   }
262
263   return myBndBox;
264 }
265
266 //=======================================================================
267 // function : CenterOfGeometry
268 // purpose  : Returns center of group. If location transformation
269 //            is set, it will be applied
270 //=======================================================================
271 gp_Pnt Select3D_SensitiveGroup::CenterOfGeometry() const
272 {
273   return myCenter;
274 }
275
276 //=======================================================================
277 // function : Box
278 // purpose  : Returns bounding box of sensitive entity with index theIdx
279 //=======================================================================
280 Select3D_BndBox3d Select3D_SensitiveGroup::Box (const Standard_Integer theIdx) const
281 {
282   const Standard_Integer anElemIdx = myBVHPrimIndexes.Value (theIdx);
283   return myEntities.FindKey (anElemIdx)->BoundingBox();
284 }
285
286 //=======================================================================
287 // function : Center
288 // purpose  : Returns geometry center of sensitive entity with index
289 //            theIdx in the vector along the given axis theAxis
290 //=======================================================================
291 Standard_Real Select3D_SensitiveGroup::Center (const Standard_Integer theIdx,
292                                                const Standard_Integer theAxis) const
293 {
294   const Standard_Integer anElemIdx = myBVHPrimIndexes.Value (theIdx);
295   const gp_Pnt aCenter = myEntities.FindKey (anElemIdx)->CenterOfGeometry();
296   return theAxis == 0 ? aCenter.X() : (theAxis == 1 ? aCenter.Y() : aCenter.Z());
297 }
298
299 //=======================================================================
300 // function : Swap
301 // purpose  : Swaps items with indexes theIdx1 and theIdx2 in the vector
302 //=======================================================================
303 void Select3D_SensitiveGroup::Swap (const Standard_Integer theIdx1,
304                                     const Standard_Integer theIdx2)
305 {
306   const Standard_Integer anEntIdx1 = myBVHPrimIndexes.Value (theIdx1);
307   const Standard_Integer anEntIdx2 = myBVHPrimIndexes.Value (theIdx2);
308
309   myBVHPrimIndexes.ChangeValue (theIdx1) = anEntIdx2;
310   myBVHPrimIndexes.ChangeValue (theIdx2) = anEntIdx1;
311 }
312
313 //=======================================================================
314 // function : Size
315 // purpose  : Returns the length of vector of sensitive entities
316 //=======================================================================
317 Standard_Integer Select3D_SensitiveGroup::Size() const
318 {
319   return myBVHPrimIndexes.Size();
320 }
321
322 // =======================================================================
323 // function : overlapsElement
324 // purpose  : Checks whether the entity with index theIdx overlaps the
325 //            current selecting volume
326 // =======================================================================
327 Standard_Boolean Select3D_SensitiveGroup::overlapsElement (SelectBasics_PickResult& thePickResult,
328                                                            SelectBasics_SelectingVolumeManager& theMgr,
329                                                            Standard_Integer theElemIdx,
330                                                            Standard_Boolean )
331 {
332   const Standard_Integer aSensitiveIdx = myBVHPrimIndexes.Value (theElemIdx);
333   if (myEntities.FindKey (aSensitiveIdx)->Matches (theMgr, thePickResult))
334   {
335     return Standard_True;
336   }
337
338   return Standard_False;
339 }
340
341 // =======================================================================
342 // function : elementIsInside
343 // purpose  :
344 // =======================================================================
345 Standard_Boolean Select3D_SensitiveGroup::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
346                                                            Standard_Integer theElemIdx,
347                                                            Standard_Boolean theIsFullInside)
348 {
349   SelectBasics_PickResult aDummy;
350   return overlapsElement (aDummy, theMgr, theElemIdx, theIsFullInside);
351 }
352
353 // =======================================================================
354 // function : distanceToCOG
355 // purpose  : Calculates distance from the 3d projection of used-picked
356 //            screen point to center of the geometry
357 // =======================================================================
358 Standard_Real Select3D_SensitiveGroup::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
359 {
360   return theMgr.DistToGeometryCenter (CenterOfGeometry());
361 }
362
363 // =======================================================================
364 // function : DumpJson
365 // purpose  :
366 // =======================================================================
367 void Select3D_SensitiveGroup::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
368 {
369   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
370   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Select3D_SensitiveSet)
371
372   for (Select3D_IndexedMapOfEntity::Iterator anIterator (myEntities); anIterator.More(); anIterator.Next())
373   {
374     const Handle(Select3D_SensitiveEntity)& anEntity = anIterator.Value();
375     OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, anEntity.get())
376   }
377
378   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMustMatchAll)
379   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToCheckOverlapAll)
380
381   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myBndBox)
382 }