0030850: Visualization, OpenGl_Text - text within trihedron persistence jitters when...
[occt.git] / src / BRepMesh / BRepMesh_CircleTool.cxx
old mode 100755 (executable)
new mode 100644 (file)
index b260ac9..67aa20e
 // Created on: 1993-06-15
 // Created by: Didier PIFFAULT
 // Copyright (c) 1993-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
-
-#include <BRepMesh_CircleTool.ixx>
-#include <gp_XY.hxx>
+#include <BRepMesh_CircleTool.hxx>
+#include <BRepMesh_GeomTool.hxx>
+#include <gp_Circ2d.hxx>
 #include <Precision.hxx>
-#include <BRepMesh_Circ.hxx>
+#include <BRepMesh_Circle.hxx>
 #include <BRepMesh_CircleInspector.hxx>
-#include <BRepMesh_BaseAllocator.hxx>
-
 
 //=======================================================================
-//function : BRepMesh_CircleInspector
-//purpose  : Constructor
+//function : BRepMesh_CircleTool
+//purpose  : 
 //=======================================================================
-
-BRepMesh_CircleInspector::BRepMesh_CircleInspector (Standard_Real theTol,
-                                                    Standard_Integer nbComp,
-                                                    const BRepMesh_BaseAllocator& theAlloc)
-                                                    : myTol(theTol*theTol),
-                                                    myResInd(theAlloc),
-                                                    myInitCircle(nbComp)
+BRepMesh_CircleTool::BRepMesh_CircleTool(
+  const Handle(NCollection_IncAllocator)& theAllocator)
+: myTolerance (Precision::PConfusion()),
+  myAllocator (theAllocator),
+  myCellFilter(10.0, theAllocator),
+  mySelector  (myTolerance, 64, theAllocator)
 {
-  //  myTol = theTol*theTol;
 }
 
 //=======================================================================
-//function : Inspect
+//function : BRepMesh_CircleTool
 //purpose  : 
-//
 //=======================================================================
-NCollection_CellFilter_Action BRepMesh_CircleInspector::Inspect (const Standard_Integer theTarget)
+BRepMesh_CircleTool::BRepMesh_CircleTool(
+  const Standard_Integer                  theReservedSize,
+  const Handle(NCollection_IncAllocator)& theAllocator)
+: myTolerance (Precision::PConfusion()),
+  myAllocator (theAllocator),
+  myCellFilter(10.0, theAllocator),
+  mySelector  (myTolerance, Max(theReservedSize, 64), theAllocator)
 {
-  const BRepMesh_Circ& Circ = myInitCircle(theTarget);
-  Standard_Real R = Circ.Radius();
-  if(R < 0)
-    return CellFilter_Purge;
-  Standard_Real dx,dy;
-  const gp_XY& aLoc=Circ.Location();
-  dx=myCurrent.X()-aLoc.X();
-  dy=myCurrent.Y()-aLoc.Y();
-  if ((dx*dx+dy*dy)-(R*R) <= myTol)
-    myResInd.Append(theTarget);
-  return CellFilter_Keep;
 }
 
-
 //=======================================================================
-//function : BRepMesh_CircleTool
+//function : bind
 //purpose  : 
 //=======================================================================
-BRepMesh_CircleTool::BRepMesh_CircleTool(const BRepMesh_BaseAllocator& theAlloc)
-: Tolerance(Precision::PConfusion()),
-Allocator(theAlloc),
-CellFilter(10, theAlloc),
-Selector(Tolerance,64,theAlloc)
+void BRepMesh_CircleTool::bind(const Standard_Integer theIndex,
+                               const gp_XY&           theLocation,
+                               const Standard_Real    theRadius)
 {
-  Tolerance=Tolerance*Tolerance;
+  BRepMesh_Circle aCirle(theLocation, theRadius);
+
+  //compute coords
+  Standard_Real aMaxX = Min(theLocation.X() + theRadius, myFaceMax.X());
+  Standard_Real aMinX = Max(theLocation.X() - theRadius, myFaceMin.X());
+  Standard_Real aMaxY = Min(theLocation.Y() + theRadius, myFaceMax.Y());
+  Standard_Real aMinY = Max(theLocation.Y() - theRadius, myFaceMin.Y());
+
+  gp_XY aMinPnt(aMinX, aMinY);
+  gp_XY aMaxPnt(aMaxX, aMaxY);
+
+  myCellFilter.Add(theIndex, aMinPnt, aMaxPnt);
+  mySelector.Bind(theIndex, aCirle);
 }
 
 //=======================================================================
