Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1995-03-14 |
2 | // Created by: Robert COUBLANC | |
3 | // Copyright (c) 1995-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
bbf32d01 | 16 | |
f838dac4 | 17 | #include <StdSelect_BRepSelectionTool.hxx> |
42cf5bc1 | 18 | |
19 | #include <Bnd_Box.hxx> | |
20 | #include <BRep_Tool.hxx> | |
7fd59977 | 21 | #include <BRepAdaptor_Curve.hxx> |
22 | #include <BRepAdaptor_Surface.hxx> | |
7fd59977 | 23 | #include <BRepBndLib.hxx> |
42cf5bc1 | 24 | #include <BRepMesh_IncrementalMesh.hxx> |
25 | #include <BRepTools.hxx> | |
26 | #include <BRepTools_WireExplorer.hxx> | |
27 | #include <GCPnts_TangentialDeflection.hxx> | |
7fd59977 | 28 | #include <Geom_Circle.hxx> |
42cf5bc1 | 29 | #include <GeomAbs_SurfaceType.hxx> |
30 | #include <GeomAdaptor_Curve.hxx> | |
31 | #include <gp_Circ.hxx> | |
32 | #include <Poly_Array1OfTriangle.hxx> | |
33 | #include <Poly_Polygon3D.hxx> | |
34 | #include <Poly_PolygonOnTriangulation.hxx> | |
35 | #include <Poly_Triangulation.hxx> | |
36 | #include <Precision.hxx> | |
37 | #include <Select3D_SensitiveBox.hxx> | |
7fd59977 | 38 | #include <Select3D_SensitiveCircle.hxx> |
39 | #include <Select3D_SensitiveCurve.hxx> | |
42cf5bc1 | 40 | #include <Select3D_SensitiveEntity.hxx> |
7fd59977 | 41 | #include <Select3D_SensitiveFace.hxx> |
7fd59977 | 42 | #include <Select3D_SensitiveGroup.hxx> |
42cf5bc1 | 43 | #include <Select3D_SensitivePoint.hxx> |
44 | #include <Select3D_SensitiveSegment.hxx> | |
45 | #include <Select3D_SensitiveTriangle.hxx> | |
46 | #include <Select3D_SensitiveTriangulation.hxx> | |
47 | #include <Select3D_SensitiveWire.hxx> | |
48 | #include <Select3D_TypeOfSensitivity.hxx> | |
49 | #include <SelectMgr_EntityOwner.hxx> | |
50 | #include <SelectMgr_SelectableObject.hxx> | |
f751596e | 51 | #include <SelectMgr_Selection.hxx> |
42cf5bc1 | 52 | #include <Standard_ErrorHandler.hxx> |
53 | #include <Standard_NullObject.hxx> | |
54 | #include <StdSelect_BRepOwner.hxx> | |
7fd59977 | 55 | #include <TColgp_HArray1OfPnt.hxx> |
56 | #include <TColgp_SequenceOfPnt.hxx> | |
57 | #include <TColStd_Array1OfReal.hxx> | |
42cf5bc1 | 58 | #include <TopExp.hxx> |
59 | #include <TopExp_Explorer.hxx> | |
60 | #include <TopoDS.hxx> | |
61 | #include <TopoDS_Face.hxx> | |
62 | #include <TopoDS_Shape.hxx> | |
bbf32d01 | 63 | #include <TopoDS_Wire.hxx> |
42cf5bc1 | 64 | #include <TopTools_IndexedMapOfShape.hxx> |
7fd59977 | 65 | |
f751596e | 66 | #define BVH_PRIMITIVE_LIMIT 800000 |
67 | ||
68 | //================================================== | |
114b7bf1 | 69 | // function: PreBuildBVH |
f751596e | 70 | // purpose : Pre-builds BVH tree for heavyweight |
71 | // sensitive entities with sub-elements | |
72 | // amount more than BVH_PRIMITIVE_LIMIT | |
73 | //================================================== | |
114b7bf1 | 74 | void StdSelect_BRepSelectionTool::PreBuildBVH (const Handle(SelectMgr_Selection)& theSelection) |
f751596e | 75 | { |
b5cce1ab | 76 | for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next()) |
f751596e | 77 | { |
0ef04197 | 78 | const Handle(Select3D_SensitiveEntity)& aSensitive = aSelEntIter.Value()->BaseSensitive(); |
f751596e | 79 | if (aSensitive->NbSubElements() >= BVH_PRIMITIVE_LIMIT) |
80 | { | |
81 | aSensitive->BVH(); | |
82 | } | |
83 | ||
f5b72419 | 84 | if (!aSensitive->IsInstance (STANDARD_TYPE(Select3D_SensitiveGroup))) |
f751596e | 85 | { |
f5b72419 | 86 | continue; |
87 | } | |
88 | ||
89 | Handle(Select3D_SensitiveGroup) aGroup = Handle(Select3D_SensitiveGroup)::DownCast (aSensitive); | |
7f5945d6 | 90 | for (Select3D_IndexedMapOfEntity::Iterator aSubEntitiesIter (aGroup->Entities()); aSubEntitiesIter.More(); aSubEntitiesIter.Next()) |
f5b72419 | 91 | { |
92 | const Handle(Select3D_SensitiveEntity)& aSubEntity = aSubEntitiesIter.Value(); | |
93 | if (aSubEntity->NbSubElements() >= BVH_PRIMITIVE_LIMIT) | |
f751596e | 94 | { |
f5b72419 | 95 | aSubEntity->BVH(); |
f751596e | 96 | } |
97 | } | |
98 | } | |
99 | } | |
100 | ||
7fd59977 | 101 | //================================================== |
bbf32d01 K |
102 | // Function: Load |
103 | // Purpose : | |
104 | //================================================== | |
f838dac4 | 105 | void StdSelect_BRepSelectionTool::Load (const Handle(SelectMgr_Selection)& theSelection, |
106 | const TopoDS_Shape& theShape, | |
107 | const TopAbs_ShapeEnum theType, | |
108 | const Standard_Real theDeflection, | |
109 | const Standard_Real theDeviationAngle, | |
110 | const Standard_Boolean isAutoTriangulation, | |
111 | const Standard_Integer thePriority, | |
112 | const Standard_Integer theNbPOnEdge, | |
113 | const Standard_Real theMaxParam) | |
7fd59977 | 114 | { |
bbf32d01 | 115 | Standard_Integer aPriority = (thePriority == -1) ? GetStandardPriority (theShape, theType) : thePriority; |
3c34883c O |
116 | |
117 | if( isAutoTriangulation && !BRepTools::Triangulation (theShape, Precision::Infinite()) ) | |
118 | { | |
14434f3e | 119 | BRepMesh_IncrementalMesh aMesher(theShape, theDeflection, Standard_False, theDeviationAngle); |
3c34883c O |
120 | } |
121 | ||
bbf32d01 K |
122 | Handle(StdSelect_BRepOwner) aBrepOwner; |
123 | switch (theType) | |
124 | { | |
125 | case TopAbs_VERTEX: | |
126 | case TopAbs_EDGE: | |
127 | case TopAbs_WIRE: | |
128 | case TopAbs_FACE: | |
129 | case TopAbs_SHELL: | |
130 | case TopAbs_SOLID: | |
131 | case TopAbs_COMPSOLID: | |
7fd59977 | 132 | { |
bbf32d01 K |
133 | TopTools_IndexedMapOfShape aSubShapes; |
134 | TopExp::MapShapes (theShape, theType, aSubShapes); | |
135 | ||
136 | Standard_Boolean isComesFromDecomposition = !((aSubShapes.Extent() == 1) && (theShape == aSubShapes (1))); | |
137 | for (Standard_Integer aShIndex = 1; aShIndex <= aSubShapes.Extent(); ++aShIndex) | |
138 | { | |
139 | const TopoDS_Shape& aSubShape = aSubShapes (aShIndex); | |
140 | aBrepOwner = new StdSelect_BRepOwner (aSubShape, aPriority, isComesFromDecomposition); | |
141 | ComputeSensitive (aSubShape, aBrepOwner, | |
142 | theSelection, | |
143 | theDeflection, | |
144 | theDeviationAngle, | |
145 | theNbPOnEdge, | |
146 | theMaxParam, | |
147 | isAutoTriangulation); | |
7fd59977 | 148 | } |
149 | break; | |
150 | } | |
bbf32d01 | 151 | default: |
7fd59977 | 152 | { |
bbf32d01 K |
153 | aBrepOwner = new StdSelect_BRepOwner (theShape, aPriority); |
154 | ComputeSensitive (theShape, aBrepOwner, | |
155 | theSelection, | |
156 | theDeflection, | |
157 | theDeviationAngle, | |
158 | theNbPOnEdge, | |
159 | theMaxParam, | |
160 | isAutoTriangulation); | |
7fd59977 | 161 | } |
7fd59977 | 162 | } |
163 | } | |
164 | ||
bbf32d01 K |
165 | //================================================== |
166 | // Function: Load | |
167 | // Purpose : | |
168 | //================================================== | |
f838dac4 | 169 | void StdSelect_BRepSelectionTool::Load (const Handle(SelectMgr_Selection)& theSelection, |
170 | const Handle(SelectMgr_SelectableObject)& theSelectableObj, | |
171 | const TopoDS_Shape& theShape, | |
172 | const TopAbs_ShapeEnum theType, | |
173 | const Standard_Real theDeflection, | |
174 | const Standard_Real theDeviationAngle, | |
175 | const Standard_Boolean isAutoTriangulation, | |
176 | const Standard_Integer thePriority, | |
177 | const Standard_Integer theNbPOnEdge, | |
178 | const Standard_Real theMaxParam) | |
7fd59977 | 179 | { |
bbf32d01 K |
180 | Load (theSelection, |
181 | theShape, | |
182 | theType, | |
7fd59977 | 183 | theDeflection, |
184 | theDeviationAngle, | |
bbf32d01 K |
185 | isAutoTriangulation, |
186 | thePriority, | |
187 | theNbPOnEdge, | |
188 | theMaxParam); | |
189 | ||
190 | // loading of selectables... | |
b5cce1ab | 191 | for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next()) |
bbf32d01 | 192 | { |
0ef04197 | 193 | const Handle(SelectMgr_EntityOwner)& anOwner = aSelEntIter.Value()->BaseSensitive()->OwnerId(); |
194 | anOwner->SetSelectable (theSelectableObj); | |
7fd59977 | 195 | } |
f751596e | 196 | |
114b7bf1 | 197 | PreBuildBVH (theSelection); |
7fd59977 | 198 | } |
199 | ||
bbf32d01 K |
200 | //================================================== |
201 | // Function: ComputeSensitive | |
202 | // Purpose : | |
203 | //================================================== | |
f838dac4 | 204 | void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape, |
205 | const Handle(SelectMgr_EntityOwner)& theOwner, | |
206 | const Handle(SelectMgr_Selection)& theSelection, | |
207 | const Standard_Real theDeflection, | |
208 | const Standard_Real theDeviationAngle, | |
209 | const Standard_Integer theNbPOnEdge, | |
210 | const Standard_Real theMaxParam, | |
211 | const Standard_Boolean isAutoTriangulation) | |
7fd59977 | 212 | { |
bbf32d01 K |
213 | switch (theShape.ShapeType()) |
214 | { | |
215 | case TopAbs_VERTEX: | |
216 | { | |
217 | theSelection->Add (new Select3D_SensitivePoint | |
218 | (theOwner, BRep_Tool::Pnt (TopoDS::Vertex (theShape)))); | |
7fd59977 | 219 | break; |
220 | } | |
bbf32d01 K |
221 | case TopAbs_EDGE: |
222 | { | |
223 | Handle(Select3D_SensitiveEntity) aSensitive; | |
224 | GetEdgeSensitive (theShape, theOwner, theSelection, | |
225 | theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, | |
226 | aSensitive); | |
227 | if (!aSensitive.IsNull()) | |
228 | { | |
229 | theSelection->Add (aSensitive); | |
230 | } | |
7fd59977 | 231 | break; |
232 | } | |
bbf32d01 | 233 | case TopAbs_WIRE: |
7fd59977 | 234 | { |
bbf32d01 | 235 | BRepTools_WireExplorer aWireExp (TopoDS::Wire (theShape)); |
7fd59977 | 236 | Handle (Select3D_SensitiveEntity) aSensitive; |
bbf32d01 K |
237 | Handle (Select3D_SensitiveWire) aWireSensitive = new Select3D_SensitiveWire (theOwner); |
238 | theSelection->Add (aWireSensitive); | |
239 | while (aWireExp.More()) | |
240 | { | |
241 | GetEdgeSensitive (aWireExp.Current(), theOwner, theSelection, | |
242 | theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, | |
243 | aSensitive); | |
244 | if (!aSensitive.IsNull()) | |
245 | { | |
246 | aWireSensitive->Add (aSensitive); | |
247 | } | |
248 | aWireExp.Next(); | |
7fd59977 | 249 | } |
250 | break; | |
251 | } | |
bbf32d01 | 252 | case TopAbs_FACE: |
7fd59977 | 253 | { |
bbf32d01 | 254 | const TopoDS_Face& aFace = TopoDS::Face (theShape); |
f751596e | 255 | Select3D_EntitySequence aSensitiveList; |
bbf32d01 K |
256 | GetSensitiveForFace (aFace, theOwner, |
257 | aSensitiveList, | |
258 | isAutoTriangulation, theNbPOnEdge, theMaxParam); | |
f751596e | 259 | for (Select3D_EntitySequenceIter aSensIter (aSensitiveList); |
bbf32d01 K |
260 | aSensIter.More(); aSensIter.Next()) |
261 | { | |
262 | theSelection->Add (aSensIter.Value()); | |
263 | } | |
7fd59977 | 264 | break; |
265 | } | |
bbf32d01 | 266 | case TopAbs_SHELL: |
bbf32d01 K |
267 | case TopAbs_SOLID: |
268 | case TopAbs_COMPSOLID: | |
7fd59977 | 269 | { |
bbf32d01 K |
270 | TopTools_IndexedMapOfShape aSubfacesMap; |
271 | TopExp::MapShapes (theShape, TopAbs_FACE, aSubfacesMap); | |
272 | for (Standard_Integer aShIndex = 1; aShIndex <= aSubfacesMap.Extent(); ++aShIndex) | |
273 | { | |
274 | ComputeSensitive (aSubfacesMap (aShIndex), theOwner, | |
275 | theSelection, | |
276 | theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation); | |
277 | } | |
7fd59977 | 278 | break; |
279 | } | |
bbf32d01 K |
280 | case TopAbs_COMPOUND: |
281 | default: | |
7fd59977 | 282 | { |
bbf32d01 K |
283 | TopExp_Explorer anExp; |
284 | // sub-vertices | |
285 | for (anExp.Init (theShape, TopAbs_VERTEX, TopAbs_EDGE); anExp.More(); anExp.Next()) | |
286 | { | |
287 | ComputeSensitive (anExp.Current(), theOwner, | |
288 | theSelection, | |
289 | theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation); | |
290 | } | |
291 | // sub-edges | |
292 | for (anExp.Init (theShape, TopAbs_EDGE, TopAbs_FACE); anExp.More(); anExp.Next()) | |
293 | { | |
294 | ComputeSensitive (anExp.Current(), theOwner, | |
295 | theSelection, | |
296 | theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation); | |
297 | } | |
298 | // sub-wires | |
299 | for (anExp.Init (theShape, TopAbs_WIRE, TopAbs_FACE); anExp.More(); anExp.Next()) | |
300 | { | |
301 | ComputeSensitive (anExp.Current(), theOwner, | |
302 | theSelection, | |
303 | theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation); | |
304 | } | |
7fd59977 | 305 | |
bbf32d01 K |
306 | // sub-faces |
307 | TopTools_IndexedMapOfShape aSubfacesMap; | |
308 | TopExp::MapShapes (theShape, TopAbs_FACE, aSubfacesMap); | |
309 | for (Standard_Integer aShIndex = 1; aShIndex <= aSubfacesMap.Extent(); ++aShIndex) | |
310 | { | |
311 | ComputeSensitive (aSubfacesMap (aShIndex), theOwner, | |
312 | theSelection, | |
313 | theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation); | |
314 | } | |
315 | } | |
316 | } | |
7fd59977 | 317 | } |
318 | ||
bbf32d01 K |
319 | //================================================== |
320 | // Function: GetPointsFromPolygon | |
321 | // Purpose : | |
322 | //================================================== | |
36679076 | 323 | static Handle(TColgp_HArray1OfPnt) GetPointsFromPolygon (const TopoDS_Edge& theEdge) |
7fd59977 | 324 | { |
325 | Handle(TColgp_HArray1OfPnt) aResultPoints; | |
326 | ||
7fd59977 | 327 | TopLoc_Location aLocation; |
328 | Handle(Poly_Polygon3D) aPolygon = BRep_Tool::Polygon3D (theEdge, aLocation); | |
329 | if (!aPolygon.IsNull()) | |
330 | { | |
36679076 | 331 | const TColgp_Array1OfPnt& aNodes = aPolygon->Nodes(); |
332 | aResultPoints = new TColgp_HArray1OfPnt (1, aNodes.Length()); | |
333 | if (aLocation.IsIdentity()) | |
7fd59977 | 334 | { |
36679076 | 335 | for (Standard_Integer aNodeId (aNodes.Lower()), aPntId (1); aNodeId <= aNodes.Upper(); ++aNodeId, ++aPntId) |
7fd59977 | 336 | { |
36679076 | 337 | aResultPoints->SetValue (aPntId, aNodes.Value (aNodeId)); |
7fd59977 | 338 | } |
36679076 | 339 | } |
340 | else | |
341 | { | |
342 | for (Standard_Integer aNodeId (aNodes.Lower()), aPntId (1); aNodeId <= aNodes.Upper(); ++aNodeId, ++aPntId) | |
7fd59977 | 343 | { |
36679076 | 344 | aResultPoints->SetValue (aPntId, aNodes.Value (aNodeId).Transformed (aLocation)); |
7fd59977 | 345 | } |
7fd59977 | 346 | } |
36679076 | 347 | return aResultPoints; |
7fd59977 | 348 | } |
349 | ||
350 | Handle(Poly_Triangulation) aTriangulation; | |
351 | Handle(Poly_PolygonOnTriangulation) anHIndices; | |
352 | BRep_Tool::PolygonOnTriangulation (theEdge, anHIndices, aTriangulation, aLocation); | |
353 | if (!anHIndices.IsNull()) | |
354 | { | |
36679076 | 355 | const TColStd_Array1OfInteger& anIndices = anHIndices->Nodes(); |
356 | const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes(); | |
7fd59977 | 357 | |
36679076 | 358 | aResultPoints = new TColgp_HArray1OfPnt (1, anIndices.Length()); |
7fd59977 | 359 | |
36679076 | 360 | if (aLocation.IsIdentity()) |
361 | { | |
362 | for (Standard_Integer anIndex (anIndices.Lower()), aPntId (1); anIndex <= anIndices.Upper(); ++anIndex, ++aPntId) | |
7fd59977 | 363 | { |
36679076 | 364 | aResultPoints->SetValue (aPntId, aNodes (anIndices (anIndex))); |
7fd59977 | 365 | } |
36679076 | 366 | } |
367 | else | |
368 | { | |
369 | for (Standard_Integer anIndex (anIndices.Lower()), aPntId (1); anIndex <= anIndices.Upper(); ++anIndex, ++aPntId) | |
7fd59977 | 370 | { |
36679076 | 371 | aResultPoints->SetValue (aPntId, aNodes (anIndices (anIndex)).Transformed (aLocation)); |
7fd59977 | 372 | } |
7fd59977 | 373 | } |
36679076 | 374 | return aResultPoints; |
7fd59977 | 375 | } |
376 | return aResultPoints; | |
377 | } | |
378 | ||
bbf32d01 K |
379 | //================================================== |
380 | // Function: FindLimits | |
381 | // Purpose : | |
382 | //================================================== | |
383 | static Standard_Boolean FindLimits (const Adaptor3d_Curve& theCurve, | |
384 | const Standard_Real theLimit, | |
385 | Standard_Real& theFirst, | |
386 | Standard_Real& theLast) | |
7fd59977 | 387 | { |
bbf32d01 K |
388 | theFirst = theCurve.FirstParameter(); |
389 | theLast = theCurve.LastParameter(); | |
390 | Standard_Boolean isFirstInf = Precision::IsNegativeInfinite (theFirst); | |
391 | Standard_Boolean isLastInf = Precision::IsPositiveInfinite (theLast); | |
392 | if (isFirstInf || isLastInf) | |
393 | { | |
394 | gp_Pnt aPnt1, aPnt2; | |
395 | Standard_Real aDelta = 1.0; | |
396 | Standard_Integer anIterCount = 0; | |
397 | if (isFirstInf && isLastInf) | |
398 | { | |
7fd59977 | 399 | do { |
bbf32d01 K |
400 | if (anIterCount++ >= 100000) return Standard_False; |
401 | aDelta *= 2.0; | |
402 | theFirst = - aDelta; | |
403 | theLast = aDelta; | |
404 | theCurve.D0 (theFirst, aPnt1); | |
405 | theCurve.D0 (theLast, aPnt2); | |
406 | } while (aPnt1.Distance (aPnt2) < theLimit); | |
7fd59977 | 407 | } |
bbf32d01 K |
408 | else if (isFirstInf) |
409 | { | |
410 | theCurve.D0 (theLast, aPnt2); | |
7fd59977 | 411 | do { |
bbf32d01 K |
412 | if (anIterCount++ >= 100000) return Standard_False; |
413 | aDelta *= 2.0; | |
414 | theFirst = theLast - aDelta; | |
415 | theCurve.D0 (theFirst, aPnt1); | |
416 | } while (aPnt1.Distance (aPnt2) < theLimit); | |
7fd59977 | 417 | } |
bbf32d01 K |
418 | else if (isLastInf) |
419 | { | |
420 | theCurve.D0 (theFirst, aPnt1); | |
7fd59977 | 421 | do { |
bbf32d01 K |
422 | if (anIterCount++ >= 100000) return Standard_False; |
423 | aDelta *= 2.0; | |
424 | theLast = theFirst + aDelta; | |
425 | theCurve.D0 (theLast, aPnt2); | |
426 | } while (aPnt1.Distance (aPnt2) < theLimit); | |
7fd59977 | 427 | } |
bbf32d01 | 428 | } |
7fd59977 | 429 | return Standard_True; |
430 | } | |
431 | ||
432 | //===================================================== | |
433 | // Function : GetEdgeSensitive | |
f838dac4 | 434 | // Purpose : |
bbf32d01 | 435 | //===================================================== |
f838dac4 | 436 | void StdSelect_BRepSelectionTool::GetEdgeSensitive (const TopoDS_Shape& theShape, |
437 | const Handle(SelectMgr_EntityOwner)& theOwner, | |
438 | const Handle(SelectMgr_Selection)& theSelection, | |
439 | const Standard_Real theDeflection, | |
440 | const Standard_Real theDeviationAngle, | |
441 | const Standard_Integer theNbPOnEdge, | |
442 | const Standard_Real theMaxParam, | |
443 | Handle(Select3D_SensitiveEntity)& theSensitive) | |
7fd59977 | 444 | { |
bbf32d01 | 445 | const TopoDS_Edge& anEdge = TopoDS::Edge (theShape); |
e05d8d90 | 446 | // try to get points from existing polygons |
447 | Handle(TColgp_HArray1OfPnt) aPoints = GetPointsFromPolygon (anEdge); | |
448 | if (!aPoints.IsNull() | |
449 | && !aPoints->IsEmpty()) | |
450 | { | |
451 | theSensitive = new Select3D_SensitiveCurve (theOwner, aPoints); | |
452 | return; | |
453 | } | |
454 | ||
bbf32d01 K |
455 | BRepAdaptor_Curve cu3d; |
456 | try { | |
457 | OCC_CATCH_SIGNALS | |
458 | cu3d.Initialize (anEdge); | |
a738b534 | 459 | } catch (Standard_NullObject const&) { |
bbf32d01 K |
460 | return; |
461 | } | |
7fd59977 | 462 | |
bbf32d01 K |
463 | Standard_Real aParamFirst = cu3d.FirstParameter(); |
464 | Standard_Real aParamLast = cu3d.LastParameter(); | |
465 | switch (cu3d.GetType()) | |
466 | { | |
467 | case GeomAbs_Line: | |
7fd59977 | 468 | { |
bbf32d01 K |
469 | BRep_Tool::Range (anEdge, aParamFirst, aParamLast); |
470 | theSensitive = new Select3D_SensitiveSegment (theOwner, | |
471 | cu3d.Value (aParamFirst), | |
472 | cu3d.Value (aParamLast)); | |
7fd59977 | 473 | break; |
474 | } | |
bbf32d01 | 475 | case GeomAbs_Circle: |
7fd59977 | 476 | { |
bbf32d01 K |
477 | Handle (Geom_Circle) aCircle = new Geom_Circle (cu3d.Circle()); |
478 | if (aCircle->Radius() <= Precision::Confusion()) | |
479 | { | |
480 | theSelection->Add (new Select3D_SensitivePoint (theOwner, aCircle->Location())); | |
481 | } | |
7fd59977 | 482 | else |
bbf32d01 K |
483 | { |
484 | theSensitive = new Select3D_SensitiveCircle (theOwner, aCircle, | |
485 | aParamFirst, aParamLast, Standard_False, 16); | |
486 | } | |
7fd59977 | 487 | break; |
488 | } | |
bbf32d01 | 489 | default: |
7fd59977 | 490 | { |
bbf32d01 K |
491 | // reproduce drawing behaviour |
492 | // TODO: remove copy-paste from StdPrs_Curve and some others... | |
493 | if (FindLimits (cu3d, theMaxParam, aParamFirst, aParamLast)) | |
7fd59977 | 494 | { |
495 | Standard_Integer aNbIntervals = cu3d.NbIntervals (GeomAbs_C1); | |
496 | TColStd_Array1OfReal anIntervals (1, aNbIntervals + 1); | |
497 | cu3d.Intervals (anIntervals, GeomAbs_C1); | |
498 | Standard_Real aV1, aV2; | |
499 | Standard_Integer aNumberOfPoints; | |
500 | TColgp_SequenceOfPnt aPointsSeq; | |
7fd59977 | 501 | for (Standard_Integer anIntervalId = 1; anIntervalId <= aNbIntervals; ++anIntervalId) |
502 | { | |
bbf32d01 K |
503 | aV1 = anIntervals (anIntervalId); |
504 | aV2 = anIntervals (anIntervalId + 1); | |
505 | if (aV2 > aParamFirst && aV1 < aParamLast) | |
7fd59977 | 506 | { |
bbf32d01 K |
507 | aV1 = Max (aV1, aParamFirst); |
508 | aV2 = Min (aV2, aParamLast); | |
7fd59977 | 509 | |
510 | GCPnts_TangentialDeflection anAlgo (cu3d, aV1, aV2, theDeviationAngle, theDeflection); | |
511 | aNumberOfPoints = anAlgo.NbPoints(); | |
512 | ||
bbf32d01 | 513 | for (Standard_Integer aPntId = 1; aPntId < aNumberOfPoints; ++aPntId) |
7fd59977 | 514 | { |
bbf32d01 K |
515 | aPointsSeq.Append (anAlgo.Value (aPntId)); |
516 | } | |
517 | if (aNumberOfPoints > 0 && anIntervalId == aNbIntervals) | |
518 | { | |
519 | aPointsSeq.Append (anAlgo.Value (aNumberOfPoints)); | |
7fd59977 | 520 | } |
521 | } | |
522 | } | |
523 | ||
524 | aPoints = new TColgp_HArray1OfPnt (1, aPointsSeq.Length()); | |
525 | for (Standard_Integer aPntId = 1; aPntId <= aPointsSeq.Length(); ++aPntId) | |
526 | { | |
527 | aPoints->SetValue (aPntId, aPointsSeq.Value (aPntId)); | |
528 | } | |
bbf32d01 | 529 | theSensitive = new Select3D_SensitiveCurve (theOwner, aPoints); |
7fd59977 | 530 | break; |
531 | } | |
532 | ||
533 | // simple subdivisions | |
534 | Standard_Integer nbintervals = 1; | |
bbf32d01 K |
535 | if (cu3d.GetType() == GeomAbs_BSplineCurve) |
536 | { | |
537 | nbintervals = cu3d.NbKnots() - 1; | |
538 | nbintervals = Max (1, nbintervals / 3); | |
7fd59977 | 539 | } |
bbf32d01 K |
540 | |
541 | Standard_Real aParam; | |
542 | Standard_Integer aPntNb = Max (2, theNbPOnEdge * nbintervals); | |
543 | Standard_Real aParamDelta = (aParamLast - aParamFirst) / (aPntNb - 1); | |
544 | Handle(TColgp_HArray1OfPnt) aPointArray = new TColgp_HArray1OfPnt (1, aPntNb); | |
545 | for (Standard_Integer aPntId = 1; aPntId <= aPntNb; ++aPntId) | |
546 | { | |
547 | aParam = aParamFirst + aParamDelta * (aPntId - 1); | |
548 | aPointArray->SetValue (aPntId, cu3d.Value (aParam)); | |
7fd59977 | 549 | } |
bbf32d01 | 550 | theSensitive = new Select3D_SensitiveCurve (theOwner, aPointArray); |
7fd59977 | 551 | } |
552 | break; | |
553 | } | |
554 | } | |
555 | ||
7fd59977 | 556 | //======================================================================= |
557 | //function : GetSensitiveEntityForFace | |
bbf32d01 | 558 | //purpose : |
7fd59977 | 559 | //======================================================================= |
f838dac4 | 560 | Standard_Boolean StdSelect_BRepSelectionTool::GetSensitiveForFace (const TopoDS_Face& theFace, |
561 | const Handle(SelectMgr_EntityOwner)& theOwner, | |
562 | Select3D_EntitySequence& theSensitiveList, | |
563 | const Standard_Boolean /*theAutoTriangulation*/, | |
564 | const Standard_Integer NbPOnEdge, | |
565 | const Standard_Real theMaxParam, | |
566 | const Standard_Boolean theInteriorFlag) | |
7fd59977 | 567 | { |
bbf32d01 | 568 | TopLoc_Location aLoc; |
c7ba4578 | 569 | if (Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (theFace, aLoc)) |
bbf32d01 K |
570 | { |
571 | Handle(Select3D_SensitiveTriangulation) STG = new Select3D_SensitiveTriangulation (theOwner, aTriangulation, aLoc, theInteriorFlag); | |
572 | theSensitiveList.Append (STG); | |
7fd59977 | 573 | return Standard_True; |
574 | } | |
575 | ||
81bba717 | 576 | // for faces with triangulation bugs or without autotriangulation .... |
577 | // very ugly and should not even exist ... | |
c7ba4578 | 578 | BRepAdaptor_Surface BS (theFace); |
bbf32d01 K |
579 | if (BS.GetType() == GeomAbs_Plane) |
580 | { | |
c7ba4578 | 581 | const Standard_Real aFirstU = BS.FirstUParameter() <= -Precision::Infinite() ? -theMaxParam : BS.FirstUParameter(); |
582 | const Standard_Real aLastU = BS.LastUParameter() >= Precision::Infinite() ? theMaxParam : BS.LastUParameter(); | |
583 | const Standard_Real aFirstV = BS.FirstVParameter() <= -Precision::Infinite() ? -theMaxParam : BS.FirstVParameter(); | |
584 | const Standard_Real aLastV = BS.LastVParameter() >= Precision::Infinite() ? theMaxParam : BS.LastVParameter(); | |
585 | Handle(TColgp_HArray1OfPnt) aPlanePnts = new TColgp_HArray1OfPnt (1, 5); | |
586 | BS.D0 (aFirstU, aFirstV, aPlanePnts->ChangeValue (1)); | |
587 | BS.D0 (aLastU, aFirstV, aPlanePnts->ChangeValue (2)); | |
588 | BS.D0 (aLastU, aLastV, aPlanePnts->ChangeValue (3)); | |
589 | BS.D0 (aFirstU, aLastV, aPlanePnts->ChangeValue (4)); | |
590 | aPlanePnts->SetValue (5, aPlanePnts->Value (1)); | |
591 | ||
81bba717 | 592 | // if the plane is "infinite", it is sensitive only on the border limited by MaxParam |
c7ba4578 | 593 | const bool isInfinite = aFirstU == -theMaxParam |
594 | && aLastU == theMaxParam | |
595 | && aFirstV == -theMaxParam | |
596 | && aLastV == theMaxParam; | |
597 | theSensitiveList.Append (new Select3D_SensitiveFace (theOwner, aPlanePnts, | |
598 | theInteriorFlag && !isInfinite | |
599 | ? Select3D_TOS_INTERIOR | |
600 | : Select3D_TOS_BOUNDARY)); | |
7fd59977 | 601 | return Standard_True; |
602 | } | |
bbf32d01 | 603 | |
c7ba4578 | 604 | // This is construction of a sensitive polygon from the exterior contour of the face... |
81bba717 | 605 | // It is not good at all, but... |
7fd59977 | 606 | TopoDS_Wire aWire; |
bbf32d01 | 607 | { |
c7ba4578 | 608 | TopExp_Explorer anExpWiresInFace (theFace, TopAbs_WIRE); |
609 | if (anExpWiresInFace.More()) | |
610 | { | |
611 | // believing that this is the first... to be seen | |
612 | aWire = TopoDS::Wire (anExpWiresInFace.Current()); | |
613 | } | |
bbf32d01 K |
614 | } |
615 | if (aWire.IsNull()) | |
616 | { | |
617 | return Standard_False; | |
618 | } | |
7fd59977 | 619 | |
c7ba4578 | 620 | TColgp_SequenceOfPnt aWirePoints; |
621 | Standard_Boolean isFirstExp = Standard_True; | |
bbf32d01 | 622 | BRepAdaptor_Curve cu3d; |
c7ba4578 | 623 | for (BRepTools_WireExplorer aWireExplorer (aWire); aWireExplorer.More(); aWireExplorer.Next()) |
bbf32d01 | 624 | { |
4ba5491a | 625 | try |
626 | { | |
627 | OCC_CATCH_SIGNALS | |
628 | cu3d.Initialize (aWireExplorer.Current()); | |
629 | } | |
a738b534 | 630 | catch (Standard_NullObject const&) |
4ba5491a | 631 | { |
632 | continue; | |
633 | } | |
634 | ||
c7ba4578 | 635 | Standard_Real wf = 0.0, wl = 0.0; |
bbf32d01 K |
636 | BRep_Tool::Range (aWireExplorer.Current(), wf, wl); |
637 | if (Abs (wf - wl) <= Precision::Confusion()) | |
638 | { | |
0797d9d3 | 639 | #ifdef OCCT_DEBUG |
04232180 | 640 | std::cout<<" StdSelect_BRepSelectionTool : Curve where ufirst = ulast ...."<<std::endl; |
bbf32d01 | 641 | #endif |
c7ba4578 | 642 | continue; |
7fd59977 | 643 | } |
c7ba4578 | 644 | |
645 | if (isFirstExp) | |
bbf32d01 | 646 | { |
c7ba4578 | 647 | isFirstExp = Standard_False; |
648 | if (aWireExplorer.Orientation() == TopAbs_FORWARD) | |
bbf32d01 | 649 | { |
c7ba4578 | 650 | aWirePoints.Append (cu3d.Value (wf)); |
651 | } | |
652 | else | |
653 | { | |
654 | aWirePoints.Append (cu3d.Value (wl)); | |
7fd59977 | 655 | } |
c7ba4578 | 656 | } |
bbf32d01 | 657 | |
c7ba4578 | 658 | switch (cu3d.GetType()) |
659 | { | |
660 | case GeomAbs_Line: | |
bbf32d01 | 661 | { |
c7ba4578 | 662 | aWirePoints.Append (cu3d.Value ((aWireExplorer.Orientation() == TopAbs_FORWARD) ? wl : wf)); |
663 | break; | |
664 | } | |
665 | case GeomAbs_Circle: | |
666 | { | |
667 | if (2.0 * M_PI - Abs (wl - wf) <= Precision::Confusion()) | |
bbf32d01 | 668 | { |
c7ba4578 | 669 | if (BS.GetType() == GeomAbs_Cylinder || |
670 | BS.GetType() == GeomAbs_Torus || | |
671 | BS.GetType() == GeomAbs_Cone || | |
672 | BS.GetType() == GeomAbs_BSplineSurface) // beuurkk pour l'instant... | |
bbf32d01 | 673 | { |
c7ba4578 | 674 | Standard_Real ff = wf ,ll = wl; |
675 | Standard_Real dw =(Max (wf, wl) - Min (wf, wl)) / (Standard_Real )Max (2, NbPOnEdge - 1); | |
676 | if (aWireExplorer.Orientation() == TopAbs_FORWARD) | |
bbf32d01 | 677 | { |
c7ba4578 | 678 | for (Standard_Real wc = wf + dw; wc <= wl; wc += dw) |
bbf32d01 | 679 | { |
c7ba4578 | 680 | aWirePoints.Append (cu3d.Value (wc)); |
bbf32d01 K |
681 | } |
682 | } | |
c7ba4578 | 683 | else if (aWireExplorer.Orientation() == TopAbs_REVERSED) |
bbf32d01 | 684 | { |
c7ba4578 | 685 | for (Standard_Real wc = ll - dw; wc >= ff; wc -= dw) |
bbf32d01 | 686 | { |
c7ba4578 | 687 | aWirePoints.Append (cu3d.Value (wc)); |
bbf32d01 K |
688 | } |
689 | } | |
690 | } | |
691 | else | |
692 | { | |
c7ba4578 | 693 | if (cu3d.Circle().Radius() <= Precision::Confusion()) |
bbf32d01 | 694 | { |
c7ba4578 | 695 | theSensitiveList.Append (new Select3D_SensitivePoint (theOwner, cu3d.Circle().Location())); |
bbf32d01 | 696 | } |
c7ba4578 | 697 | else |
bbf32d01 | 698 | { |
c7ba4578 | 699 | theSensitiveList.Append (new Select3D_SensitiveCircle (theOwner, new Geom_Circle (cu3d.Circle()), theInteriorFlag, 16)); |
bbf32d01 K |
700 | } |
701 | } | |
bbf32d01 | 702 | } |
c7ba4578 | 703 | else |
bbf32d01 K |
704 | { |
705 | Standard_Real ff = wf, ll = wl; | |
706 | Standard_Real dw = (Max (wf, wl) - Min (wf, wl)) / (Standard_Real )Max (2, NbPOnEdge - 1); | |
c7ba4578 | 707 | if (aWireExplorer.Orientation() == TopAbs_FORWARD) |
bbf32d01 K |
708 | { |
709 | for (Standard_Real wc = wf + dw; wc <= wl; wc += dw) | |
710 | { | |
c7ba4578 | 711 | aWirePoints.Append (cu3d.Value (wc)); |
bbf32d01 K |
712 | } |
713 | } | |
714 | else if (aWireExplorer.Orientation() == TopAbs_REVERSED) | |
715 | { | |
716 | for (Standard_Real wc = ll - dw; wc >= ff; wc -= dw) | |
717 | { | |
c7ba4578 | 718 | aWirePoints.Append (cu3d.Value (wc)); |
bbf32d01 K |
719 | } |
720 | } | |
721 | } | |
c7ba4578 | 722 | break; |
723 | } | |
724 | default: | |
725 | { | |
726 | Standard_Real ff = wf, ll = wl; | |
727 | Standard_Real dw = (Max (wf, wl) - Min (wf, wl)) / (Standard_Real )Max (2, NbPOnEdge - 1); | |
728 | if (aWireExplorer.Orientation()==TopAbs_FORWARD) | |
729 | { | |
730 | for (Standard_Real wc = wf + dw; wc <= wl; wc += dw) | |
731 | { | |
732 | aWirePoints.Append (cu3d.Value (wc)); | |
733 | } | |
734 | } | |
735 | else if (aWireExplorer.Orientation() == TopAbs_REVERSED) | |
736 | { | |
737 | for (Standard_Real wc = ll - dw; wc >= ff; wc -= dw) | |
738 | { | |
739 | aWirePoints.Append (cu3d.Value (wc)); | |
740 | } | |
741 | } | |
7fd59977 | 742 | } |
743 | } | |
744 | } | |
bbf32d01 | 745 | |
c7ba4578 | 746 | Handle(TColgp_HArray1OfPnt) aFacePoints = new TColgp_HArray1OfPnt (1, aWirePoints.Length()); |
bbf32d01 | 747 | { |
c7ba4578 | 748 | Standard_Integer aPntIndex = 1; |
749 | for (TColgp_SequenceOfPnt::Iterator aPntIter (aWirePoints); aPntIter.More(); aPntIter.Next()) | |
750 | { | |
751 | aFacePoints->SetValue (aPntIndex++, aPntIter.Value()); | |
752 | } | |
bbf32d01 K |
753 | } |
754 | ||
c7ba4578 | 755 | // 1 if only one circular edge |
756 | if (aFacePoints->Array1().Length() == 2) | |
757 | { | |
758 | theSensitiveList.Append (new Select3D_SensitiveCurve (theOwner, aFacePoints)); | |
759 | } | |
760 | else if (aFacePoints->Array1().Length() > 2) | |
761 | { | |
762 | theSensitiveList.Append (new Select3D_SensitiveFace (theOwner, aFacePoints, | |
763 | theInteriorFlag | |
764 | ? Select3D_TOS_INTERIOR | |
765 | : Select3D_TOS_BOUNDARY)); | |
7fd59977 | 766 | } |
767 | return Standard_True; | |
768 | } |