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