-//function : BRepMesh_CircleTool
+//function : Bind
 //purpose  : 
 //=======================================================================
-BRepMesh_CircleTool::BRepMesh_CircleTool(const Standard_Integer nbComp,
-                                         const BRepMesh_BaseAllocator& theAlloc)
-                                         : Tolerance(Precision::PConfusion()),
-                                         Allocator(theAlloc),
-                                         CellFilter(10, theAlloc),
-                                         Selector(Tolerance,Max(nbComp,64),theAlloc)
+void BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
+                               const gp_Circ2d&       theCircle)
 {
-  Tolerance=Tolerance*Tolerance;
+  gp_XY         aCoord  = theCircle.Location().Coord();
+  Standard_Real aRadius = theCircle.Radius();
+  bind(theIndex, aCoord, aRadius);
 }
 
-
 //=======================================================================
-//function : Initialize
+//function : MakeCircle
 //purpose  : 
 //=======================================================================
-void BRepMesh_CircleTool::Initialize(const Standard_Integer /*nbComp*/)
+Standard_Boolean BRepMesh_CircleTool::MakeCircle(const gp_XY&   thePoint1,
+                                                 const gp_XY&   thePoint2,
+                                                 const gp_XY&   thePoint3,
+                                                 gp_XY&         theLocation,
+                                                 Standard_Real& theRadius)
 {
-  Tolerance=Precision::PConfusion();
-  Tolerance=Tolerance*Tolerance;
-}
+  static const Standard_Real aPrecision   = Precision::PConfusion();
+  static const Standard_Real aSqPrecision = aPrecision * aPrecision;
 
-void BRepMesh_CircleTool::SetCellSize(const Standard_Real theSize)
-{
-  CellFilter.Reset(theSize, Allocator);
-}
+  gp_XY aLink1(const_cast<gp_XY&>(thePoint3).ChangeCoord(1) - const_cast<gp_XY&>(thePoint2).ChangeCoord(1),
+               const_cast<gp_XY&>(thePoint2).ChangeCoord(2) - const_cast<gp_XY&>(thePoint3).ChangeCoord(2));
+  if (aLink1.SquareModulus() < aSqPrecision)
+    return Standard_False;
 
-void BRepMesh_CircleTool::SetCellSize(const Standard_Real theXSize, 
-                                      const Standard_Real theYSize)
-{
-  Standard_Real aCellSize[2];
-  aCellSize[0] = theXSize;
-  aCellSize[1] = theYSize;
+  gp_XY aLink2(const_cast<gp_XY&>(thePoint1).ChangeCoord(1) - const_cast<gp_XY&>(thePoint3).ChangeCoord(1),
+               const_cast<gp_XY&>(thePoint3).ChangeCoord(2) - const_cast<gp_XY&>(thePoint1).ChangeCoord(2));
+  if (aLink2.SquareModulus() < aSqPrecision)
+    return Standard_False;
 
-  CellFilter.Reset(aCellSize, Allocator);
-}
+  gp_XY aLink3(const_cast<gp_XY&>(thePoint2).ChangeCoord(1) - const_cast<gp_XY&>(thePoint1).ChangeCoord(1),
+               const_cast<gp_XY&>(thePoint1).ChangeCoord(2) - const_cast<gp_XY&>(thePoint2).ChangeCoord(2));
+  if (aLink3.SquareModulus() < aSqPrecision)
+    return Standard_False;
 
+  const Standard_Real aD = 2 * (const_cast<gp_XY&>(thePoint1).ChangeCoord(1) * aLink1.Y() +
+                                const_cast<gp_XY&>(thePoint2).ChangeCoord(1) * aLink2.Y() +
+                                const_cast<gp_XY&>(thePoint3).ChangeCoord(1) * aLink3.Y());
 
-void BRepMesh_CircleTool::SetMinMaxSize(const gp_XY& theMin,
-                                        const gp_XY& theMax)
-{
-  FaceMin = theMin;
-  FaceMax = theMax;
-}
+  if (Abs(aD) < gp::Resolution())
+    return Standard_False;
 
