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