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