-//=======================================================================
-//function : Add
-//purpose  : 
-//=======================================================================
-void  BRepMesh_CircleTool::Add(const gp_Circ2d& theCirc,
-                               const Standard_Integer theIndex)
-{
-  gp_XY aCoord(theCirc.Location().Coord());
-  Standard_Real R = theCirc.Radius();
-  BRepMesh_Circ aCir(aCoord, R);
+  const Standard_Real aInvD = 1. / aD;
+  const Standard_Real aSqMod1 = thePoint1.SquareModulus();
+  const Standard_Real aSqMod2 = thePoint2.SquareModulus();
+  const Standard_Real aSqMod3 = thePoint3.SquareModulus();
+  theLocation.ChangeCoord(1) = (aSqMod1 * aLink1.Y() +
+                                aSqMod2 * aLink2.Y() +
+                                aSqMod3 * aLink3.Y()) * aInvD;
 
-  //compute coords
-  Standard_Real xMax=Min(aCoord.X()+R,FaceMax.X());
-  Standard_Real xMin=Max(aCoord.X()-R,FaceMin.X());
-  Standard_Real yMax=Min(aCoord.Y()+R,FaceMax.Y());
-  Standard_Real yMin=Max(aCoord.Y()-R,FaceMin.Y());
+  theLocation.ChangeCoord(2) = (aSqMod1 * aLink1.X() +
+                                aSqMod2 * aLink2.X() +
+                                aSqMod3 * aLink3.X()) * aInvD;
 
-  gp_XY MinPnt(xMin,yMin);
-  gp_XY MaxPnt(xMax,yMax);
+  theRadius = Sqrt(Max(Max((thePoint1 - theLocation).SquareModulus(),
+                           (thePoint2 - theLocation).SquareModulus()),
+                           (thePoint3 - theLocation).SquareModulus())) + 2 * RealEpsilon();
 
-  CellFilter.Add(theIndex, MinPnt, MaxPnt);
-  Selector.Add(theIndex, aCir);
+  return Standard_True;
 }
 
 //=======================================================================
-//function : Add
+//function : Bind
 //purpose  : 
 //=======================================================================
