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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Select3D_SensitiveGroup.hxx>
19 IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveGroup,Select3D_SensitiveSet)
21 //=======================================================================
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) {}
32 //=======================================================================
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)
45 for (Select3D_EntitySequenceIter anIter (theEntities); anIter.More(); anIter.Next())
47 const Handle(Select3D_SensitiveEntity)& anEntity = anIter.Value();
48 const Standard_Integer aPrevExtent = myEntities.Extent();
49 if (myEntities.Add (anEntity) <= aPrevExtent)
54 myBndBox.Combine (anEntity->BoundingBox());
55 myBVHPrimIndexes.Append (myEntities.Extent());
56 myCenter.ChangeCoord() += anEntity->CenterOfGeometry().XYZ();
59 myCenter.ChangeCoord().Divide (static_cast<Standard_Real> (myEntities.Extent()));
64 //=======================================================================
66 //purpose : No control of entities inside
67 //=======================================================================
68 void Select3D_SensitiveGroup::Add (Select3D_EntitySequence& theEntities)
70 if (theEntities.IsEmpty())
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())
79 const Handle(Select3D_SensitiveEntity)& anEntity = anIter.Value();
80 const Standard_Integer aPrevExtent = myEntities.Extent();
81 if (myEntities.Add (anEntity) <= aPrevExtent)
86 myBndBox.Combine (anEntity->BoundingBox());
87 myBVHPrimIndexes.Append (myEntities.Extent());
88 aCent.ChangeCoord() += anEntity->CenterOfGeometry().XYZ();
90 aCent.ChangeCoord().Divide (myEntities.Extent());
91 myCenter = (myCenter.XYZ() + aCent.XYZ()).Multiplied (0.5);
94 //=======================================================================
97 //=======================================================================
98 void Select3D_SensitiveGroup::Add (const Handle(Select3D_SensitiveEntity)& theSensitive)
100 const Standard_Integer aPrevExtent = myEntities.Extent();
101 if (myEntities.Add (theSensitive) <= aPrevExtent)
106 myBVHPrimIndexes.Append (myEntities.Extent());
107 myBndBox.Combine (theSensitive->BoundingBox());
108 myCenter.ChangeCoord() += theSensitive->CenterOfGeometry().XYZ();
109 if (myEntities.Extent() >= 2)
111 myCenter.ChangeCoord().Multiply (0.5);
115 //=======================================================================
118 //=======================================================================
119 void Select3D_SensitiveGroup::Remove (const Handle(Select3D_SensitiveEntity)& theSensitive)
121 if (!myEntities.RemoveKey (theSensitive))
127 myCenter = gp_Pnt (0.0, 0.0, 0.0);
128 myBVHPrimIndexes.Clear();
129 for (Standard_Integer anIdx = 1; anIdx <= myEntities.Size(); ++anIdx)
131 const Handle(Select3D_SensitiveEntity)& anEntity = myEntities.FindKey (anIdx);
132 myBndBox.Combine (anEntity->BoundingBox());
133 myCenter.ChangeCoord() += anEntity->CenterOfGeometry().XYZ();
134 myBVHPrimIndexes.Append (anIdx);
136 myCenter.ChangeCoord().Divide (static_cast<Standard_Real> (myEntities.Extent()));
139 //=======================================================================
142 //=======================================================================
143 Standard_Boolean Select3D_SensitiveGroup::IsIn (const Handle(Select3D_SensitiveEntity)& theSensitive) const
145 return myEntities.Contains (theSensitive);
148 //=======================================================================
151 //=======================================================================
153 void Select3D_SensitiveGroup::Clear()
157 myCenter = gp_Pnt (0.0, 0.0, 0.0);
158 myBVHPrimIndexes.Clear();
161 //=======================================================================
162 // function : NbSubElements
163 // purpose : Returns the amount of sub-entities
164 //=======================================================================
165 Standard_Integer Select3D_SensitiveGroup::NbSubElements() const
167 return myEntities.Size();
170 //=======================================================================
171 //function : GetConnected
173 //=======================================================================
175 Handle(Select3D_SensitiveEntity) Select3D_SensitiveGroup::GetConnected()
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())
181 aConnectedEnt.Append (anEntityIter.Value()->GetConnected());
183 aNewEntity->Add (aConnectedEnt);
187 //=======================================================================
190 //=======================================================================
191 Standard_Boolean Select3D_SensitiveGroup::Matches (SelectBasics_SelectingVolumeManager& theMgr,
192 SelectBasics_PickResult& thePickResult)
194 const Standard_Boolean toMatchAll = theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Point
196 const Standard_Boolean toCheckAll = theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Point
197 && myToCheckOverlapAll;
198 if (!toMatchAll && !toCheckAll)
200 return Select3D_SensitiveSet::Matches (theMgr, thePickResult);
203 SelectBasics_PickResult aPickResult;
204 Standard_Boolean isFailed = Standard_False;
205 for (Select3D_IndexedMapOfEntity::Iterator anEntityIter (myEntities); anEntityIter.More(); anEntityIter.Next())
207 const Handle(Select3D_SensitiveEntity)& aChild = anEntityIter.Value();
208 if (!aChild->Matches (theMgr, aPickResult))
212 isFailed = Standard_True;
221 thePickResult = SelectBasics_PickResult::Min (thePickResult, aPickResult);
226 return Standard_False;
229 thePickResult.SetDistToGeomCenter(distanceToCOG(theMgr));
230 return Standard_True;
233 //=======================================================================
236 //=======================================================================
237 void Select3D_SensitiveGroup::Set (const Handle(SelectMgr_EntityOwner)& theOwnerId)
239 Select3D_SensitiveEntity::Set (theOwnerId);
240 for (Select3D_IndexedMapOfEntity::Iterator anEntityIter (myEntities); anEntityIter.More(); anEntityIter.Next())
242 anEntityIter.Value()->Set (theOwnerId);
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()
253 if (myBndBox.IsValid())
256 // do not apply the transformation because sensitives AABBs
257 // are already transformed
258 for (Select3D_IndexedMapOfEntity::Iterator anEntityIter (myEntities); anEntityIter.More(); anEntityIter.Next())
260 myBndBox.Combine (anEntityIter.Value()->BoundingBox());
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
276 //=======================================================================
278 // purpose : Returns bounding box of sensitive entity with index theIdx
279 //=======================================================================
280 Select3D_BndBox3d Select3D_SensitiveGroup::Box (const Standard_Integer theIdx) const
282 const Standard_Integer anElemIdx = myBVHPrimIndexes.Value (theIdx);
283 return myEntities.FindKey (anElemIdx)->BoundingBox();
286 //=======================================================================
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
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());
299 //=======================================================================
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)
306 const Standard_Integer anEntIdx1 = myBVHPrimIndexes.Value (theIdx1);
307 const Standard_Integer anEntIdx2 = myBVHPrimIndexes.Value (theIdx2);
309 myBVHPrimIndexes.ChangeValue (theIdx1) = anEntIdx2;
310 myBVHPrimIndexes.ChangeValue (theIdx2) = anEntIdx1;
313 //=======================================================================
315 // purpose : Returns the length of vector of sensitive entities
316 //=======================================================================
317 Standard_Integer Select3D_SensitiveGroup::Size() const
319 return myBVHPrimIndexes.Size();
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,
332 const Standard_Integer aSensitiveIdx = myBVHPrimIndexes.Value (theElemIdx);
333 if (myEntities.FindKey (aSensitiveIdx)->Matches (theMgr, thePickResult))
335 return Standard_True;
338 return Standard_False;
341 // =======================================================================
342 // function : elementIsInside
344 // =======================================================================
345 Standard_Boolean Select3D_SensitiveGroup::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
346 Standard_Integer theElemIdx,
347 Standard_Boolean theIsFullInside)
349 SelectBasics_PickResult aDummy;
350 return overlapsElement (aDummy, theMgr, theElemIdx, theIsFullInside);
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)
360 return theMgr.DistToGeometryCenter (CenterOfGeometry());
363 // =======================================================================
364 // function : DumpJson
366 // =======================================================================
367 void Select3D_SensitiveGroup::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
369 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
370 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Select3D_SensitiveSet)
372 for (Select3D_IndexedMapOfEntity::Iterator anIterator (myEntities); anIterator.More(); anIterator.Next())
374 const Handle(Select3D_SensitiveEntity)& anEntity = anIterator.Value();
375 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, anEntity.get())
378 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMustMatchAll)
379 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToCheckOverlapAll)
381 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myBndBox)