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 | |
24 | IMPLEMENT_STANDARD_RTTIEXT (MeshVS_CommonSensitiveEntity, Select3D_SensitiveSet) |
25 | |
26 | //======================================================================= |
27 | //function : Constructor |
28 | //purpose : |
29 | //======================================================================= |
0ef04197 |
30 | MeshVS_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 | //======================================================================= |
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) |
102 | { |
103 | // |
104 | } |
105 | |
114b7bf1 |
106 | //======================================================================= |
107 | //function : Destructor |
108 | //purpose : |
109 | //======================================================================= |
110 | MeshVS_CommonSensitiveEntity::~MeshVS_CommonSensitiveEntity() |
111 | { |
112 | myDataSource.Nullify(); |
113 | myItemIndexes.Clear(); |
114 | } |
115 | |
116 | //======================================================================= |
117 | //function : NbSubElements |
118 | //purpose : |
119 | //======================================================================= |
120 | Standard_Integer MeshVS_CommonSensitiveEntity::NbSubElements() |
121 | { |
122 | return myItemIndexes.Size(); |
123 | } |
124 | |
125 | //======================================================================= |
126 | //function : Size |
127 | //purpose : |
128 | //======================================================================= |
129 | Standard_Integer MeshVS_CommonSensitiveEntity::Size() const |
130 | { |
131 | return myItemIndexes.Size(); |
132 | } |
133 | |
134 | //======================================================================= |
135 | //function : getVertexByIndex |
136 | //purpose : |
137 | //======================================================================= |
138 | gp_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 | //======================================================================= |
155 | Select3D_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 | //======================================================================= |
199 | Standard_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 | //======================================================================= |
212 | void 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 |
225 | Standard_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 | //======================================================================= |
284 | Standard_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 | //======================================================================= |
339 | Standard_Real MeshVS_CommonSensitiveEntity::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) |
340 | { |
341 | return theMgr.DistToGeometryCenter (myCOG); |
342 | } |
343 | |
344 | //======================================================================= |
345 | //function : BoundingBox |
346 | //purpose : |
347 | //======================================================================= |
348 | Select3D_BndBox3d MeshVS_CommonSensitiveEntity::BoundingBox() |
349 | { |
350 | return myBndBox; |
351 | } |
41e08b4d |
352 | |
353 | //======================================================================= |
354 | //function : CenterOfGeometry |
355 | //purpose : |
356 | //======================================================================= |
357 | gp_Pnt MeshVS_CommonSensitiveEntity::CenterOfGeometry() const |
358 | { |
359 | return myCOG; |
360 | } |