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