0029938: Visualization - SelectMgr_ViewerSelector::PickedPoint() should return point...
[occt.git] / src / MeshVS / MeshVS_CommonSensitiveEntity.cxx
CommitLineData
114b7bf1 1// Created on: 2016-02-18
2// Created by: Varvara POSKONINA
3// Copyright (c) 2016 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <MeshVS_CommonSensitiveEntity.hxx>
17
18#include <MeshVS_Buffer.hxx>
19#include <MeshVS_Drawer.hxx>
20#include <MeshVS_DrawerAttribute.hxx>
21#include <TColStd_PackedMapOfInteger.hxx>
22#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
23
24IMPLEMENT_STANDARD_RTTIEXT (MeshVS_CommonSensitiveEntity, Select3D_SensitiveSet)
25
26//=======================================================================
27//function : Constructor
28//purpose :
29//=======================================================================
30MeshVS_CommonSensitiveEntity::MeshVS_CommonSensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwner,
31 const Handle(MeshVS_Mesh)& theParentMesh,
32 const MeshVS_MeshSelectionMethod theSelMethod)
33: Select3D_SensitiveSet (theOwner),
34 myDataSource (theParentMesh->GetDataSource()),
35 mySelMethod (theSelMethod)
36{
37 theParentMesh->GetDrawer()->GetInteger (MeshVS_DA_MaxFaceNodes, myMaxFaceNodes);
38 Standard_ASSERT_RAISE (myMaxFaceNodes > 0,
39 "The maximal amount of nodes in a face must be greater than zero to create sensitive entity");
40 gp_XYZ aCenter (0.0, 0.0, 0.0);
41
42 if (mySelMethod == MeshVS_MSM_NODES)
43 {
44 Standard_Integer aNbSelectableNodes = 0;
45 const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes();
46 for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
47 {
48 const Standard_Integer aNodeIdx = aNodesIter.Key();
49 if (theParentMesh->IsSelectableNode (aNodeIdx))
50 {
51 const gp_Pnt aVertex = getVertexByIndex (aNodeIdx);
52 aCenter += aVertex.XYZ();
53 myBndBox.Add (SelectMgr_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
54 ++aNbSelectableNodes;
55 myItemIndexes.Append (aNodeIdx);
56 }
57 }
58
59 // increase sensitivity for vertices detection
60 SetSensitivityFactor (8);
61 myCOG = aCenter / aNbSelectableNodes;
62 }
63 else if (mySelMethod == MeshVS_MSM_PRECISE)
64 {
65 const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes();
66 for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
67 {
68 const Standard_Integer aNodeIdx = aNodesIter.Key();
69 const gp_Pnt aVertex = getVertexByIndex (aNodeIdx);
70 aCenter += aVertex.XYZ();
71 myBndBox.Add (SelectMgr_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
72 }
73 myCOG = aCenter / anAllNodesMap.Extent();
74
75 const TColStd_PackedMapOfInteger& anAllElementsMap = myDataSource->GetAllElements();
76 MeshVS_EntityType aType;
77 for (TColStd_MapIteratorOfPackedMapOfInteger anElemIter (anAllElementsMap); anElemIter.More(); anElemIter.Next())
78 {
79 const Standard_Integer anElemIdx = anElemIter.Key();
80 if (theParentMesh->IsSelectableElem (anElemIdx)
81 && myDataSource->GetGeomType (anElemIdx, Standard_True, aType)
82 && aType == MeshVS_ET_Face)
83 {
84 myItemIndexes.Append (anElemIdx);
85 }
86 }
87 }
88}
89
834f2897 90//=======================================================================
91//function : Constructor
92//purpose :
93//=======================================================================
94MeshVS_CommonSensitiveEntity::MeshVS_CommonSensitiveEntity (const MeshVS_CommonSensitiveEntity& theOther)
95: Select3D_SensitiveSet (theOther.myOwnerId),
96 myDataSource (theOther.myDataSource),
97 myItemIndexes (theOther.myItemIndexes),
98 mySelMethod (theOther.mySelMethod),
99 myMaxFaceNodes (theOther.myMaxFaceNodes),
100 myCOG (theOther.myCOG),
101 myBndBox (theOther.myBndBox)
102{
103 //
104}
105
114b7bf1 106//=======================================================================
107//function : Destructor
108//purpose :
109//=======================================================================
110MeshVS_CommonSensitiveEntity::~MeshVS_CommonSensitiveEntity()
111{
112 myDataSource.Nullify();
113 myItemIndexes.Clear();
114}
115
116//=======================================================================
117//function : NbSubElements
118//purpose :
119//=======================================================================
120Standard_Integer MeshVS_CommonSensitiveEntity::NbSubElements()
121{
122 return myItemIndexes.Size();
123}
124
125//=======================================================================
126//function : Size
127//purpose :
128//=======================================================================
129Standard_Integer MeshVS_CommonSensitiveEntity::Size() const
130{
131 return myItemIndexes.Size();
132}
133
134//=======================================================================
135//function : getVertexByIndex
136//purpose :
137//=======================================================================
138gp_Pnt MeshVS_CommonSensitiveEntity::getVertexByIndex (const Standard_Integer theNodeIdx) const
139{
140 Standard_Real aCoordsBuf[3];
141 TColStd_Array1OfReal aCoords (aCoordsBuf[0], 1, 3);
142 Standard_Integer aNbNodes;
143 MeshVS_EntityType aType;
144 if (!myDataSource->GetGeom (theNodeIdx, Standard_False, aCoords, aNbNodes, aType))
145 {
146 return gp_Pnt();
147 }
148 return gp_Pnt (aCoords.Value (1), aCoords.Value (2), aCoords.Value (3));
149}
150
151//=======================================================================
152//function : Box
153//purpose :
154//=======================================================================
155Select3D_BndBox3d MeshVS_CommonSensitiveEntity::Box (const Standard_Integer theIdx) const
156{
157 const Standard_Integer anItemIdx = myItemIndexes.Value (theIdx);
158 Select3D_BndBox3d aBox;
159 if (mySelMethod == MeshVS_MSM_PRECISE)
160 {
161 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
162 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
163 Standard_Integer aNbNodes;
164 MeshVS_EntityType aType;
165 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
166 || aNbNodes == 0)
167 {
168 return aBox;
169 }
170
171 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
172 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
173 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
174 {
175 return aBox;
176 }
177
178 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
179 {
180 const SelectMgr_Vec3 aPnt (aCoords (3 * aNodeIdx - 2),
181 aCoords (3 * aNodeIdx - 1),
182 aCoords (3 * aNodeIdx));
183 aBox.Add (aPnt);
184 }
185 }
186 else if (mySelMethod == MeshVS_MSM_NODES)
187 {
188 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
189 aBox.Add (SelectMgr_Vec3 (aVert.X(), aVert.Y(), aVert.Z()));
190 }
191
192 return aBox;
193}
194
195//=======================================================================
196//function : Center
197//purpose :
198//=======================================================================
199Standard_Real MeshVS_CommonSensitiveEntity::Center (const Standard_Integer theIdx,
200 const Standard_Integer theAxis) const
201{
202 const Select3D_BndBox3d& aBox = Box (theIdx);
203 SelectMgr_Vec3 aCenter = (aBox.CornerMin () + aBox.CornerMax ()) * 0.5;
204
205 return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z());
206}
207
208//=======================================================================
209//function : Swap
210//purpose :
211//=======================================================================
212void MeshVS_CommonSensitiveEntity::Swap (const Standard_Integer theIdx1,
213 const Standard_Integer theIdx2)
214{
215 const Standard_Integer anItem1 = myItemIndexes.Value (theIdx1);
216 const Standard_Integer anItem2 = myItemIndexes.Value (theIdx2);
217 myItemIndexes.ChangeValue (theIdx1) = anItem2;
218 myItemIndexes.ChangeValue (theIdx2) = anItem1;
219}
220
221//=======================================================================
222//function : overlapsElement
223//purpose :
224//=======================================================================
225Standard_Boolean MeshVS_CommonSensitiveEntity::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
226 Standard_Integer theElemIdx,
17017555 227 SelectBasics_PickResult& thePickResult)
114b7bf1 228{
229 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
230 if (mySelMethod == MeshVS_MSM_PRECISE)
231 {
232 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
233 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
234 Standard_Integer aNbNodes;
235 MeshVS_EntityType aType;
236 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
237 || aNbNodes == 0)
238 {
239 return Standard_False;
240 }
241
242 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
243 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
244 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
245 {
246 return Standard_False;
247 }
248 if (aNbNodes == 3)
249 {
250 return theMgr.Overlaps (gp_Pnt (aCoords (1), aCoords (2), aCoords (3)),
251 gp_Pnt (aCoords (4), aCoords (5), aCoords (6)),
252 gp_Pnt (aCoords (7), aCoords (8), aCoords (9)),
17017555 253 Select3D_TOS_INTERIOR, thePickResult);
114b7bf1 254 }
255
256 MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
257 TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
258 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
259 {
260 aFacePnts.SetValue (aNodeIdx, gp_Pnt (aCoords (3 * aNodeIdx - 2),
261 aCoords (3 * aNodeIdx - 1),
262 aCoords (3 * aNodeIdx)));
263 }
17017555 264 return theMgr.Overlaps (aFacePnts, Select3D_TOS_INTERIOR, thePickResult);
114b7bf1 265 }
266 else if (mySelMethod == MeshVS_MSM_NODES)
267 {
268 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
17017555 269 return theMgr.Overlaps (aVert, thePickResult);
114b7bf1 270 }
271 return Standard_False;
272}
273
274//=======================================================================
275//function : elementIsInside
276//purpose :
277//=======================================================================
278Standard_Boolean MeshVS_CommonSensitiveEntity::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
279 const Standard_Integer theElemIdx)
280{
281 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
282 if (mySelMethod == MeshVS_MSM_PRECISE)
283 {
284 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
285 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
286 Standard_Integer aNbNodes;
287 MeshVS_EntityType aType;
288 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
289 || aNbNodes == 0)
290 {
291 return Standard_False;
292 }
293
294 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
295 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
296 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
297 {
298 return Standard_False;
299 }
300
301 MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
302 TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
303 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; ++aNodeIdx)
304 {
305 const gp_Pnt aPnt (aCoords (3 * aNodeIdx - 2),
306 aCoords (3 * aNodeIdx - 1),
307 aCoords (3 * aNodeIdx));
308 if (!theMgr.Overlaps (aPnt))
309 {
310 return Standard_False;
311 }
312 }
313 return Standard_True;
314 }
315 else if (mySelMethod == MeshVS_MSM_NODES)
316 {
317 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
318 return theMgr.Overlaps (aVert);
319 }
320 return Standard_False;
321}
322
323//=======================================================================
324//function : distanceToCOG
325//purpose :
326//=======================================================================
327Standard_Real MeshVS_CommonSensitiveEntity::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
328{
329 return theMgr.DistToGeometryCenter (myCOG);
330}
331
332//=======================================================================
333//function : BoundingBox
334//purpose :
335//=======================================================================
336Select3D_BndBox3d MeshVS_CommonSensitiveEntity::BoundingBox()
337{
338 return myBndBox;
339}
41e08b4d 340
341//=======================================================================
342//function : CenterOfGeometry
343//purpose :
344//=======================================================================
345gp_Pnt MeshVS_CommonSensitiveEntity::CenterOfGeometry() const
346{
347 return myCOG;
348}