0031313: Foundation Classes - Dump improvement for classes
[occt.git] / src / StdSelect / StdSelect_BRepSelectionTool.cxx
CommitLineData
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 74void 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 105void 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 169void 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 204void 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 323static 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//==================================================
383static 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 436void 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 560Standard_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}