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 | { |
b1492cb3 |
37 | myMaxFaceNodes = 0; |
114b7bf1 |
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); |
42 | |
43 | if (mySelMethod == MeshVS_MSM_NODES) |
44 | { |
45 | Standard_Integer aNbSelectableNodes = 0; |
46 | const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes(); |
47 | for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next()) |
48 | { |
49 | const Standard_Integer aNodeIdx = aNodesIter.Key(); |
50 | if (theParentMesh->IsSelectableNode (aNodeIdx)) |
51 | { |
52 | const gp_Pnt aVertex = getVertexByIndex (aNodeIdx); |
53 | aCenter += aVertex.XYZ(); |
54 | myBndBox.Add (SelectMgr_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z())); |
55 | ++aNbSelectableNodes; |
56 | myItemIndexes.Append (aNodeIdx); |
57 | } |
58 | } |
59 | |
60 | // increase sensitivity for vertices detection |
61 | SetSensitivityFactor (8); |
62 | myCOG = aCenter / aNbSelectableNodes; |
63 | } |
64 | else if (mySelMethod == MeshVS_MSM_PRECISE) |
65 | { |
66 | const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes(); |
67 | for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next()) |
68 | { |
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())); |
73 | } |
74 | myCOG = aCenter / anAllNodesMap.Extent(); |
75 | |
76 | const TColStd_PackedMapOfInteger& anAllElementsMap = myDataSource->GetAllElements(); |
77 | MeshVS_EntityType aType; |
78 | for (TColStd_MapIteratorOfPackedMapOfInteger anElemIter (anAllElementsMap); anElemIter.More(); anElemIter.Next()) |
79 | { |
80 | const Standard_Integer anElemIdx = anElemIter.Key(); |
81 | if (theParentMesh->IsSelectableElem (anElemIdx) |
82 | && myDataSource->GetGeomType (anElemIdx, Standard_True, aType) |
83 | && aType == MeshVS_ET_Face) |
84 | { |
85 | myItemIndexes.Append (anElemIdx); |
86 | } |
87 | } |
88 | } |
89 | } |
90 | |
834f2897 |
91 | //======================================================================= |
92 | //function : Constructor |
93 | //purpose : |
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) |
103 | { |
104 | // |
105 | } |
106 | |
114b7bf1 |
107 | //======================================================================= |
108 | //function : Destructor |
109 | //purpose : |
110 | //======================================================================= |
111 | MeshVS_CommonSensitiveEntity::~MeshVS_CommonSensitiveEntity() |
112 | { |
113 | myDataSource.Nullify(); |
114 | myItemIndexes.Clear(); |
115 | } |
116 | |
117 | //======================================================================= |
118 | //function : NbSubElements |
119 | //purpose : |
120 | //======================================================================= |
fe758dbe |
121 | Standard_Integer MeshVS_CommonSensitiveEntity::NbSubElements() const |
114b7bf1 |
122 | { |
123 | return myItemIndexes.Size(); |
124 | } |
125 | |
126 | //======================================================================= |
127 | //function : Size |
128 | //purpose : |
129 | //======================================================================= |
130 | Standard_Integer MeshVS_CommonSensitiveEntity::Size() const |
131 | { |
132 | return myItemIndexes.Size(); |
133 | } |
134 | |
135 | //======================================================================= |
136 | //function : getVertexByIndex |
137 | //purpose : |
138 | //======================================================================= |
139 | gp_Pnt MeshVS_CommonSensitiveEntity::getVertexByIndex (const Standard_Integer theNodeIdx) const |
140 | { |
141 | Standard_Real aCoordsBuf[3]; |
142 | TColStd_Array1OfReal aCoords (aCoordsBuf[0], 1, 3); |
143 | Standard_Integer aNbNodes; |
144 | MeshVS_EntityType aType; |
145 | if (!myDataSource->GetGeom (theNodeIdx, Standard_False, aCoords, aNbNodes, aType)) |
146 | { |
147 | return gp_Pnt(); |
148 | } |
149 | return gp_Pnt (aCoords.Value (1), aCoords.Value (2), aCoords.Value (3)); |
150 | } |
151 | |
152 | //======================================================================= |
153 | //function : Box |
154 | //purpose : |
155 | //======================================================================= |
156 | Select3D_BndBox3d MeshVS_CommonSensitiveEntity::Box (const Standard_Integer theIdx) const |
157 | { |
158 | const Standard_Integer anItemIdx = myItemIndexes.Value (theIdx); |
159 | Select3D_BndBox3d aBox; |
160 | if (mySelMethod == MeshVS_MSM_PRECISE) |
161 | { |
162 | MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real)); |
163 | TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes); |
164 | Standard_Integer aNbNodes; |
165 | MeshVS_EntityType aType; |
166 | if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType) |
167 | || aNbNodes == 0) |
168 | { |
169 | return aBox; |
170 | } |
171 | |
172 | MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer)); |
173 | TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes); |
174 | if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes)) |
175 | { |
176 | return aBox; |
177 | } |
178 | |
179 | for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++) |
180 | { |
181 | const SelectMgr_Vec3 aPnt (aCoords (3 * aNodeIdx - 2), |
182 | aCoords (3 * aNodeIdx - 1), |
183 | aCoords (3 * aNodeIdx)); |
184 | aBox.Add (aPnt); |
185 | } |
186 | } |
187 | else if (mySelMethod == MeshVS_MSM_NODES) |
188 | { |
189 | const gp_Pnt aVert = getVertexByIndex (anItemIdx); |
190 | aBox.Add (SelectMgr_Vec3 (aVert.X(), aVert.Y(), aVert.Z())); |
191 | } |
192 | |
193 | return aBox; |
194 | } |
195 | |
196 | //======================================================================= |
197 | //function : Center |
198 | //purpose : |
199 | //======================================================================= |
200 | Standard_Real MeshVS_CommonSensitiveEntity::Center (const Standard_Integer theIdx, |
201 | const Standard_Integer theAxis) const |
202 | { |
203 | const Select3D_BndBox3d& aBox = Box (theIdx); |
204 | SelectMgr_Vec3 aCenter = (aBox.CornerMin () + aBox.CornerMax ()) * 0.5; |
205 | |
206 | return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z()); |
207 | } |
208 | |
209 | //======================================================================= |
210 | //function : Swap |
211 | //purpose : |
212 | //======================================================================= |
213 | void MeshVS_CommonSensitiveEntity::Swap (const Standard_Integer theIdx1, |
214 | const Standard_Integer theIdx2) |
215 | { |
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; |
220 | } |
221 | |
222 | //======================================================================= |
223 | //function : overlapsElement |
224 | //purpose : |
225 | //======================================================================= |
4a056d20 |
226 | Standard_Boolean MeshVS_CommonSensitiveEntity::overlapsElement (SelectBasics_PickResult& thePickResult, |
227 | SelectBasics_SelectingVolumeManager& theMgr, |
114b7bf1 |
228 | Standard_Integer theElemIdx, |
4a056d20 |
229 | Standard_Boolean theIsFullInside) |
114b7bf1 |
230 | { |
4a056d20 |
231 | if (theIsFullInside) |
232 | { |
233 | return Standard_True; |
234 | } |
235 | |
114b7bf1 |
236 | const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx); |
237 | if (mySelMethod == MeshVS_MSM_PRECISE) |
238 | { |
239 | MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real)); |
240 | TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes); |
241 | Standard_Integer aNbNodes; |
242 | MeshVS_EntityType aType; |
243 | if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType) |
244 | || aNbNodes == 0) |
245 | { |
246 | return Standard_False; |
247 | } |
248 | |
249 | MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer)); |
250 | TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes); |
251 | if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes)) |
252 | { |
253 | return Standard_False; |
254 | } |
255 | if (aNbNodes == 3) |
256 | { |
257 | return theMgr.Overlaps (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)), |
17017555 |
260 | Select3D_TOS_INTERIOR, thePickResult); |
114b7bf1 |
261 | } |
262 | |
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++) |
266 | { |
267 | aFacePnts.SetValue (aNodeIdx, gp_Pnt (aCoords (3 * aNodeIdx - 2), |
268 | aCoords (3 * aNodeIdx - 1), |
269 | aCoords (3 * aNodeIdx))); |
270 | } |
17017555 |
271 | return theMgr.Overlaps (aFacePnts, Select3D_TOS_INTERIOR, thePickResult); |
114b7bf1 |
272 | } |
273 | else if (mySelMethod == MeshVS_MSM_NODES) |
274 | { |
275 | const gp_Pnt aVert = getVertexByIndex (anItemIdx); |
17017555 |
276 | return theMgr.Overlaps (aVert, thePickResult); |
114b7bf1 |
277 | } |
278 | return Standard_False; |
279 | } |
280 | |
281 | //======================================================================= |
282 | //function : elementIsInside |
283 | //purpose : |
284 | //======================================================================= |
285 | Standard_Boolean MeshVS_CommonSensitiveEntity::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr, |
4a056d20 |
286 | Standard_Integer theElemIdx, |
287 | Standard_Boolean theIsFullInside) |
114b7bf1 |
288 | { |
4a056d20 |
289 | if (theIsFullInside) |
290 | { |
291 | return Standard_True; |
292 | } |
293 | |
114b7bf1 |
294 | const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx); |
295 | if (mySelMethod == MeshVS_MSM_PRECISE) |
296 | { |
297 | MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real)); |
298 | TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes); |
299 | Standard_Integer aNbNodes; |
300 | MeshVS_EntityType aType; |
301 | if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType) |
302 | || aNbNodes == 0) |
303 | { |
304 | return Standard_False; |
305 | } |
306 | |
307 | MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer)); |
308 | TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes); |
309 | if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes)) |
310 | { |
311 | return Standard_False; |
312 | } |
313 | |
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) |
317 | { |
318 | const gp_Pnt aPnt (aCoords (3 * aNodeIdx - 2), |
319 | aCoords (3 * aNodeIdx - 1), |
320 | aCoords (3 * aNodeIdx)); |
321 | if (!theMgr.Overlaps (aPnt)) |
322 | { |
323 | return Standard_False; |
324 | } |
325 | } |
326 | return Standard_True; |
327 | } |
328 | else if (mySelMethod == MeshVS_MSM_NODES) |
329 | { |
330 | const gp_Pnt aVert = getVertexByIndex (anItemIdx); |
331 | return theMgr.Overlaps (aVert); |
332 | } |
333 | return Standard_False; |
334 | } |
335 | |
336 | //======================================================================= |
337 | //function : distanceToCOG |
338 | //purpose : |
339 | //======================================================================= |
340 | Standard_Real MeshVS_CommonSensitiveEntity::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) |
341 | { |
342 | return theMgr.DistToGeometryCenter (myCOG); |
343 | } |
344 | |
345 | //======================================================================= |
346 | //function : BoundingBox |
347 | //purpose : |
348 | //======================================================================= |
349 | Select3D_BndBox3d MeshVS_CommonSensitiveEntity::BoundingBox() |
350 | { |
351 | return myBndBox; |
352 | } |
41e08b4d |
353 | |
354 | //======================================================================= |
355 | //function : CenterOfGeometry |
356 | //purpose : |
357 | //======================================================================= |
358 | gp_Pnt MeshVS_CommonSensitiveEntity::CenterOfGeometry() const |
359 | { |
360 | return myCOG; |
361 | } |