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