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_PickResult& thePickResult,
116 SelectBasics_SelectingVolumeManager& theMgr,
117 Standard_Integer theElemIdx,
120 const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theElemIdx);
121 const Handle(SelectBasics_SensitiveEntity)& aSeg = myEntities.Value (aSensitiveIdx);
122 return aSeg->Matches (theMgr, thePickResult);
125 // =======================================================================
126 // function : elementIsInside
128 // =======================================================================
129 Standard_Boolean Select3D_SensitiveWire::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
130 Standard_Integer theElemIdx,
133 SelectBasics_PickResult aMatchResult;
134 return myEntities.Value (myEntityIndexes.Value (theElemIdx))->Matches (theMgr, aMatchResult);
137 // =======================================================================
138 // function : distanceToCOG
139 // purpose : Calculates distance from the 3d projection of used-picked
140 // screen point to center of the geometry
141 // =======================================================================
142 Standard_Real Select3D_SensitiveWire::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
144 return theMgr.DistToGeometryCenter (myCenter);
147 //=======================================================================
148 //function : GetConnected
150 //=======================================================================
152 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected()
154 Handle(Select3D_SensitiveWire) aNewEntity = new Select3D_SensitiveWire (myOwnerId);
155 for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); anEntityIdx++)
156 aNewEntity->Add (myEntities(anEntityIdx)->GetConnected());
161 //=======================================================================
162 //function : GetEdges
163 //purpose : returns the sensitive edges stored in this wire
164 //=======================================================================
165 const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& Select3D_SensitiveWire::GetEdges()
170 //=============================================================================
171 // Function : GetLastDetected
173 //=============================================================================
174 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const
176 Handle(Select3D_SensitiveEntity) aRes;
178 if (myDetectedIdx >= 0 && myDetectedIdx < myEntities.Length())
180 const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (myDetectedIdx);
181 aRes = myEntities.Value (aSensitiveIdx);
187 //=======================================================================
190 //=======================================================================
191 void Select3D_SensitiveWire::Set (const Handle(SelectBasics_EntityOwner)& theOwnerId)
193 Select3D_SensitiveEntity::Set (theOwnerId);
195 // Set TheOwnerId for each element of sensitive wire
196 for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); ++anEntityIdx)
198 myEntities.Value (anEntityIdx)->Set (theOwnerId);
202 //=======================================================================
203 // function : BoundingBox
204 // purpose : Returns bounding box of the wire. If location
205 // transformation is set, it will be applied
206 //=======================================================================
207 Select3D_BndBox3d Select3D_SensitiveWire::BoundingBox()
209 if (myBndBox.IsValid())
212 for (Standard_Integer aSensitiveIdx = 0; aSensitiveIdx < myEntities.Length(); ++aSensitiveIdx)
214 myBndBox.Combine (myEntities.Value (aSensitiveIdx)->BoundingBox());
220 //=======================================================================
221 // function : CenterOfGeometry
222 // purpose : Returns center of the wire. If location transformation
223 // is set, it will be applied
224 //=======================================================================
225 gp_Pnt Select3D_SensitiveWire::CenterOfGeometry() const