// 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;
}
//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);
}