0027119: Regression: Draw command "incmesh" hangs on the attacheced face.
[occt.git] / src / BRepMesh / BRepMesh_CircleTool.cxx
CommitLineData
b311480e 1// Created on: 1993-06-15
2// Created by: Didier PIFFAULT
3// Copyright (c) 1993-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.
0d88155b 16
fc9b36d6 17#include <BRepMesh_CircleTool.hxx>
18#include <BRepMesh_GeomTool.hxx>
19#include <gp_Circ2d.hxx>
0d88155b 20#include <Precision.hxx>
fc9b36d6 21#include <BRepMesh_Circle.hxx>
0d88155b 22#include <BRepMesh_CircleInspector.hxx>
0d88155b
O
23
24//=======================================================================
25//function : Inspect
26//purpose :
0d88155b 27//=======================================================================
fc9b36d6 28NCollection_CellFilter_Action BRepMesh_CircleInspector::Inspect(
29 const Standard_Integer theTargetIndex)
0d88155b 30{
fc9b36d6 31 const BRepMesh_Circle& aCircle = myCircles(theTargetIndex);
32 Standard_Real aRadius = aCircle.Radius();
33 if(aRadius < 0.)
0d88155b 34 return CellFilter_Purge;
fc9b36d6 35
36 const gp_XY& aLoc = aCircle.Location();
37
38 if ((myPoint - aLoc).SquareModulus() - (aRadius * aRadius) <= myTolerance)
39 myResIndices.Append(theTargetIndex);
40
0d88155b
O
41 return CellFilter_Keep;
42}
43
44
45//=======================================================================
46//function : BRepMesh_CircleTool
47//purpose :
48//=======================================================================
fc9b36d6 49BRepMesh_CircleTool::BRepMesh_CircleTool(
848fa7e3 50 const Handle(NCollection_IncAllocator)& theAllocator)
fc9b36d6 51: myTolerance (Precision::PConfusion() * Precision::PConfusion()),
52 myAllocator (theAllocator),
7c4740f8 53 myCellFilter(10.0, theAllocator),
fc9b36d6 54 mySelector (myTolerance, 64, theAllocator)
0d88155b 55{
0d88155b
O
56}
57
58//=======================================================================
59//function : BRepMesh_CircleTool
60//purpose :
61//=======================================================================
fc9b36d6 62BRepMesh_CircleTool::BRepMesh_CircleTool(
848fa7e3 63 const Standard_Integer theReservedSize,
64 const Handle(NCollection_IncAllocator)& theAllocator)
fc9b36d6 65: myTolerance (Precision::PConfusion() * Precision::PConfusion()),
66 myAllocator (theAllocator),
7c4740f8 67 myCellFilter(10.0, theAllocator),
fc9b36d6 68 mySelector (myTolerance, Max(theReservedSize, 64), theAllocator)
0d88155b 69{
0d88155b
O
70}
71
0d88155b 72//=======================================================================
fc9b36d6 73//function : bind
0d88155b
O
74//purpose :
75//=======================================================================
fc9b36d6 76void BRepMesh_CircleTool::bind(const Standard_Integer theIndex,
77 const gp_XY& theLocation,
78 const Standard_Real theRadius)
0d88155b 79{
fc9b36d6 80 BRepMesh_Circle aCirle(theLocation, theRadius);
0d88155b 81
fc9b36d6 82 //compute coords
83 Standard_Real aMaxX = Min(theLocation.X() + theRadius, myFaceMax.X());
84 Standard_Real aMinX = Max(theLocation.X() - theRadius, myFaceMin.X());
85 Standard_Real aMaxY = Min(theLocation.Y() + theRadius, myFaceMax.Y());
86 Standard_Real aMinY = Max(theLocation.Y() - theRadius, myFaceMin.Y());
0d88155b 87
fc9b36d6 88 gp_XY aMinPnt(aMinX, aMinY);
89 gp_XY aMaxPnt(aMaxX, aMaxY);
0d88155b 90
fc9b36d6 91 myCellFilter.Add(theIndex, aMinPnt, aMaxPnt);
92 mySelector.Bind(theIndex, aCirle);
0d88155b
O
93}
94
95//=======================================================================
fc9b36d6 96//function : Bind
0d88155b
O
97//purpose :
98//=======================================================================
fc9b36d6 99void BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
100 const gp_Circ2d& theCircle)
0d88155b 101{
fc9b36d6 102 gp_XY aCoord = theCircle.Location().Coord();
103 Standard_Real aRadius = theCircle.Radius();
104 bind(theIndex, aCoord, aRadius);
0d88155b
O
105}
106
107//=======================================================================
ec26bf88 108//function : MakeCircle
0d88155b
O
109//purpose :
110//=======================================================================
ec26bf88 111Standard_Boolean BRepMesh_CircleTool::MakeCircle(const gp_XY& thePoint1,
112 const gp_XY& thePoint2,
113 const gp_XY& thePoint3,
114 gp_XY& theLocation,
115 Standard_Real& theRadius)
0d88155b 116{
ec26bf88 117 static const Standard_Real aPrecision = Precision::PConfusion();
118 static const Standard_Real aSqPrecision = aPrecision * aPrecision;
0d88155b 119
ec26bf88 120 if ((thePoint1 - thePoint3).SquareModulus() < aSqPrecision)
121 return Standard_False;
0d88155b 122
ec26bf88 123 gp_XY aLink1(thePoint2 - thePoint1);
124 if (aLink1.SquareModulus() < aSqPrecision)
125 return Standard_False;
0d88155b 126
ec26bf88 127 gp_XY aLink2(thePoint3 - thePoint2);
128 if (aLink2.SquareModulus() < aSqPrecision)
129 return Standard_False;
130
131 gp_XY aMidPnt1 = (thePoint1 + thePoint2) / 2.;
132 gp_XY aNorm1 = gp_XY(aLink1.Y(), -aLink1.X());
133 aNorm1.Add(aMidPnt1);
0d88155b 134
ec26bf88 135 if (aLink2.SquareModulus() < aSqPrecision)
136 return Standard_False;
0d88155b 137
ec26bf88 138 gp_XY aMidPnt2 = (thePoint2 + thePoint3) / 2.;
139 gp_XY aNorm2 = gp_XY(aLink2.Y(), -aLink2.X());
140 aNorm2.Add(aMidPnt2);
0d88155b 141
fc9b36d6 142 gp_XY aIntPnt;
143 Standard_Real aParam[2];
144 BRepMesh_GeomTool::IntFlag aIntFlag =
ec26bf88 145 BRepMesh_GeomTool::IntLinLin(aMidPnt1, aNorm1,
146 aMidPnt2, aNorm2, aIntPnt, aParam);
0d88155b 147
fc9b36d6 148 if (aIntFlag != BRepMesh_GeomTool::Cross)
149 return Standard_False;
0d88155b 150
ec26bf88 151 theLocation = aIntPnt;
152
153 theRadius = Sqrt(Max(Max((thePoint1 - aIntPnt).SquareModulus(),
154 (thePoint2 - aIntPnt).SquareModulus()),
66dce5e7 155 (thePoint3 - aIntPnt).SquareModulus())) + 2 * RealEpsilon();
ec26bf88 156
157 return Standard_True;
158}
159
160//=======================================================================
161//function : Bind
162//purpose :
163//=======================================================================
164Standard_Boolean BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
165 const gp_XY& thePoint1,
166 const gp_XY& thePoint2,
167 const gp_XY& thePoint3)
168{
169 gp_XY aLocation;
170 Standard_Real aRadius;
171 if (!MakeCircle(thePoint1, thePoint2, thePoint3, aLocation, aRadius))
172 return Standard_False;
173
174 bind(theIndex, aLocation, aRadius);
0d88155b
O
175 return Standard_True;
176}
177
178//=======================================================================
179//function : Delete
180//purpose :
181//=======================================================================
fc9b36d6 182void BRepMesh_CircleTool::Delete(const Standard_Integer theIndex)
0d88155b 183{
fc9b36d6 184 BRepMesh_Circle& aCircle = mySelector.Circle(theIndex);
185 if(aCircle.Radius() > 0.)
186 aCircle.SetRadius(-1);
0d88155b
O
187}
188
189//=======================================================================
190//function : Select
191//purpose :
192//=======================================================================
848fa7e3 193BRepMesh::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint)
0d88155b 194{
fc9b36d6 195 mySelector.SetPoint(thePoint);
196 myCellFilter.Inspect(thePoint, mySelector);
197 return mySelector.GetShotCircles();
0d88155b
O
198}
199
fc9b36d6 200//=======================================================================
201//function : MocBind
202//purpose :
203//=======================================================================
204void BRepMesh_CircleTool::MocBind(const Standard_Integer theIndex)
0d88155b 205{
fc9b36d6 206 BRepMesh_Circle aNullCir(gp::Origin2d().Coord(), -1.);
207 mySelector.Bind(theIndex, aNullCir);
0d88155b 208}