1 // Created on: 1995-03-14
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <StdSelect_BRepSelectionTool.hxx>
19 #include <Bnd_Box.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <BRepBndLib.hxx>
24 #include <BRepMesh_IncrementalMesh.hxx>
25 #include <BRepTools.hxx>
26 #include <BRepTools_WireExplorer.hxx>
27 #include <GCPnts_TangentialDeflection.hxx>
28 #include <GeomAbs_SurfaceType.hxx>
29 #include <GeomAdaptor_Curve.hxx>
30 #include <Geom_SphericalSurface.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>
38 #include <Select3D_SensitiveCircle.hxx>
39 #include <Select3D_SensitiveCurve.hxx>
40 #include <Select3D_SensitiveEntity.hxx>
41 #include <Select3D_SensitiveFace.hxx>
42 #include <Select3D_SensitiveGroup.hxx>
43 #include <Select3D_SensitivePoint.hxx>
44 #include <Select3D_SensitiveSegment.hxx>
45 #include <Select3D_SensitiveSphere.hxx>
46 #include <Select3D_SensitiveTriangle.hxx>
47 #include <Select3D_SensitiveTriangulation.hxx>
48 #include <Select3D_SensitiveWire.hxx>
49 #include <Select3D_TypeOfSensitivity.hxx>
50 #include <SelectMgr_EntityOwner.hxx>
51 #include <SelectMgr_SelectableObject.hxx>
52 #include <SelectMgr_Selection.hxx>
53 #include <Standard_ErrorHandler.hxx>
54 #include <Standard_NullObject.hxx>
55 #include <StdSelect_BRepOwner.hxx>
56 #include <TColgp_HArray1OfPnt.hxx>
57 #include <TColgp_SequenceOfPnt.hxx>
58 #include <TColStd_Array1OfReal.hxx>
60 #include <TopExp_Explorer.hxx>
62 #include <TopoDS_Face.hxx>
63 #include <TopoDS_Shape.hxx>
64 #include <TopoDS_Wire.hxx>
65 #include <TopTools_IndexedMapOfShape.hxx>
67 #define BVH_PRIMITIVE_LIMIT 800000
69 //==================================================
70 // function: PreBuildBVH
71 // purpose : Pre-builds BVH tree for heavyweight
72 // sensitive entities with sub-elements
73 // amount more than BVH_PRIMITIVE_LIMIT
74 //==================================================
75 void StdSelect_BRepSelectionTool::PreBuildBVH (const Handle(SelectMgr_Selection)& theSelection)
77 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
79 const Handle(Select3D_SensitiveEntity)& aSensitive = aSelEntIter.Value()->BaseSensitive();
80 if (aSensitive->NbSubElements() >= BVH_PRIMITIVE_LIMIT)
85 if (!aSensitive->IsInstance (STANDARD_TYPE(Select3D_SensitiveGroup)))
90 Handle(Select3D_SensitiveGroup) aGroup = Handle(Select3D_SensitiveGroup)::DownCast (aSensitive);
91 for (Select3D_IndexedMapOfEntity::Iterator aSubEntitiesIter (aGroup->Entities()); aSubEntitiesIter.More(); aSubEntitiesIter.Next())
93 const Handle(Select3D_SensitiveEntity)& aSubEntity = aSubEntitiesIter.Value();
94 if (aSubEntity->NbSubElements() >= BVH_PRIMITIVE_LIMIT)
102 //==================================================
105 //==================================================
106 void StdSelect_BRepSelectionTool::Load (const Handle(SelectMgr_Selection)& theSelection,
107 const TopoDS_Shape& theShape,
108 const TopAbs_ShapeEnum theType,
109 const Standard_Real theDeflection,
110 const Standard_Real theDeviationAngle,
111 const Standard_Boolean isAutoTriangulation,
112 const Standard_Integer thePriority,
113 const Standard_Integer theNbPOnEdge,
114 const Standard_Real theMaxParam)
116 Standard_Integer aPriority = (thePriority == -1) ? GetStandardPriority (theShape, theType) : thePriority;
117 if (isAutoTriangulation
118 && !BRepTools::Triangulation (theShape, Precision::Infinite(), true))
120 BRepMesh_IncrementalMesh aMesher(theShape, theDeflection, Standard_False, theDeviationAngle);
123 Handle(StdSelect_BRepOwner) aBrepOwner;
132 case TopAbs_COMPSOLID:
134 TopTools_IndexedMapOfShape aSubShapes;
135 TopExp::MapShapes (theShape, theType, aSubShapes);
137 Standard_Boolean isComesFromDecomposition = !((aSubShapes.Extent() == 1) && (theShape == aSubShapes (1)));
138 for (Standard_Integer aShIndex = 1; aShIndex <= aSubShapes.Extent(); ++aShIndex)
140 const TopoDS_Shape& aSubShape = aSubShapes (aShIndex);
141 aBrepOwner = new StdSelect_BRepOwner (aSubShape, aPriority, isComesFromDecomposition);
142 ComputeSensitive (aSubShape, aBrepOwner,
148 isAutoTriangulation);
154 aBrepOwner = new StdSelect_BRepOwner (theShape, aPriority);
155 ComputeSensitive (theShape, aBrepOwner,
161 isAutoTriangulation);
166 //==================================================
169 //==================================================
170 void StdSelect_BRepSelectionTool::Load (const Handle(SelectMgr_Selection)& theSelection,
171 const Handle(SelectMgr_SelectableObject)& theSelectableObj,
172 const TopoDS_Shape& theShape,
173 const TopAbs_ShapeEnum theType,
174 const Standard_Real theDeflection,
175 const Standard_Real theDeviationAngle,
176 const Standard_Boolean isAutoTriangulation,
177 const Standard_Integer thePriority,
178 const Standard_Integer theNbPOnEdge,
179 const Standard_Real theMaxParam)
191 // loading of selectables...
192 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
194 const Handle(SelectMgr_EntityOwner)& anOwner = aSelEntIter.Value()->BaseSensitive()->OwnerId();
195 anOwner->SetSelectable (theSelectableObj);
199 //==================================================
200 // Function: ComputeSensitive
202 //==================================================
203 void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape,
204 const Handle(SelectMgr_EntityOwner)& theOwner,
205 const Handle(SelectMgr_Selection)& theSelection,
206 const Standard_Real theDeflection,
207 const Standard_Real theDeviationAngle,
208 const Standard_Integer theNbPOnEdge,
209 const Standard_Real theMaxParam,
210 const Standard_Boolean isAutoTriangulation)
212 switch (theShape.ShapeType())
216 theSelection->Add (new Select3D_SensitivePoint
217 (theOwner, BRep_Tool::Pnt (TopoDS::Vertex (theShape))));
222 Handle(Select3D_SensitiveEntity) aSensitive;
223 GetEdgeSensitive (theShape, theOwner, theSelection,
224 theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam,
226 if (!aSensitive.IsNull())
228 theSelection->Add (aSensitive);
234 BRepTools_WireExplorer aWireExp (TopoDS::Wire (theShape));
235 Handle (Select3D_SensitiveEntity) aSensitive;
236 Handle (Select3D_SensitiveWire) aWireSensitive = new Select3D_SensitiveWire (theOwner);
237 theSelection->Add (aWireSensitive);
238 while (aWireExp.More())
240 GetEdgeSensitive (aWireExp.Current(), theOwner, theSelection,
241 theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam,
243 if (!aSensitive.IsNull())
245 aWireSensitive->Add (aSensitive);
253 const TopoDS_Face& aFace = TopoDS::Face (theShape);
254 Select3D_EntitySequence aSensitiveList;
255 GetSensitiveForFace (aFace, theOwner,
257 isAutoTriangulation, theNbPOnEdge, theMaxParam);
258 for (Select3D_EntitySequenceIter aSensIter (aSensitiveList);
259 aSensIter.More(); aSensIter.Next())
261 theSelection->Add (aSensIter.Value());
267 case TopAbs_COMPSOLID:
269 TopTools_IndexedMapOfShape aSubfacesMap;
270 TopExp::MapShapes (theShape, TopAbs_FACE, aSubfacesMap);
271 for (Standard_Integer aShIndex = 1; aShIndex <= aSubfacesMap.Extent(); ++aShIndex)
273 ComputeSensitive (aSubfacesMap (aShIndex), theOwner,
275 theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation);
279 case TopAbs_COMPOUND:
282 TopExp_Explorer anExp;
284 for (anExp.Init (theShape, TopAbs_VERTEX, TopAbs_EDGE); anExp.More(); anExp.Next())
286 ComputeSensitive (anExp.Current(), theOwner,
288 theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation);
291 for (anExp.Init (theShape, TopAbs_EDGE, TopAbs_FACE); anExp.More(); anExp.Next())
293 ComputeSensitive (anExp.Current(), theOwner,
295 theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation);
298 for (anExp.Init (theShape, TopAbs_WIRE, TopAbs_FACE); anExp.More(); anExp.Next())
300 ComputeSensitive (anExp.Current(), theOwner,
302 theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation);
306 TopTools_IndexedMapOfShape aSubfacesMap;
307 TopExp::MapShapes (theShape, TopAbs_FACE, aSubfacesMap);
308 for (Standard_Integer aShIndex = 1; aShIndex <= aSubfacesMap.Extent(); ++aShIndex)
310 ComputeSensitive (aSubfacesMap (aShIndex), theOwner,
312 theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation);
318 //==================================================
319 // Function: GetPointsFromPolygon
321 //==================================================
322 static Handle(TColgp_HArray1OfPnt) GetPointsFromPolygon (const TopoDS_Edge& theEdge)
324 Handle(TColgp_HArray1OfPnt) aResultPoints;
326 TopLoc_Location aLocation;
327 Handle(Poly_Polygon3D) aPolygon = BRep_Tool::Polygon3D (theEdge, aLocation);
328 if (!aPolygon.IsNull())
330 const TColgp_Array1OfPnt& aNodes = aPolygon->Nodes();
331 aResultPoints = new TColgp_HArray1OfPnt (1, aNodes.Length());
332 if (aLocation.IsIdentity())
334 for (Standard_Integer aNodeId (aNodes.Lower()), aPntId (1); aNodeId <= aNodes.Upper(); ++aNodeId, ++aPntId)
336 aResultPoints->SetValue (aPntId, aNodes.Value (aNodeId));
341 for (Standard_Integer aNodeId (aNodes.Lower()), aPntId (1); aNodeId <= aNodes.Upper(); ++aNodeId, ++aPntId)
343 aResultPoints->SetValue (aPntId, aNodes.Value (aNodeId).Transformed (aLocation));
346 return aResultPoints;
349 Handle(Poly_Triangulation) aTriangulation;
350 Handle(Poly_PolygonOnTriangulation) anHIndices;
351 BRep_Tool::PolygonOnTriangulation (theEdge, anHIndices, aTriangulation, aLocation);
352 if (!anHIndices.IsNull())
354 const TColStd_Array1OfInteger& anIndices = anHIndices->Nodes();
356 aResultPoints = new TColgp_HArray1OfPnt (1, anIndices.Length());
358 if (aLocation.IsIdentity())
360 for (Standard_Integer anIndex (anIndices.Lower()), aPntId (1); anIndex <= anIndices.Upper(); ++anIndex, ++aPntId)
362 aResultPoints->SetValue (aPntId, aTriangulation->Node (anIndices[anIndex]));
367 for (Standard_Integer anIndex (anIndices.Lower()), aPntId (1); anIndex <= anIndices.Upper(); ++anIndex, ++aPntId)
369 aResultPoints->SetValue (aPntId, aTriangulation->Node (anIndices[anIndex]).Transformed (aLocation));
372 return aResultPoints;
374 return aResultPoints;
377 //==================================================
378 // Function: FindLimits
380 //==================================================
381 static Standard_Boolean FindLimits (const Adaptor3d_Curve& theCurve,
382 const Standard_Real theLimit,
383 Standard_Real& theFirst,
384 Standard_Real& theLast)
386 theFirst = theCurve.FirstParameter();
387 theLast = theCurve.LastParameter();
388 Standard_Boolean isFirstInf = Precision::IsNegativeInfinite (theFirst);
389 Standard_Boolean isLastInf = Precision::IsPositiveInfinite (theLast);
390 if (isFirstInf || isLastInf)
393 Standard_Real aDelta = 1.0;
394 Standard_Integer anIterCount = 0;
395 if (isFirstInf && isLastInf)
398 if (anIterCount++ >= 100000) return Standard_False;
402 theCurve.D0 (theFirst, aPnt1);
403 theCurve.D0 (theLast, aPnt2);
404 } while (aPnt1.Distance (aPnt2) < theLimit);
408 theCurve.D0 (theLast, aPnt2);
410 if (anIterCount++ >= 100000) return Standard_False;
412 theFirst = theLast - aDelta;
413 theCurve.D0 (theFirst, aPnt1);
414 } while (aPnt1.Distance (aPnt2) < theLimit);
418 theCurve.D0 (theFirst, aPnt1);
420 if (anIterCount++ >= 100000) return Standard_False;
422 theLast = theFirst + aDelta;
423 theCurve.D0 (theLast, aPnt2);
424 } while (aPnt1.Distance (aPnt2) < theLimit);
427 return Standard_True;
430 //=====================================================
431 // Function : GetEdgeSensitive
433 //=====================================================
434 void StdSelect_BRepSelectionTool::GetEdgeSensitive (const TopoDS_Shape& theShape,
435 const Handle(SelectMgr_EntityOwner)& theOwner,
436 const Handle(SelectMgr_Selection)& theSelection,
437 const Standard_Real theDeflection,
438 const Standard_Real theDeviationAngle,
439 const Standard_Integer theNbPOnEdge,
440 const Standard_Real theMaxParam,
441 Handle(Select3D_SensitiveEntity)& theSensitive)
443 const TopoDS_Edge& anEdge = TopoDS::Edge (theShape);
444 // try to get points from existing polygons
445 Handle(TColgp_HArray1OfPnt) aPoints = GetPointsFromPolygon (anEdge);
446 if (!aPoints.IsNull()
447 && !aPoints->IsEmpty())
449 if (aPoints->Length() == 2)
451 // don't waste memory, create a segment
452 theSensitive = new Select3D_SensitiveSegment (theOwner, aPoints->First(), aPoints->Last());
456 theSensitive = new Select3D_SensitiveCurve (theOwner, aPoints);
461 BRepAdaptor_Curve cu3d;
464 cu3d.Initialize (anEdge);
465 } catch (Standard_NullObject const&) {
469 Standard_Real aParamFirst = cu3d.FirstParameter();
470 Standard_Real aParamLast = cu3d.LastParameter();
471 switch (cu3d.GetType())
475 BRep_Tool::Range (anEdge, aParamFirst, aParamLast);
476 theSensitive = new Select3D_SensitiveSegment (theOwner,
477 cu3d.Value (aParamFirst),
478 cu3d.Value (aParamLast));
483 const gp_Circ aCircle = cu3d.Circle();
484 if (aCircle.Radius() <= Precision::Confusion())
486 theSelection->Add (new Select3D_SensitivePoint (theOwner, aCircle.Location()));
490 theSensitive = new Select3D_SensitiveCircle (theOwner, aCircle,
491 aParamFirst, aParamLast, Standard_False, 16);
497 // reproduce drawing behaviour
498 // TODO: remove copy-paste from StdPrs_Curve and some others...
499 if (FindLimits (cu3d, theMaxParam, aParamFirst, aParamLast))
501 Standard_Integer aNbIntervals = cu3d.NbIntervals (GeomAbs_C1);
502 TColStd_Array1OfReal anIntervals (1, aNbIntervals + 1);
503 cu3d.Intervals (anIntervals, GeomAbs_C1);
504 Standard_Real aV1, aV2;
505 Standard_Integer aNumberOfPoints;
506 TColgp_SequenceOfPnt aPointsSeq;
507 for (Standard_Integer anIntervalId = 1; anIntervalId <= aNbIntervals; ++anIntervalId)
509 aV1 = anIntervals (anIntervalId);
510 aV2 = anIntervals (anIntervalId + 1);
511 if (aV2 > aParamFirst && aV1 < aParamLast)
513 aV1 = Max (aV1, aParamFirst);
514 aV2 = Min (aV2, aParamLast);
516 GCPnts_TangentialDeflection anAlgo (cu3d, aV1, aV2, theDeviationAngle, theDeflection);
517 aNumberOfPoints = anAlgo.NbPoints();
519 for (Standard_Integer aPntId = 1; aPntId < aNumberOfPoints; ++aPntId)
521 aPointsSeq.Append (anAlgo.Value (aPntId));
523 if (aNumberOfPoints > 0 && anIntervalId == aNbIntervals)
525 aPointsSeq.Append (anAlgo.Value (aNumberOfPoints));
530 aPoints = new TColgp_HArray1OfPnt (1, aPointsSeq.Length());
531 for (Standard_Integer aPntId = 1; aPntId <= aPointsSeq.Length(); ++aPntId)
533 aPoints->SetValue (aPntId, aPointsSeq.Value (aPntId));
535 theSensitive = new Select3D_SensitiveCurve (theOwner, aPoints);
539 // simple subdivisions
540 Standard_Integer nbintervals = 1;
541 if (cu3d.GetType() == GeomAbs_BSplineCurve)
543 nbintervals = cu3d.NbKnots() - 1;
544 nbintervals = Max (1, nbintervals / 3);
547 Standard_Real aParam;
548 Standard_Integer aPntNb = Max (2, theNbPOnEdge * nbintervals);
549 Standard_Real aParamDelta = (aParamLast - aParamFirst) / (aPntNb - 1);
550 Handle(TColgp_HArray1OfPnt) aPointArray = new TColgp_HArray1OfPnt (1, aPntNb);
551 for (Standard_Integer aPntId = 1; aPntId <= aPntNb; ++aPntId)
553 aParam = aParamFirst + aParamDelta * (aPntId - 1);
554 aPointArray->SetValue (aPntId, cu3d.Value (aParam));
556 theSensitive = new Select3D_SensitiveCurve (theOwner, aPointArray);
562 //=======================================================================
563 //function : GetSensitiveEntityForFace
565 //=======================================================================
566 Standard_Boolean StdSelect_BRepSelectionTool::GetSensitiveForFace (const TopoDS_Face& theFace,
567 const Handle(SelectMgr_EntityOwner)& theOwner,
568 Select3D_EntitySequence& theSensitiveList,
569 const Standard_Boolean /*theAutoTriangulation*/,
570 const Standard_Integer NbPOnEdge,
571 const Standard_Real theMaxParam,
572 const Standard_Boolean theInteriorFlag)
574 TopLoc_Location aLoc;
575 if (Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (theFace, aLoc))
577 TopLoc_Location aLocSurf;
578 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (theFace, aLocSurf);
579 if (Handle(Geom_SphericalSurface) aGeomSphere = Handle(Geom_SphericalSurface)::DownCast (aSurf))
581 bool isFullSphere = theFace.NbChildren() == 0;
582 if (theFace.NbChildren() == 1)
584 const TopoDS_Iterator aWireIter (theFace);
585 const TopoDS_Wire& aWire = TopoDS::Wire (aWireIter.Value());
586 if (aWire.NbChildren() == 4)
588 Standard_Integer aNbSeamEdges = 0, aNbDegenEdges = 0;
589 for (TopoDS_Iterator anEdgeIter (aWire); anEdgeIter.More(); anEdgeIter.Next())
591 const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Value());
592 aNbSeamEdges += BRep_Tool::IsClosed (anEdge, theFace);
593 aNbDegenEdges += BRep_Tool::Degenerated (anEdge);
595 isFullSphere = aNbSeamEdges == 2 && aNbDegenEdges == 2;
600 gp_Sphere aSphere = BRepAdaptor_Surface (theFace).Sphere();
601 Handle(Select3D_SensitiveSphere) aSensSphere = new Select3D_SensitiveSphere (theOwner, aSphere.Position().Axis().Location(), aSphere.Radius());
602 theSensitiveList.Append (aSensSphere);
603 return Standard_True;
606 Handle(Select3D_SensitiveTriangulation) STG = new Select3D_SensitiveTriangulation (theOwner, aTriangulation, aLoc, theInteriorFlag);
607 theSensitiveList.Append (STG);
608 return Standard_True;
611 // for faces with triangulation bugs or without autotriangulation ....
612 // very ugly and should not even exist ...
613 BRepAdaptor_Surface BS (theFace);
614 if (BS.GetType() == GeomAbs_Plane)
616 const Standard_Real aFirstU = BS.FirstUParameter() <= -Precision::Infinite() ? -theMaxParam : BS.FirstUParameter();
617 const Standard_Real aLastU = BS.LastUParameter() >= Precision::Infinite() ? theMaxParam : BS.LastUParameter();
618 const Standard_Real aFirstV = BS.FirstVParameter() <= -Precision::Infinite() ? -theMaxParam : BS.FirstVParameter();
619 const Standard_Real aLastV = BS.LastVParameter() >= Precision::Infinite() ? theMaxParam : BS.LastVParameter();
620 Handle(TColgp_HArray1OfPnt) aPlanePnts = new TColgp_HArray1OfPnt (1, 5);
621 BS.D0 (aFirstU, aFirstV, aPlanePnts->ChangeValue (1));
622 BS.D0 (aLastU, aFirstV, aPlanePnts->ChangeValue (2));
623 BS.D0 (aLastU, aLastV, aPlanePnts->ChangeValue (3));
624 BS.D0 (aFirstU, aLastV, aPlanePnts->ChangeValue (4));
625 aPlanePnts->SetValue (5, aPlanePnts->Value (1));
627 // if the plane is "infinite", it is sensitive only on the border limited by MaxParam
628 const bool isInfinite = aFirstU == -theMaxParam
629 && aLastU == theMaxParam
630 && aFirstV == -theMaxParam
631 && aLastV == theMaxParam;
632 theSensitiveList.Append (new Select3D_SensitiveFace (theOwner, aPlanePnts,
633 theInteriorFlag && !isInfinite
634 ? Select3D_TOS_INTERIOR
635 : Select3D_TOS_BOUNDARY));
636 return Standard_True;
639 // This is construction of a sensitive polygon from the exterior contour of the face...
640 // It is not good at all, but...
643 TopExp_Explorer anExpWiresInFace (theFace, TopAbs_WIRE);
644 if (anExpWiresInFace.More())
646 // believing that this is the first... to be seen
647 aWire = TopoDS::Wire (anExpWiresInFace.Current());
652 return Standard_False;
655 TColgp_SequenceOfPnt aWirePoints;
656 Standard_Boolean isFirstExp = Standard_True;
657 BRepAdaptor_Curve cu3d;
658 for (BRepTools_WireExplorer aWireExplorer (aWire); aWireExplorer.More(); aWireExplorer.Next())
663 cu3d.Initialize (aWireExplorer.Current());
665 catch (Standard_NullObject const&)
670 Standard_Real wf = 0.0, wl = 0.0;
671 BRep_Tool::Range (aWireExplorer.Current(), wf, wl);
672 if (Abs (wf - wl) <= Precision::Confusion())
675 std::cout<<" StdSelect_BRepSelectionTool : Curve where ufirst = ulast ...."<<std::endl;
682 isFirstExp = Standard_False;
683 if (aWireExplorer.Orientation() == TopAbs_FORWARD)
685 aWirePoints.Append (cu3d.Value (wf));
689 aWirePoints.Append (cu3d.Value (wl));
693 switch (cu3d.GetType())
697 aWirePoints.Append (cu3d.Value ((aWireExplorer.Orientation() == TopAbs_FORWARD) ? wl : wf));
702 if (2.0 * M_PI - Abs (wl - wf) <= Precision::Confusion())
704 if (BS.GetType() == GeomAbs_Cylinder ||
705 BS.GetType() == GeomAbs_Torus ||
706 BS.GetType() == GeomAbs_Cone ||
707 BS.GetType() == GeomAbs_BSplineSurface) // beuurkk pour l'instant...
709 Standard_Real ff = wf ,ll = wl;
710 Standard_Real dw =(Max (wf, wl) - Min (wf, wl)) / (Standard_Real )Max (2, NbPOnEdge - 1);
711 if (aWireExplorer.Orientation() == TopAbs_FORWARD)
713 for (Standard_Real wc = wf + dw; wc <= wl; wc += dw)
715 aWirePoints.Append (cu3d.Value (wc));
718 else if (aWireExplorer.Orientation() == TopAbs_REVERSED)
720 for (Standard_Real wc = ll - dw; wc >= ff; wc -= dw)
722 aWirePoints.Append (cu3d.Value (wc));
728 if (cu3d.Circle().Radius() <= Precision::Confusion())
730 theSensitiveList.Append (new Select3D_SensitivePoint (theOwner, cu3d.Circle().Location()));
734 theSensitiveList.Append (new Select3D_SensitiveCircle (theOwner, cu3d.Circle(), theInteriorFlag, 16));
740 Standard_Real ff = wf, ll = wl;
741 Standard_Real dw = (Max (wf, wl) - Min (wf, wl)) / (Standard_Real )Max (2, NbPOnEdge - 1);
742 if (aWireExplorer.Orientation() == TopAbs_FORWARD)
744 for (Standard_Real wc = wf + dw; wc <= wl; wc += dw)
746 aWirePoints.Append (cu3d.Value (wc));
749 else if (aWireExplorer.Orientation() == TopAbs_REVERSED)
751 for (Standard_Real wc = ll - dw; wc >= ff; wc -= dw)
753 aWirePoints.Append (cu3d.Value (wc));
761 Standard_Real ff = wf, ll = wl;
762 Standard_Real dw = (Max (wf, wl) - Min (wf, wl)) / (Standard_Real )Max (2, NbPOnEdge - 1);
763 if (aWireExplorer.Orientation()==TopAbs_FORWARD)
765 for (Standard_Real wc = wf + dw; wc <= wl; wc += dw)
767 aWirePoints.Append (cu3d.Value (wc));
770 else if (aWireExplorer.Orientation() == TopAbs_REVERSED)
772 for (Standard_Real wc = ll - dw; wc >= ff; wc -= dw)
774 aWirePoints.Append (cu3d.Value (wc));
781 Handle(TColgp_HArray1OfPnt) aFacePoints = new TColgp_HArray1OfPnt (1, aWirePoints.Length());
783 Standard_Integer aPntIndex = 1;
784 for (TColgp_SequenceOfPnt::Iterator aPntIter (aWirePoints); aPntIter.More(); aPntIter.Next())
786 aFacePoints->SetValue (aPntIndex++, aPntIter.Value());
790 // 1 if only one circular edge
791 if (aFacePoints->Array1().Length() == 2)
793 theSensitiveList.Append (new Select3D_SensitiveCurve (theOwner, aFacePoints));
795 else if (aFacePoints->Array1().Length() > 2)
797 theSensitiveList.Append (new Select3D_SensitiveFace (theOwner, aFacePoints,
799 ? Select3D_TOS_INTERIOR
800 : Select3D_TOS_BOUNDARY));
802 return Standard_True;