1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <Select3D_SensitivePoly.hxx>
16 IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePoly,Select3D_SensitiveSet)
18 //==================================================
19 // Function: Select3D_SensitivePoly
21 //==================================================
22 Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId,
23 const TColgp_Array1OfPnt& thePoints,
24 const Standard_Boolean theIsBVHEnabled)
25 : Select3D_SensitiveSet (theOwnerId),
26 myPolyg (thePoints.Upper() - thePoints.Lower() + 1)
28 Standard_Integer aLowerIdx = thePoints.Lower();
29 Standard_Integer anUpperIdx = thePoints.Upper();
30 gp_XYZ aPntSum (0.0, 0.0, 0.0);
32 Select3D_BndBox3d aBndBox;
33 for (Standard_Integer aIdx = aLowerIdx; aIdx <= anUpperIdx; ++aIdx)
35 aPntSum += thePoints.Value (aIdx).XYZ();
36 const SelectMgr_Vec3 aPnt (thePoints.Value (aIdx).X(),
37 thePoints.Value (aIdx).Y(),
38 thePoints.Value (aIdx).Z());
40 myPolyg.SetPnt (aIdx - aLowerIdx, thePoints.Value (aIdx));
44 myCOG = aPntSum / myPolyg.Size();
48 const Standard_Integer aPntsNum = myPolyg.Size();
49 mySegmentIndexes = new TColStd_HArray1OfInteger (0, aPntsNum - 2);
50 for (Standard_Integer aSegmIter = 0; aSegmIter < aPntsNum - 1; ++aSegmIter)
52 mySegmentIndexes->SetValue (aSegmIter, aSegmIter);
56 myIsComputed = Standard_True;
59 //==================================================
60 // Function: Select3D_SensitivePoly
62 //==================================================
63 Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId,
64 const Handle(TColgp_HArray1OfPnt)& thePoints,
65 const Standard_Boolean theIsBVHEnabled)
66 : Select3D_SensitiveSet (theOwnerId),
67 myPolyg (thePoints->Upper() - thePoints->Lower() + 1)
69 Standard_Integer aLowerIdx = thePoints->Lower();
70 Standard_Integer anUpperIdx = thePoints->Upper();
71 gp_XYZ aPntSum (0.0, 0.0, 0.0);
73 Select3D_BndBox3d aBndBox;
74 for (Standard_Integer aIdx = aLowerIdx; aIdx <= anUpperIdx; ++aIdx)
76 aPntSum += thePoints->Value (aIdx).XYZ();
77 const SelectMgr_Vec3 aPnt (thePoints->Value (aIdx).X(),
78 thePoints->Value (aIdx).Y(),
79 thePoints->Value (aIdx).Z());
81 myPolyg.SetPnt (aIdx - aLowerIdx, thePoints->Value (aIdx));
85 myCOG = aPntSum / myPolyg.Size();
89 const Standard_Integer aPntsNum = myPolyg.Size();
90 mySegmentIndexes = new TColStd_HArray1OfInteger (0, aPntsNum - 2);
91 for (Standard_Integer aSegmIter = 0; aSegmIter < aPntsNum - 1; ++aSegmIter)
93 mySegmentIndexes->SetValue (aSegmIter, aSegmIter);
97 myIsComputed = Standard_True;
100 //==================================================
101 // Function: Creation
103 //==================================================
104 Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId,
105 const Standard_Boolean theIsBVHEnabled,
106 const Standard_Integer theNbPnts)
107 : Select3D_SensitiveSet (theOwnerId),
112 mySegmentIndexes = new TColStd_HArray1OfInteger (0, theNbPnts - 2);
113 for (Standard_Integer aIdx = 0; aIdx < theNbPnts - 1; ++aIdx)
115 mySegmentIndexes->SetValue (aIdx, aIdx);
118 myCOG = gp_Pnt (RealLast(), RealLast(), RealLast());
119 myIsComputed = Standard_False;
122 //==================================================
123 // function : BoundingBox
124 // purpose : Returns bounding box of a polygon. If location
125 // transformation is set, it will be applied
126 //==================================================
127 Select3D_BndBox3d Select3D_SensitivePoly::BoundingBox()
129 if (myBndBox.IsValid())
132 Select3D_BndBox3d aBndBox;
133 for (Standard_Integer aPntIter = 0; aPntIter < myPolyg.Size(); ++aPntIter)
135 SelectMgr_Vec3 aPnt (myPolyg.Pnt (aPntIter).x,
136 myPolyg.Pnt (aPntIter).y,
137 myPolyg.Pnt (aPntIter).z);
146 //==================================================
148 // Purpose : Returns the amount of segments of
150 //==================================================
151 Standard_Integer Select3D_SensitivePoly::Size() const
153 if (!mySegmentIndexes.IsNull())
154 return mySegmentIndexes->Length();
159 //==================================================
161 // Purpose : Returns bounding box of segment with
163 //==================================================
164 Select3D_BndBox3d Select3D_SensitivePoly::Box (const Standard_Integer theIdx) const
166 if (mySegmentIndexes.IsNull())
167 return Select3D_BndBox3d (SelectMgr_Vec3 (RealLast()));
169 const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theIdx);
170 gp_Pnt aPnt1 = myPolyg.Pnt3d (aSegmentIdx);
171 gp_Pnt aPnt2 = myPolyg.Pnt3d (aSegmentIdx + 1);
173 const SelectMgr_Vec3 aMinPnt (Min (aPnt1.X(), aPnt2.X()),
174 Min (aPnt1.Y(), aPnt2.Y()),
175 Min (aPnt1.Z(), aPnt2.Z()));
176 const SelectMgr_Vec3 aMaxPnt (Max (aPnt1.X(), aPnt2.X()),
177 Max (aPnt1.Y(), aPnt2.Y()),
178 Max (aPnt1.Z(), aPnt2.Z()));
180 return Select3D_BndBox3d (aMinPnt, aMaxPnt);
183 //==================================================
185 // Purpose : Returns geometry center of sensitive
186 // entity index theIdx in the vector along
187 // the given axis theAxis
188 //==================================================
189 Standard_Real Select3D_SensitivePoly::Center (const Standard_Integer theIdx,
190 const Standard_Integer theAxis) const
192 if (mySegmentIndexes.IsNull())
195 const Select3D_BndBox3d aBndBox = Box (theIdx);
196 const SelectMgr_Vec3 aCenter = (aBndBox.CornerMin() + aBndBox.CornerMax()) * 0.5;
197 return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z());
200 //==================================================
202 // Purpose : Swaps items with indexes theIdx1 and
203 // theIdx2 in the vector
204 //==================================================
205 void Select3D_SensitivePoly::Swap (const Standard_Integer theIdx1,
206 const Standard_Integer theIdx2)
208 if (mySegmentIndexes.IsNull())
211 const Standard_Integer aSegmentIdx1 = mySegmentIndexes->Value (theIdx1);
212 const Standard_Integer aSegmentIdx2 = mySegmentIndexes->Value (theIdx2);
213 mySegmentIndexes->ChangeValue (theIdx1) = aSegmentIdx2;
214 mySegmentIndexes->ChangeValue (theIdx2) = aSegmentIdx1;
217 //==================================================
218 // Function: overlapsElement
219 // Purpose : Checks whether the segment with index
220 // theIdx overlaps the current selecting
222 //==================================================
223 Standard_Boolean Select3D_SensitivePoly::overlapsElement (SelectBasics_PickResult& thePickResult,
224 SelectBasics_SelectingVolumeManager& theMgr,
225 Standard_Integer theElemIdx,
226 Standard_Boolean theIsFullInside)
228 if (mySegmentIndexes.IsNull())
230 return Standard_False;
232 else if (theIsFullInside)
234 return Standard_True;
237 const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
238 gp_Pnt aPnt1 = myPolyg.Pnt3d (aSegmentIdx);
239 gp_Pnt aPnt2 = myPolyg.Pnt3d (aSegmentIdx + 1);
240 return theMgr.Overlaps (aPnt1, aPnt2, thePickResult);
243 //==================================================
244 // Function : elementIsInside
246 //==================================================
247 Standard_Boolean Select3D_SensitivePoly::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
248 Standard_Integer theElemIdx,
249 Standard_Boolean theIsFullInside)
253 return Standard_True;
256 const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
257 return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0))
258 && theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1));
261 //==================================================
262 // Function: distanceToCOG
263 // Purpose : Calculates distance from the 3d
264 // projection of used-picked screen point
265 // to center of the geometry
266 //==================================================
267 Standard_Real Select3D_SensitivePoly::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
271 gp_XYZ aCenter (0.0, 0.0, 0.0);
272 for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx)
274 aCenter += myPolyg.Pnt (aIdx);
276 myCOG = aCenter / myPolyg.Size();
277 myIsComputed = Standard_True;
280 return theMgr.DistToGeometryCenter (myCOG);
283 //==================================================
284 // Function: NbSubElements
285 // Purpose : Returns the amount of segments in poly
286 //==================================================
287 Standard_Integer Select3D_SensitivePoly::NbSubElements()
289 return myPolyg.Size();
292 //==================================================
293 // Function: CenterOfGeometry
294 // Purpose : Returns center of the point set. If
295 // location transformation is set, it will
297 //==================================================
298 gp_Pnt Select3D_SensitivePoly::CenterOfGeometry() const
302 gp_XYZ aCenter (0.0, 0.0, 0.0);
303 for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx)
305 aCenter += myPolyg.Pnt (aIdx);
307 myCOG = aCenter / myPolyg.Size();
308 myIsComputed = Standard_True;