1 // Created on: 1996-10-17
2 // Created by: Odile OLIVIER
3 // Copyright (c) 1996-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_SensitiveWire.hxx>
18 #include <Select3D_SensitiveEntity.hxx>
19 #include <Precision.hxx>
20 #include <TopLoc_Location.hxx>
22 #include <Select3D_SensitiveSegment.hxx>
25 IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveWire,Select3D_SensitiveSet)
27 //=====================================================
28 // Function : Select3D_SensitiveWire
30 //=====================================================
31 Select3D_SensitiveWire::Select3D_SensitiveWire (const Handle(SelectBasics_EntityOwner)& theOwnerId)
32 : Select3D_SensitiveSet (theOwnerId),
33 myCenter (0.0, 0.0, 0.0)
36 //=====================================================
39 //=====================================================
40 void Select3D_SensitiveWire::Add (const Handle(Select3D_SensitiveEntity)& theSensitive)
42 if (!theSensitive.IsNull())
43 myEntities.Append (theSensitive);
45 Select3D_BndBox3d aBndBox = theSensitive->BoundingBox();
46 myBndBox.Combine (aBndBox);
47 myCenter.ChangeCoord() += theSensitive->CenterOfGeometry().XYZ();
48 if (myEntities.Length() != 1)
49 myCenter.ChangeCoord().Divide (2.0);
50 myEntityIndexes.Append (myEntities.Length() - 1);
53 //=======================================================================
54 // function : NbSubElements
55 // purpose : Returns the amount of sub-entities
56 //=======================================================================
57 Standard_Integer Select3D_SensitiveWire::NbSubElements()
59 return myEntities.Length();
62 //=======================================================================
64 // purpose : Returns the length of vector of sensitive entities
65 //=======================================================================
66 Standard_Integer Select3D_SensitiveWire::Size() const
68 return myEntities.Length();
71 //=======================================================================
73 // purpose : Returns bounding box of sensitive entity with index theIdx
74 //=======================================================================
75 Select3D_BndBox3d Select3D_SensitiveWire::Box (const Standard_Integer theIdx) const
77 const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theIdx);
78 return myEntities.Value (aSensitiveIdx)->BoundingBox();
81 //=======================================================================
83 // purpose : Returns geometry center of sensitive entity with index
84 // theIdx in the vector along the given axis theAxis
85 //=======================================================================
86 Standard_Real Select3D_SensitiveWire::Center (const Standard_Integer theIdx,
87 const Standard_Integer theAxis) const
89 const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theIdx);
90 const gp_Pnt& aCenter = myEntities.Value (aSensitiveIdx)->CenterOfGeometry();
91 Standard_Real aCenterCoord = 0.0;
92 aCenterCoord = theAxis == 0 ? aCenter.X() : (theAxis == 1 ? aCenter.Y() : aCenter.Z());
97 //=======================================================================
99 // purpose : Swaps items with indexes theIdx1 and theIdx2 in the vector
100 //=======================================================================
101 void Select3D_SensitiveWire::Swap (const Standard_Integer theIdx1,
102 const Standard_Integer theIdx2)
104 const Standard_Integer aSensitiveIdx1 = myEntityIndexes.Value (theIdx1);
105 const Standard_Integer aSensitiveIdx2 = myEntityIndexes.Value (theIdx2);
106 myEntityIndexes.ChangeValue (theIdx1) = aSensitiveIdx2;
107 myEntityIndexes.ChangeValue (theIdx2) = aSensitiveIdx1;
110 // =======================================================================
111 // function : overlapsElement
112 // purpose : Checks whether the entity with index theIdx overlaps the
113 // current selecting volume
114 // =======================================================================
115 Standard_Boolean Select3D_SensitiveWire::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
116 Standard_Integer theElemIdx,
117 Standard_Real& theMatchDepth)
119 const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theElemIdx);
120 const Handle(SelectBasics_SensitiveEntity)& aSeg = myEntities.Value (aSensitiveIdx);
121 SelectBasics_PickResult aMatchResult;
122 if (aSeg->Matches (theMgr, aMatchResult))
124 theMatchDepth = aMatchResult.Depth();
125 return Standard_True;
128 return Standard_False;
131 // =======================================================================
132 // function : elementIsInside
134 // =======================================================================
135 Standard_Boolean Select3D_SensitiveWire::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
136 const Standard_Integer theElemIdx)
138 SelectBasics_PickResult aMatchResult;
139 return myEntities.Value (myEntityIndexes.Value (theElemIdx))->Matches (theMgr, aMatchResult);
142 // =======================================================================
143 // function : distanceToCOG
144 // purpose : Calculates distance from the 3d projection of used-picked
145 // screen point to center of the geometry
146 // =======================================================================
147 Standard_Real Select3D_SensitiveWire::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
149 return theMgr.DistToGeometryCenter (myCenter);
152 //=======================================================================
153 //function : GetConnected
155 //=======================================================================
157 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected()
159 Handle(Select3D_SensitiveWire) aNewEntity = new Select3D_SensitiveWire (myOwnerId);
160 for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); anEntityIdx++)
161 aNewEntity->Add (myEntities(anEntityIdx)->GetConnected());
166 //=======================================================================
167 //function : GetEdges
168 //purpose : returns the sensitive edges stored in this wire
169 //=======================================================================
170 const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& Select3D_SensitiveWire::GetEdges()
175 //=============================================================================
176 // Function : GetLastDetected
178 //=============================================================================
179 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const
181 Handle(Select3D_SensitiveEntity) aRes;
183 if (myDetectedIdx >= 0 && myDetectedIdx < myEntities.Length())
185 const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (myDetectedIdx);
186 aRes = myEntities.Value (aSensitiveIdx);
192 //=======================================================================
195 //=======================================================================
196 void Select3D_SensitiveWire::Set (const Handle(SelectBasics_EntityOwner)& theOwnerId)
198 Select3D_SensitiveEntity::Set (theOwnerId);
200 // Set TheOwnerId for each element of sensitive wire
201 for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); ++anEntityIdx)
203 myEntities.Value (anEntityIdx)->Set (theOwnerId);
207 //=======================================================================
208 // function : BoundingBox
209 // purpose : Returns bounding box of the wire. If location
210 // transformation is set, it will be applied
211 //=======================================================================
212 Select3D_BndBox3d Select3D_SensitiveWire::BoundingBox()
214 if (myBndBox.IsValid())
217 for (Standard_Integer aSensitiveIdx = 0; aSensitiveIdx < myEntities.Length(); ++aSensitiveIdx)
219 myBndBox.Combine (myEntities.Value (aSensitiveIdx)->BoundingBox());
225 //=======================================================================
226 // function : CenterOfGeometry
227 // purpose : Returns center of the wire. If location transformation
228 // is set, it will be applied
229 //=======================================================================
230 gp_Pnt Select3D_SensitiveWire::CenterOfGeometry() const