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(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)
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 : Destructor
93 //=======================================================================
94 MeshVS_CommonSensitiveEntity::~MeshVS_CommonSensitiveEntity()
96 myDataSource.Nullify();
97 myItemIndexes.Clear();
100 //=======================================================================
101 //function : NbSubElements
103 //=======================================================================
104 Standard_Integer MeshVS_CommonSensitiveEntity::NbSubElements()
106 return myItemIndexes.Size();
109 //=======================================================================
112 //=======================================================================
113 Standard_Integer MeshVS_CommonSensitiveEntity::Size() const
115 return myItemIndexes.Size();
118 //=======================================================================
119 //function : getVertexByIndex
121 //=======================================================================
122 gp_Pnt MeshVS_CommonSensitiveEntity::getVertexByIndex (const Standard_Integer theNodeIdx) const
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))
132 return gp_Pnt (aCoords.Value (1), aCoords.Value (2), aCoords.Value (3));
135 //=======================================================================
138 //=======================================================================
139 Select3D_BndBox3d MeshVS_CommonSensitiveEntity::Box (const Standard_Integer theIdx) const
141 const Standard_Integer anItemIdx = myItemIndexes.Value (theIdx);
142 Select3D_BndBox3d aBox;
143 if (mySelMethod == MeshVS_MSM_PRECISE)
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)
155 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
156 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
157 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
162 for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
164 const SelectMgr_Vec3 aPnt (aCoords (3 * aNodeIdx - 2),
165 aCoords (3 * aNodeIdx - 1),
166 aCoords (3 * aNodeIdx));
170 else if (mySelMethod == MeshVS_MSM_NODES)
172 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
173 aBox.Add (SelectMgr_Vec3 (aVert.X(), aVert.Y(), aVert.Z()));
179 //=======================================================================
182 //=======================================================================
183 Standard_Real MeshVS_CommonSensitiveEntity::Center (const Standard_Integer theIdx,
184 const Standard_Integer theAxis) const
186 const Select3D_BndBox3d& aBox = Box (theIdx);
187 SelectMgr_Vec3 aCenter = (aBox.CornerMin () + aBox.CornerMax ()) * 0.5;
189 return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z());
192 //=======================================================================
195 //=======================================================================
196 void MeshVS_CommonSensitiveEntity::Swap (const Standard_Integer theIdx1,
197 const Standard_Integer theIdx2)
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;
205 //=======================================================================
206 //function : overlapsElement
208 //=======================================================================
209 Standard_Boolean MeshVS_CommonSensitiveEntity::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
210 Standard_Integer theElemIdx,
211 Standard_Real& theMatchDepth)
213 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
214 if (mySelMethod == MeshVS_MSM_PRECISE)
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)
223 return Standard_False;
226 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
227 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
228 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
230 return Standard_False;
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);
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++)
244 aFacePnts.SetValue (aNodeIdx, gp_Pnt (aCoords (3 * aNodeIdx - 2),
245 aCoords (3 * aNodeIdx - 1),
246 aCoords (3 * aNodeIdx)));
248 return theMgr.Overlaps (aFacePnts, Select3D_TOS_INTERIOR, theMatchDepth);
250 else if (mySelMethod == MeshVS_MSM_NODES)
252 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
253 return theMgr.Overlaps (aVert, theMatchDepth);
255 return Standard_False;
258 //=======================================================================
259 //function : elementIsInside
261 //=======================================================================
262 Standard_Boolean MeshVS_CommonSensitiveEntity::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
263 const Standard_Integer theElemIdx)
265 const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
266 if (mySelMethod == MeshVS_MSM_PRECISE)
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)
275 return Standard_False;
278 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
279 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
280 if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
282 return Standard_False;
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)
289 const gp_Pnt aPnt (aCoords (3 * aNodeIdx - 2),
290 aCoords (3 * aNodeIdx - 1),
291 aCoords (3 * aNodeIdx));
292 if (!theMgr.Overlaps (aPnt))
294 return Standard_False;
297 return Standard_True;
299 else if (mySelMethod == MeshVS_MSM_NODES)
301 const gp_Pnt aVert = getVertexByIndex (anItemIdx);
302 return theMgr.Overlaps (aVert);
304 return Standard_False;
307 //=======================================================================
308 //function : distanceToCOG
310 //=======================================================================
311 Standard_Real MeshVS_CommonSensitiveEntity::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
313 return theMgr.DistToGeometryCenter (myCOG);
316 //=======================================================================
317 //function : BoundingBox
319 //=======================================================================
320 Select3D_BndBox3d MeshVS_CommonSensitiveEntity::BoundingBox()