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)
38 theParentMesh->GetDrawer()->GetInteger (MeshVS_DA_MaxFaceNodes, myMaxFaceNodes);
39 Standard_ASSERT_RAISE (myMaxFaceNodes > 0,
40 "The maximal amount of nodes in a face must be greater than zero to create sensitive entity");
41 gp_XYZ aCenter (0.0, 0.0, 0.0);
43 if (mySelMethod == MeshVS_MSM_NODES)
45 Standard_Integer aNbSelectableNodes = 0;
46 const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes();
47 for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
49 const Standard_Integer aNodeIdx = aNodesIter.Key();
50 if (theParentMesh->IsSelectableNode (aNodeIdx))
52 const gp_Pnt aVertex = getVertexByIndex (aNodeIdx);
53 aCenter += aVertex.XYZ();
54 myBndBox.Add (SelectMgr_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
56 myItemIndexes.Append (aNodeIdx);
60 // increase sensitivity for vertices detection
61 SetSensitivityFactor (8);
62 myCOG = aCenter / aNbSelectableNodes;
64 else if (mySelMethod == MeshVS_MSM_PRECISE)
66 const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes();
67 for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
69 const Standard_Integer aNodeIdx = aNodesIter.Key();
70 const gp_Pnt aVertex = getVertexByIndex (aNodeIdx);
71 aCenter += aVertex.XYZ();
72 myBndBox.Add (SelectMgr_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
74 myCOG = aCenter / anAllNodesMap.Extent();
76 const TColStd_PackedMapOfInteger& anAllElementsMap = myDataSource->GetAllElements();
77 MeshVS_EntityType aType = MeshVS_ET_NONE;
78 for (TColStd_MapIteratorOfPackedMapOfInteger anElemIter (anAllElementsMap); anElemIter.More(); anElemIter.Next())
80 const Standard_Integer anElemIdx = anElemIter.Key();
81 if (theParentMesh->IsSelectableElem (anElemIdx)
82 && myDataSource->GetGeomType (anElemIdx, Standard_True, aType)
83 && aType == MeshVS_ET_Face)
85 myItemIndexes.Append (anElemIdx);
91 //=======================================================================
92 //function : Constructor
94 //=======================================================================
95 MeshVS_CommonSensitiveEntity::MeshVS_CommonSensitiveEntity (const MeshVS_CommonSensitiveEntity& theOther)
96 : Select3D_SensitiveSet (theOther.myOwnerId),
97 myDataSource (theOther.myDataSource),
98 myItemIndexes (theOther.myItemIndexes),
99 mySelMethod (theOther.mySelMethod),
100 myMaxFaceNodes (theOther.myMaxFaceNodes),
101 myCOG (theOther.myCOG),
102 myBndBox (theOther.myBndBox)
107 //=======================================================================
108 //function : Destructor
110 //=======================================================================
111 MeshVS_CommonSensitiveEntity::~MeshVS_CommonSensitiveEntity()
113 myDataSource.Nullify();
114 myItemIndexes.Clear();
117 //=======================================================================
118 //function : NbSubElements
120 //=======================================================================
121 Standard_Integer MeshVS_CommonSensitiveEntity::NbSubElements() const
123 return myItemIndexes.Size();
126 //=======================================================================
129 //=======================================================================
130 Standard_Integer MeshVS_CommonSensitiveEntity::Size() const
132 return myItemIndexes.Size();
135 //=======================================================================
136 //function : getVertexByIndex
138 //=======================================================================
139 gp_Pnt MeshVS_CommonSensitiveEntity::getVertexByIndex (const Standard_Integer theNodeIdx) const
141 Standard_Real aCoordsBuf[3] = {};
142 TColStd_Array1OfReal aCoords (aCoordsBuf[0], 1, 3);
143 Standard_Integer aNbNodes = 0;
144 MeshVS_EntityType aType = MeshVS_ET_NONE;
145 if (!myDataSource->GetGeom (theNodeIdx, Standard_False, aCoords, aNbNodes, aType))
149 return gp_Pnt (aCoords.Value (1), aCoords.Value (2), aCoords.Value (3));
152 //=======================================================================
155 //=======================================================================
156 Select3D_BndBox3d MeshVS_CommonSensitiveEntity::Box (const Standard_Integer theIdx) const
158 const Standard_Integer anItemIdx = myItemIndexes.Value (theIdx);
159 Select3D_BndBox3d aBox;
160 if (mySelMethod == MeshVS_MSM_PRECISE)
162 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
163 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
164 Standard_Integer aNbNodes = 0;
165 MeshVS_EntityType aType = MeshVS_ET_NONE;
166 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
172 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
173 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
174 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
179 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
181 const SelectMgr_Vec3 aPnt (aCoords (3 * aNodeIdx - 2),
182 aCoords (3 * aNodeIdx - 1),
183 aCoords (3 * aNodeIdx));
187 else if (mySelMethod == MeshVS_MSM_NODES)
189 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
190 aBox.Add (SelectMgr_Vec3 (aVert.X(), aVert.Y(), aVert.Z()));
196 //=======================================================================
199 //=======================================================================
200 Standard_Real MeshVS_CommonSensitiveEntity::Center (const Standard_Integer theIdx,
201 const Standard_Integer theAxis) const
203 const Select3D_BndBox3d& aBox = Box (theIdx);
204 SelectMgr_Vec3 aCenter = (aBox.CornerMin () + aBox.CornerMax ()) * 0.5;
206 return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z());
209 //=======================================================================
212 //=======================================================================
213 void MeshVS_CommonSensitiveEntity::Swap (const Standard_Integer theIdx1,
214 const Standard_Integer theIdx2)
216 const Standard_Integer anItem1 = myItemIndexes.Value (theIdx1);
217 const Standard_Integer anItem2 = myItemIndexes.Value (theIdx2);
218 myItemIndexes.ChangeValue (theIdx1) = anItem2;
219 myItemIndexes.ChangeValue (theIdx2) = anItem1;
222 //=======================================================================
223 //function : overlapsElement
225 //=======================================================================
226 Standard_Boolean MeshVS_CommonSensitiveEntity::overlapsElement (SelectBasics_PickResult& thePickResult,
227 SelectBasics_SelectingVolumeManager& theMgr,
228 Standard_Integer theElemIdx,
229 Standard_Boolean theIsFullInside)
233 return Standard_True;
236 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
237 if (mySelMethod == MeshVS_MSM_PRECISE)
239 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
240 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
241 Standard_Integer aNbNodes = 0;
242 MeshVS_EntityType aType = MeshVS_ET_NONE;
243 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
246 return Standard_False;
249 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
250 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
251 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
253 return Standard_False;
257 return theMgr.OverlapsTriangle (gp_Pnt (aCoords (1), aCoords (2), aCoords (3)),
258 gp_Pnt (aCoords (4), aCoords (5), aCoords (6)),
259 gp_Pnt (aCoords (7), aCoords (8), aCoords (9)),
260 Select3D_TOS_INTERIOR, thePickResult);
263 MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
264 TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
265 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
267 aFacePnts.SetValue (aNodeIdx, gp_Pnt (aCoords (3 * aNodeIdx - 2),
268 aCoords (3 * aNodeIdx - 1),
269 aCoords (3 * aNodeIdx)));
271 return theMgr.OverlapsPolygon (aFacePnts, Select3D_TOS_INTERIOR, thePickResult);
273 else if (mySelMethod == MeshVS_MSM_NODES)
275 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
276 return theMgr.OverlapsPoint (aVert, thePickResult);
278 return Standard_False;
281 //=======================================================================
282 //function : elementIsInside
284 //=======================================================================
285 Standard_Boolean MeshVS_CommonSensitiveEntity::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
286 Standard_Integer theElemIdx,
287 Standard_Boolean theIsFullInside)
291 return Standard_True;
294 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
295 if (mySelMethod == MeshVS_MSM_PRECISE)
297 MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
298 TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
299 Standard_Integer aNbNodes = 0;
300 MeshVS_EntityType aType = MeshVS_ET_NONE;
301 if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
304 return Standard_False;
307 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
308 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
309 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
311 return Standard_False;
314 MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
315 TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
316 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; ++aNodeIdx)
318 const gp_Pnt aPnt (aCoords (3 * aNodeIdx - 2),
319 aCoords (3 * aNodeIdx - 1),
320 aCoords (3 * aNodeIdx));
321 if (!theMgr.OverlapsPoint (aPnt))
323 return Standard_False;
326 return Standard_True;
328 else if (mySelMethod == MeshVS_MSM_NODES)
330 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
331 return theMgr.OverlapsPoint (aVert);
333 return Standard_False;
336 //=======================================================================
337 //function : distanceToCOG
339 //=======================================================================
340 Standard_Real MeshVS_CommonSensitiveEntity::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
342 return theMgr.DistToGeometryCenter (myCOG);
345 //=======================================================================
346 //function : BoundingBox
348 //=======================================================================
349 Select3D_BndBox3d MeshVS_CommonSensitiveEntity::BoundingBox()
354 //=======================================================================
355 //function : CenterOfGeometry
357 //=======================================================================
358 gp_Pnt MeshVS_CommonSensitiveEntity::CenterOfGeometry() const