0030963: Visualization, TKOpenGl - texture unit error during FFP global texture's...
[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//=======================================================================
0ef04197 30MeshVS_CommonSensitiveEntity::MeshVS_CommonSensitiveEntity (const Handle(SelectMgr_EntityOwner)& theOwner,
31 const Handle(MeshVS_Mesh)& theParentMesh,
32 const MeshVS_MeshSelectionMethod theSelMethod)
114b7bf1 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//=======================================================================
4a056d20 225Standard_Boolean MeshVS_CommonSensitiveEntity::overlapsElement (SelectBasics_PickResult& thePickResult,
226 SelectBasics_SelectingVolumeManager& theMgr,
114b7bf1 227 Standard_Integer theElemIdx,
4a056d20 228 Standard_Boolean theIsFullInside)
114b7bf1 229{
4a056d20 230 if (theIsFullInside)
231 {
232 return Standard_True;
233 }
234
114b7bf1 235 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
236 if (mySelMethod == MeshVS_MSM_PRECISE)
237 {
238 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
239 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
240 Standard_Integer aNbNodes;
241 MeshVS_EntityType aType;
242 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
243 || aNbNodes == 0)
244 {
245 return Standard_False;
246 }
247
248 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
249 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
250 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
251 {
252 return Standard_False;
253 }
254 if (aNbNodes == 3)
255 {
256 return theMgr.Overlaps (gp_Pnt (aCoords (1), aCoords (2), aCoords (3)),
257 gp_Pnt (aCoords (4), aCoords (5), aCoords (6)),
258 gp_Pnt (aCoords (7), aCoords (8), aCoords (9)),
17017555 259 Select3D_TOS_INTERIOR, thePickResult);
114b7bf1 260 }
261
262 MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
263 TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
264 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
265 {
266 aFacePnts.SetValue (aNodeIdx, gp_Pnt (aCoords (3 * aNodeIdx - 2),
267 aCoords (3 * aNodeIdx - 1),
268 aCoords (3 * aNodeIdx)));
269 }
17017555 270 return theMgr.Overlaps (aFacePnts, Select3D_TOS_INTERIOR, thePickResult);
114b7bf1 271 }
272 else if (mySelMethod == MeshVS_MSM_NODES)
273 {
274 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
17017555 275 return theMgr.Overlaps (aVert, thePickResult);
114b7bf1 276 }
277 return Standard_False;
278}
279
280//=======================================================================
281//function : elementIsInside
282//purpose :
283//=======================================================================
284Standard_Boolean MeshVS_CommonSensitiveEntity::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
4a056d20 285 Standard_Integer theElemIdx,
286 Standard_Boolean theIsFullInside)
114b7bf1 287{
4a056d20 288 if (theIsFullInside)
289 {
290 return Standard_True;
291 }
292
114b7bf1 293 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
294 if (mySelMethod == MeshVS_MSM_PRECISE)
295 {
296 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
297 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
298 Standard_Integer aNbNodes;
299 MeshVS_EntityType aType;
300 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
301 || aNbNodes == 0)
302 {
303 return Standard_False;
304 }
305
306 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
307 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
308 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
309 {
310 return Standard_False;
311 }
312
313 MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
314 TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
315 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; ++aNodeIdx)
316 {
317 const gp_Pnt aPnt (aCoords (3 * aNodeIdx - 2),
318 aCoords (3 * aNodeIdx - 1),
319 aCoords (3 * aNodeIdx));
320 if (!theMgr.Overlaps (aPnt))
321 {
322 return Standard_False;
323 }
324 }
325 return Standard_True;
326 }
327 else if (mySelMethod == MeshVS_MSM_NODES)
328 {
329 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
330 return theMgr.Overlaps (aVert);
331 }
332 return Standard_False;
333}
334
335//=======================================================================
336//function : distanceToCOG
337//purpose :
338//=======================================================================
339Standard_Real MeshVS_CommonSensitiveEntity::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
340{
341 return theMgr.DistToGeometryCenter (myCOG);
342}
343
344//=======================================================================
345//function : BoundingBox
346//purpose :
347//=======================================================================
348Select3D_BndBox3d MeshVS_CommonSensitiveEntity::BoundingBox()
349{
350 return myBndBox;
351}
41e08b4d 352
353//=======================================================================
354//function : CenterOfGeometry
355//purpose :
356//=======================================================================
357gp_Pnt MeshVS_CommonSensitiveEntity::CenterOfGeometry() const
358{
359 return myCOG;
360}