0027317: Some visualisation tests failed because of exceptions generated by FP signals.
[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
90//=======================================================================
91//function : Destructor
92//purpose :
93//=======================================================================
94MeshVS_CommonSensitiveEntity::~MeshVS_CommonSensitiveEntity()
95{
96 myDataSource.Nullify();
97 myItemIndexes.Clear();
98}
99
100//=======================================================================
101//function : NbSubElements
102//purpose :
103//=======================================================================
104Standard_Integer MeshVS_CommonSensitiveEntity::NbSubElements()
105{
106 return myItemIndexes.Size();
107}
108
109//=======================================================================
110//function : Size
111//purpose :
112//=======================================================================
113Standard_Integer MeshVS_CommonSensitiveEntity::Size() const
114{
115 return myItemIndexes.Size();
116}
117
118//=======================================================================
119//function : getVertexByIndex
120//purpose :
121//=======================================================================
122gp_Pnt MeshVS_CommonSensitiveEntity::getVertexByIndex (const Standard_Integer theNodeIdx) const
123{
124 Standard_Real aCoordsBuf[3];
125 TColStd_Array1OfReal aCoords (aCoordsBuf[0], 1, 3);
126 Standard_Integer aNbNodes;
127 MeshVS_EntityType aType;
128 if (!myDataSource->GetGeom (theNodeIdx, Standard_False, aCoords, aNbNodes, aType))
129 {
130 return gp_Pnt();
131 }
132 return gp_Pnt (aCoords.Value (1), aCoords.Value (2), aCoords.Value (3));
133}
134
135//=======================================================================
136//function : Box
137//purpose :
138//=======================================================================
139Select3D_BndBox3d MeshVS_CommonSensitiveEntity::Box (const Standard_Integer theIdx) const
140{
141 const Standard_Integer anItemIdx = myItemIndexes.Value (theIdx);
142 Select3D_BndBox3d aBox;
143 if (mySelMethod == MeshVS_MSM_PRECISE)
144 {
145 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
146 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
147 Standard_Integer aNbNodes;
148 MeshVS_EntityType aType;
149 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
150 || aNbNodes == 0)
151 {
152 return aBox;
153 }
154
155 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
156 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
157 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
158 {
159 return aBox;
160 }
161
162 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
163 {
164 const SelectMgr_Vec3 aPnt (aCoords (3 * aNodeIdx - 2),
165 aCoords (3 * aNodeIdx - 1),
166 aCoords (3 * aNodeIdx));
167 aBox.Add (aPnt);
168 }
169 }
170 else if (mySelMethod == MeshVS_MSM_NODES)
171 {
172 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
173 aBox.Add (SelectMgr_Vec3 (aVert.X(), aVert.Y(), aVert.Z()));
174 }
175
176 return aBox;
177}
178
179//=======================================================================
180//function : Center
181//purpose :
182//=======================================================================
183Standard_Real MeshVS_CommonSensitiveEntity::Center (const Standard_Integer theIdx,
184 const Standard_Integer theAxis) const
185{
186 const Select3D_BndBox3d& aBox = Box (theIdx);
187 SelectMgr_Vec3 aCenter = (aBox.CornerMin () + aBox.CornerMax ()) * 0.5;
188
189 return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z());
190}
191
192//=======================================================================
193//function : Swap
194//purpose :
195//=======================================================================
196void MeshVS_CommonSensitiveEntity::Swap (const Standard_Integer theIdx1,
197 const Standard_Integer theIdx2)
198{
199 const Standard_Integer anItem1 = myItemIndexes.Value (theIdx1);
200 const Standard_Integer anItem2 = myItemIndexes.Value (theIdx2);
201 myItemIndexes.ChangeValue (theIdx1) = anItem2;
202 myItemIndexes.ChangeValue (theIdx2) = anItem1;
203}
204
205//=======================================================================
206//function : overlapsElement
207//purpose :
208//=======================================================================
209Standard_Boolean MeshVS_CommonSensitiveEntity::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
210 Standard_Integer theElemIdx,
211 Standard_Real& theMatchDepth)
212{
213 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
214 if (mySelMethod == MeshVS_MSM_PRECISE)
215 {
216 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
217 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
218 Standard_Integer aNbNodes;
219 MeshVS_EntityType aType;
220 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
221 || aNbNodes == 0)
222 {
223 return Standard_False;
224 }
225
226 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
227 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
228 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
229 {
230 return Standard_False;
231 }
232 if (aNbNodes == 3)
233 {
234 return theMgr.Overlaps (gp_Pnt (aCoords (1), aCoords (2), aCoords (3)),
235 gp_Pnt (aCoords (4), aCoords (5), aCoords (6)),
236 gp_Pnt (aCoords (7), aCoords (8), aCoords (9)),
237 Select3D_TOS_INTERIOR, theMatchDepth);
238 }
239
240 MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
241 TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
242 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
243 {
244 aFacePnts.SetValue (aNodeIdx, gp_Pnt (aCoords (3 * aNodeIdx - 2),
245 aCoords (3 * aNodeIdx - 1),
246 aCoords (3 * aNodeIdx)));
247 }
248 return theMgr.Overlaps (aFacePnts, Select3D_TOS_INTERIOR, theMatchDepth);
249 }
250 else if (mySelMethod == MeshVS_MSM_NODES)
251 {
252 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
253 return theMgr.Overlaps (aVert, theMatchDepth);
254 }
255 return Standard_False;
256}
257
258//=======================================================================
259//function : elementIsInside
260//purpose :
261//=======================================================================
262Standard_Boolean MeshVS_CommonSensitiveEntity::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
263 const Standard_Integer theElemIdx)
264{
265 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
266 if (mySelMethod == MeshVS_MSM_PRECISE)
267 {
268 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
269 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
270 Standard_Integer aNbNodes;
271 MeshVS_EntityType aType;
272 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
273 || aNbNodes == 0)
274 {
275 return Standard_False;
276 }
277
278 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
279 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
280 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
281 {
282 return Standard_False;
283 }
284
285 MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
286 TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
287 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; ++aNodeIdx)
288 {
289 const gp_Pnt aPnt (aCoords (3 * aNodeIdx - 2),
290 aCoords (3 * aNodeIdx - 1),
291 aCoords (3 * aNodeIdx));
292 if (!theMgr.Overlaps (aPnt))
293 {
294 return Standard_False;
295 }
296 }
297 return Standard_True;
298 }
299 else if (mySelMethod == MeshVS_MSM_NODES)
300 {
301 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
302 return theMgr.Overlaps (aVert);
303 }
304 return Standard_False;
305}
306
307//=======================================================================
308//function : distanceToCOG
309//purpose :
310//=======================================================================
311Standard_Real MeshVS_CommonSensitiveEntity::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
312{
313 return theMgr.DistToGeometryCenter (myCOG);
314}
315
316//=======================================================================
317//function : BoundingBox
318//purpose :
319//=======================================================================
320Select3D_BndBox3d MeshVS_CommonSensitiveEntity::BoundingBox()
321{
322 return myBndBox;
323}
41e08b4d 324
325//=======================================================================
326//function : CenterOfGeometry
327//purpose :
328//=======================================================================
329gp_Pnt MeshVS_CommonSensitiveEntity::CenterOfGeometry() const
330{
331 return myCOG;
332}