1 // Created on: 2016-02-18
2 // Created by: Varvara POSKONINA
3 // Copyright (c) 2016 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <MeshVS_CommonSensitiveEntity.hxx>
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>
24 IMPLEMENT_STANDARD_RTTIEXT (MeshVS_CommonSensitiveEntity, Select3D_SensitiveSet)
26 //=======================================================================
27 //function : Constructor
29 //=======================================================================
30 MeshVS_CommonSensitiveEntity::MeshVS_CommonSensitiveEntity (const Handle(SelectMgr_EntityOwner)& theOwner,
31 const Handle(MeshVS_Mesh)& theParentMesh,
32 const MeshVS_MeshSelectionMethod theSelMethod)
33 : Select3D_SensitiveSet (theOwner),
34 myDataSource (theParentMesh->GetDataSource()),
35 mySelMethod (theSelMethod)
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);
42 if (mySelMethod == MeshVS_MSM_NODES)
44 Standard_Integer aNbSelectableNodes = 0;
45 const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes();
46 for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
48 const Standard_Integer aNodeIdx = aNodesIter.Key();
49 if (theParentMesh->IsSelectableNode (aNodeIdx))
51 const gp_Pnt aVertex = getVertexByIndex (aNodeIdx);
52 aCenter += aVertex.XYZ();
53 myBndBox.Add (SelectMgr_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
55 myItemIndexes.Append (aNodeIdx);
59 // increase sensitivity for vertices detection
60 SetSensitivityFactor (8);
61 myCOG = aCenter / aNbSelectableNodes;
63 else if (mySelMethod == MeshVS_MSM_PRECISE)
65 const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes();
66 for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
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()));
73 myCOG = aCenter / anAllNodesMap.Extent();
75 const TColStd_PackedMapOfInteger& anAllElementsMap = myDataSource->GetAllElements();
76 MeshVS_EntityType aType;
77 for (TColStd_MapIteratorOfPackedMapOfInteger anElemIter (anAllElementsMap); anElemIter.More(); anElemIter.Next())
79 const Standard_Integer anElemIdx = anElemIter.Key();
80 if (theParentMesh->IsSelectableElem (anElemIdx)
81 && myDataSource->GetGeomType (anElemIdx, Standard_True, aType)
82 && aType == MeshVS_ET_Face)
84 myItemIndexes.Append (anElemIdx);
90 //=======================================================================
91 //function : Constructor
93 //=======================================================================
94 MeshVS_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)
106 //=======================================================================
107 //function : Destructor
109 //=======================================================================
110 MeshVS_CommonSensitiveEntity::~MeshVS_CommonSensitiveEntity()
112 myDataSource.Nullify();
113 myItemIndexes.Clear();
116 //=======================================================================
117 //function : NbSubElements
119 //=======================================================================
120 Standard_Integer MeshVS_CommonSensitiveEntity::NbSubElements()
122 return myItemIndexes.Size();
125 //=======================================================================
128 //=======================================================================
129 Standard_Integer MeshVS_CommonSensitiveEntity::Size() const
131 return myItemIndexes.Size();
134 //=======================================================================
135 //function : getVertexByIndex
137 //=======================================================================
138 gp_Pnt MeshVS_CommonSensitiveEntity::getVertexByIndex (const Standard_Integer theNodeIdx) const
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))
148 return gp_Pnt (aCoords.Value (1), aCoords.Value (2), aCoords.Value (3));
151 //=======================================================================
154 //=======================================================================
155 Select3D_BndBox3d MeshVS_CommonSensitiveEntity::Box (const Standard_Integer theIdx) const
157 const Standard_Integer anItemIdx = myItemIndexes.Value (theIdx);
158 Select3D_BndBox3d aBox;
159 if (mySelMethod == MeshVS_MSM_PRECISE)
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)
171 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
172 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
173 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
178 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
180 const SelectMgr_Vec3 aPnt (aCoords (3 * aNodeIdx - 2),
181 aCoords (3 * aNodeIdx - 1),
182 aCoords (3 * aNodeIdx));
186 else if (mySelMethod == MeshVS_MSM_NODES)
188 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
189 aBox.Add (SelectMgr_Vec3 (aVert.X(), aVert.Y(), aVert.Z()));
195 //=======================================================================
198 //=======================================================================
199 Standard_Real MeshVS_CommonSensitiveEntity::Center (const Standard_Integer theIdx,
200 const Standard_Integer theAxis) const
202 const Select3D_BndBox3d& aBox = Box (theIdx);
203 SelectMgr_Vec3 aCenter = (aBox.CornerMin () + aBox.CornerMax ()) * 0.5;
205 return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z());
208 //=======================================================================
211 //=======================================================================
212 void MeshVS_CommonSensitiveEntity::Swap (const Standard_Integer theIdx1,
213 const Standard_Integer theIdx2)
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;
221 //=======================================================================
222 //function : overlapsElement
224 //=======================================================================
225 Standard_Boolean MeshVS_CommonSensitiveEntity::overlapsElement (SelectBasics_PickResult& thePickResult,
226 SelectBasics_SelectingVolumeManager& theMgr,
227 Standard_Integer theElemIdx,
228 Standard_Boolean theIsFullInside)
232 return Standard_True;
235 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
236 if (mySelMethod == MeshVS_MSM_PRECISE)
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)
245 return Standard_False;
248 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
249 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
250 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
252 return Standard_False;
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)),
259 Select3D_TOS_INTERIOR, thePickResult);
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++)
266 aFacePnts.SetValue (aNodeIdx, gp_Pnt (aCoords (3 * aNodeIdx - 2),
267 aCoords (3 * aNodeIdx - 1),
268 aCoords (3 * aNodeIdx)));
270 return theMgr.Overlaps (aFacePnts, Select3D_TOS_INTERIOR, thePickResult);
272 else if (mySelMethod == MeshVS_MSM_NODES)
274 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
275 return theMgr.Overlaps (aVert, thePickResult);
277 return Standard_False;
280 //=======================================================================
281 //function : elementIsInside
283 //=======================================================================
284 Standard_Boolean MeshVS_CommonSensitiveEntity::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
285 Standard_Integer theElemIdx,
286 Standard_Boolean theIsFullInside)
290 return Standard_True;
293 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
294 if (mySelMethod == MeshVS_MSM_PRECISE)
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)
303 return Standard_False;
306 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
307 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
308 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
310 return Standard_False;
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)
317 const gp_Pnt aPnt (aCoords (3 * aNodeIdx - 2),
318 aCoords (3 * aNodeIdx - 1),
319 aCoords (3 * aNodeIdx));
320 if (!theMgr.Overlaps (aPnt))
322 return Standard_False;
325 return Standard_True;
327 else if (mySelMethod == MeshVS_MSM_NODES)
329 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
330 return theMgr.Overlaps (aVert);
332 return Standard_False;
335 //=======================================================================
336 //function : distanceToCOG
338 //=======================================================================
339 Standard_Real MeshVS_CommonSensitiveEntity::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
341 return theMgr.DistToGeometryCenter (myCOG);
344 //=======================================================================
345 //function : BoundingBox
347 //=======================================================================
348 Select3D_BndBox3d MeshVS_CommonSensitiveEntity::BoundingBox()
353 //=======================================================================
354 //function : CenterOfGeometry
356 //=======================================================================
357 gp_Pnt MeshVS_CommonSensitiveEntity::CenterOfGeometry() const