-Standard_Boolean BRepMesh_CircleTool::Add(const gp_XY& p1,
-                                          const gp_XY& p2,
-                                          const gp_XY& p3,
-                                          const Standard_Integer theIndex)
+Standard_Boolean BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
+                                           const gp_XY&           thePoint1,
+                                           const gp_XY&           thePoint2,
+                                           const gp_XY&           thePoint3)
 {
-  gp_XY m1((p1.X()+p2.X())/2., (p1.Y()+p2.Y())/2.);
-  gp_XY m2((p2.X()+p3.X())/2., (p2.Y()+p3.Y())/2.);
-  gp_XY m3((p3.X()+p1.X())/2., (p3.Y()+p1.Y())/2.);
-  Standard_Real dx=m1.X()-m2.X();
-  Standard_Real dy=m1.Y()-m2.Y();
-  Standard_Real d12=(dx*dx)+(dy*dy);
-  dx=m2.X()-m3.X();
-  dy=m2.Y()-m3.Y();
-  Standard_Real d23=(dx*dx)+(dy*dy);
-  dx=m3.X()-m1.X();
-  dy=m3.Y()-m1.Y();
-  Standard_Real d31=(dx*dx)+(dy*dy);
-  gp_XY pl11, pl12, pl21, pl22;
-
-  if (d12>d23 && d12>d31) {
-    dy=p2.Y()-p1.Y();
-    dx=p1.X()-p2.X();
-    if (dy!=0. || dx!=0.) {
-      pl11 = m1;
-      pl12 = gp_XY(dy, dx);
-    }
-    else return Standard_False;
-
-    dy=p3.Y()-p2.Y();
-    dx=p2.X()-p3.X();
-    if (dy!=0. || dx!=0.) {
-      pl21 = m2;
-      pl22 = gp_XY(dy, dx);
-    }
-    else return Standard_False;
-  }
-  else {
-    if (d23>d31) {
-      dy=p3.Y()-p2.Y();
-      dx=p2.X()-p3.X();
-      if (dy!=0. || dx!=0.) {
-        pl11 = m2;
-        pl12 = gp_XY(dy, dx);
-      }
-      else return Standard_False;
-
-      dy=p1.Y()-p3.Y();
-      dx=p3.X()-p1.X();
-      if (dy!=0. || dx!=0.) {
-        pl21 = m3;
-        pl22 = gp_XY(dy, dx);
-      }
-      else return Standard_False;
-    }
-    else {
-      dy=p1.Y()-p3.Y();
-      dx=p3.X()-p1.X();
-      if (dy!=0. || dx!=0.) {
-        pl11 = m3;
-        pl12 = gp_XY(dy, dx);
-      }
-      else return Standard_False;
-
-      dy=p2.Y()-p1.Y();
-      dx=p1.X()-p2.X();
-      if (dy!=0. || dx!=0.) {
-        pl21 = m1;
-        pl22 = gp_XY(dy, dx);
-      }
-      else return Standard_False;
-    }
-  }
-
-  gp_XY aVecO1O2 = pl21 - pl11;
-  Standard_Real aCrossD1D2 = pl12 ^ pl22;
-  Standard_Real theSinAngle = Abs(aCrossD1D2);
-  if (theSinAngle < gp::Resolution())
+  gp_XY aLocation;
+  Standard_Real aRadius;
+  if (!MakeCircle(thePoint1, thePoint2, thePoint3, aLocation, aRadius))
     return Standard_False;
-  Standard_Real theParam1 = (aVecO1O2 ^ pl22) / aCrossD1D2;
-  gp_XY pInt = pl11+pl12*theParam1;
-  dx=p1.X()-pInt.X();
-  dy=p1.Y()-pInt.Y();
-  Standard_Real R = Sqrt(dx*dx+dy*dy);
-  BRepMesh_Circ aCir(pInt, R);
-
-  //compute coords
-  Standard_Real xMax=Min(pInt.X()+R,FaceMax.X());
-  Standard_Real xMin=Max(pInt.X()-R,FaceMin.X());
-  Standard_Real yMax=Min(pInt.Y()+R,FaceMax.Y());
-  Standard_Real yMin=Max(pInt.Y()-R,FaceMin.Y());
 
-  gp_XY MinPnt(xMin,yMin);
-  gp_XY MaxPnt(xMax,yMax);    
-
-  CellFilter.Add(theIndex, MinPnt, MaxPnt);
-
-  Selector.Add(theIndex, aCir);
+  bind(theIndex, aLocation, aRadius);
   return Standard_True;
 }
 
@@ -256,29 +159,30 @@ Standard_Boolean BRepMesh_CircleTool::Add(const gp_XY& p1,
 //function : Delete
 //purpose  : 
 //=======================================================================
-void  BRepMesh_CircleTool::Delete(const Standard_Integer theIndex)
+void BRepMesh_CircleTool::Delete(const Standard_Integer theIndex)
 {
-  BRepMesh_Circ& Circ = Selector.GetCirc(theIndex);
-  if(Circ.Radius() > 0.) {
-    Circ.SetRadius(-1);
-  }
+  BRepMesh_Circle& aCircle = mySelector.Circle(theIndex);
+  if(aCircle.Radius() > 0.)
+    aCircle.SetRadius(-1);
 }
 
 //=======================================================================
 //function : Select
 //purpose  : 
 //=======================================================================
-BRepMesh_ListOfInteger&  BRepMesh_CircleTool::Select(const gp_XY& thePnt)
+IMeshData::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint)
 {
-  Selector.ClerResList();
-  Selector.SetCurrent(thePnt);
-  CellFilter.Inspect (thePnt, Selector);
-  return Selector.GetCoincidentInd();
+  mySelector.SetPoint(thePoint);
+  myCellFilter.Inspect(thePoint, mySelector);
+  return mySelector.GetShotCircles();
 }
 
-void BRepMesh_CircleTool::MocAdd(const Standard_Integer theIndex)
+//=======================================================================
+//function : MocBind
+//purpose  : 
+//=======================================================================
+void BRepMesh_CircleTool::MocBind(const Standard_Integer theIndex)
 {
-  gp_XY nullPnt(0.,0.);
-  BRepMesh_Circ theNullCir(nullPnt, -1.);
-  Selector.Add(theIndex, theNullCir);
+  BRepMesh_Circle aNullCir(gp::Origin2d().Coord(), -1.);
+  mySelector.Bind(theIndex, aNullCir);
 }