mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-12-26 09:20:35 +05:00
Rewrite local function ModifySurface of BlockFix_SphereSpaceModifier
This commit is contained in:
parent
8d33dd3a86
commit
d6f16273ad
@ -38,13 +38,17 @@
|
|||||||
#include <TopoDS_Edge.hxx>
|
#include <TopoDS_Edge.hxx>
|
||||||
#include <TopoDS_Face.hxx>
|
#include <TopoDS_Face.hxx>
|
||||||
#include <TopoDS_Vertex.hxx>
|
#include <TopoDS_Vertex.hxx>
|
||||||
|
#include <TopoDS_Iterator.hxx>
|
||||||
|
|
||||||
#include <BRep_Tool.hxx>
|
#include <BRep_Tool.hxx>
|
||||||
#include <BRep_Builder.hxx>
|
#include <BRep_Builder.hxx>
|
||||||
|
#include <BRepTools.hxx>
|
||||||
|
#include <BRepAdaptor_Curve2d.hxx>
|
||||||
|
#include <BRepTopAdaptor_FClass2d.hxx>
|
||||||
|
|
||||||
#include <BRepGProp.hxx>
|
#include <ElSLib.hxx>
|
||||||
#include <GProp_GProps.hxx>
|
#include <Geom_Circle.hxx>
|
||||||
|
#include <Geom_TrimmedCurve.hxx>
|
||||||
#include <Geom_SphericalSurface.hxx>
|
#include <Geom_SphericalSurface.hxx>
|
||||||
#include <Geom_RectangularTrimmedSurface.hxx>
|
#include <Geom_RectangularTrimmedSurface.hxx>
|
||||||
|
|
||||||
@ -87,64 +91,145 @@ void BlockFix_SphereSpaceModifier::SetTolerance(const Standard_Real Tol)
|
|||||||
//function : NewSurface
|
//function : NewSurface
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
static Standard_Boolean ModifySurface(const TopoDS_Face& aFace,
|
static Standard_Boolean ModifySurface(const TopoDS_Face& theFace,
|
||||||
const Handle(Geom_Surface)& aSurface,
|
const Handle(Geom_Surface)& theSurface,
|
||||||
Handle(Geom_Surface)& aNewSurface)
|
Handle(Geom_Surface)& theNewSurface)
|
||||||
{
|
{
|
||||||
Handle(Geom_Surface) S = aSurface;
|
TopoDS_Face aFace = theFace;
|
||||||
if(S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
|
aFace.Orientation (TopAbs_FORWARD);
|
||||||
|
|
||||||
|
Handle(Geom_Surface) aNewSurface;
|
||||||
|
|
||||||
|
Handle(Geom_Surface) aSurf = theSurface;
|
||||||
|
if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
|
||||||
Handle(Geom_RectangularTrimmedSurface) RTS =
|
Handle(Geom_RectangularTrimmedSurface) RTS =
|
||||||
Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
|
Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf);
|
||||||
S = RTS->BasisSurface();
|
aSurf = RTS->BasisSurface();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
|
if (aSurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
|
||||||
Standard_Real Umin, Umax, Vmin, Vmax;
|
Standard_Real Umin, Umax, Vmin, Vmax;
|
||||||
ShapeAnalysis::GetFaceUVBounds(aFace,Umin, Umax, Vmin, Vmax);
|
ShapeAnalysis::GetFaceUVBounds (aFace, Umin, Umax, Vmin, Vmax);
|
||||||
Standard_Real PI2 = M_PI/2.;
|
Standard_Real PI2 = M_PI/2.;
|
||||||
if(Vmax > PI2 - Precision::PConfusion() || Vmin < -PI2+::Precision::PConfusion()) {
|
Handle(Geom_SphericalSurface) aSphere = Handle(Geom_SphericalSurface)::DownCast(aSurf);
|
||||||
Handle(Geom_SphericalSurface) aSphere = Handle(Geom_SphericalSurface)::DownCast(S);
|
|
||||||
gp_Sphere sp = aSphere->Sphere();
|
gp_Sphere sp = aSphere->Sphere();
|
||||||
//modified by jgv, 12.11.2012 for issue 21777//
|
|
||||||
Standard_Real Radius = sp.Radius();
|
Standard_Real Radius = sp.Radius();
|
||||||
Standard_Real HalfArea = 2.*M_PI*Radius*Radius;
|
|
||||||
GProp_GProps Properties;
|
|
||||||
BRepGProp::SurfaceProperties(aFace, Properties);
|
|
||||||
Standard_Real anArea = Properties.Mass();
|
|
||||||
Standard_Real AreaTol = Radius*Radius*1.e-6;
|
|
||||||
if (anArea > HalfArea - AreaTol) //no chance to avoid singularity
|
|
||||||
return Standard_False;
|
|
||||||
///////////////////////////////////////////////
|
|
||||||
gp_Ax3 ax3 = sp.Position();
|
gp_Ax3 ax3 = sp.Position();
|
||||||
if(Abs(Vmax-Vmin) < PI2) {
|
gp_Pnt aCentre = sp.Location();
|
||||||
gp_Ax3 axnew3(ax3.Axis().Location(), ax3.Direction()^ax3.XDirection(),ax3.XDirection());
|
|
||||||
sp.SetPosition(axnew3);
|
TopoDS_Wire aWire = BRepTools::OuterWire (aFace);
|
||||||
Handle(Geom_SphericalSurface) aNewSphere = new Geom_SphericalSurface(sp);
|
BRepTopAdaptor_FClass2d aClassifier (aFace, Precision::PConfusion());
|
||||||
aNewSurface = aNewSphere;
|
TopTools_MapOfShape aEmap;
|
||||||
return Standard_True;
|
const Standard_Real anOffsetValue = 0.01*M_PI;
|
||||||
|
for (Standard_Integer ii = 1; ii <= 2; ii++)
|
||||||
|
{
|
||||||
|
TopoDS_Iterator itw (aWire);
|
||||||
|
for (; itw.More(); itw.Next())
|
||||||
|
{
|
||||||
|
const TopoDS_Edge& anEdge = TopoDS::Edge (itw.Value());
|
||||||
|
if (aEmap.Contains (anEdge) ||
|
||||||
|
anEdge.Orientation() == TopAbs_INTERNAL ||
|
||||||
|
anEdge.Orientation() == TopAbs_EXTERNAL ||
|
||||||
|
BRep_Tool::Degenerated (anEdge) ||
|
||||||
|
BRepTools::IsReallyClosed (anEdge, aFace))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BRepAdaptor_Curve2d aBAcurve2d (anEdge, aFace);
|
||||||
|
GeomAbs_CurveType aType = aBAcurve2d.GetType();
|
||||||
|
if (ii == 1 && aType == GeomAbs_Line) //first pass: consider only curvilinear edges
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Standard_Real aMidPar = (aBAcurve2d.FirstParameter() + aBAcurve2d.LastParameter())/2;
|
||||||
|
gp_Pnt2d aMidP2d;
|
||||||
|
gp_Vec2d aTangent;
|
||||||
|
aBAcurve2d.D1 (aMidPar, aMidP2d, aTangent);
|
||||||
|
if (anEdge.Orientation() == TopAbs_REVERSED)
|
||||||
|
aTangent.Reverse();
|
||||||
|
|
||||||
|
aTangent.Normalize();
|
||||||
|
gp_Vec2d aNormal (aTangent.Y(), -aTangent.X());
|
||||||
|
aNormal *= anOffsetValue;
|
||||||
|
gp_Pnt2d anUpperPole = aMidP2d.Translated (aNormal);
|
||||||
|
if (anUpperPole.Y() < -PI2 || anUpperPole.Y() > PI2)
|
||||||
|
{
|
||||||
|
aEmap.Add(anEdge);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
if (anUpperPole.X() < 0.)
|
||||||
gp_Pnt PC = ax3.Location();
|
anUpperPole.SetX (anUpperPole.X() + 2.*M_PI);
|
||||||
Standard_Real Vpar;
|
else if (anUpperPole.X() > 2.*M_PI)
|
||||||
if(fabs(PI2-Vmax)>fabs(-PI2-Vmin))
|
anUpperPole.SetX (anUpperPole.X() - 2.*M_PI);
|
||||||
Vpar = (PI2+Vmax)/2.;
|
|
||||||
else
|
TopAbs_State aStatus = aClassifier.Perform (anUpperPole);
|
||||||
Vpar = (-PI2+Vmin)/2.;
|
if (aStatus != TopAbs_OUT)
|
||||||
Standard_Real Upar = (Umin+Umax)/2.;;
|
{
|
||||||
gp_Pnt PN,PX;
|
aEmap.Add(anEdge);
|
||||||
S->D0(Upar,Vpar,PN);
|
continue;
|
||||||
S->D0(Upar+PI2,0.,PX);
|
}
|
||||||
gp_Dir newNorm(gp_Vec(PC,PN));
|
|
||||||
gp_Dir newDirX(gp_Vec(PC,PX));
|
gp_Pnt anUpperPole3d = aSphere->Value (anUpperPole.X(), anUpperPole.Y());
|
||||||
gp_Ax3 axnew3(ax3.Axis().Location(), newNorm, newDirX);
|
gp_Vec aVec (aCentre, anUpperPole3d);
|
||||||
sp.SetPosition(axnew3);
|
aVec.Reverse();
|
||||||
Handle(Geom_SphericalSurface) aNewSphere = new Geom_SphericalSurface(sp);
|
gp_Pnt aLowerPole3d = aCentre.Translated (aVec);
|
||||||
aNewSurface = aNewSphere;
|
Standard_Real aU, aV;
|
||||||
return Standard_True;
|
ElSLib::Parameters (sp, aLowerPole3d, aU, aV);
|
||||||
|
gp_Pnt2d aLowerPole (aU, aV);
|
||||||
|
aStatus = aClassifier.Perform (aLowerPole);
|
||||||
|
if (aStatus != TopAbs_OUT)
|
||||||
|
{
|
||||||
|
aEmap.Add(anEdge);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Build a meridian
|
||||||
|
gp_Vec anUp (aCentre, anUpperPole3d);
|
||||||
|
anUp.Normalize();
|
||||||
|
gp_Pnt aMidPnt = aSphere->Value (aMidP2d.X(), aMidP2d.Y());
|
||||||
|
gp_Vec aMidOnEdge (aCentre, aMidPnt);
|
||||||
|
aMidOnEdge.Normalize();
|
||||||
|
gp_Vec AxisOfCircle = anUp ^ aMidOnEdge;
|
||||||
|
gp_Vec XDirOfCircle = anUp ^ AxisOfCircle;
|
||||||
|
gp_Ax2 anAxis (aCentre, AxisOfCircle, XDirOfCircle);
|
||||||
|
Handle(Geom_Circle) aCircle = new Geom_Circle (anAxis, Radius);
|
||||||
|
Handle(Geom_TrimmedCurve) aMeridian = new Geom_TrimmedCurve (aCircle, -PI2, PI2);
|
||||||
|
|
||||||
|
//Check the meridian
|
||||||
|
Standard_Boolean IsInnerPointFound = Standard_False;
|
||||||
|
Standard_Integer NbSamples = 10;
|
||||||
|
Standard_Real aDelta = M_PI / NbSamples;
|
||||||
|
for (Standard_Integer jj = 1; jj < NbSamples; jj++)
|
||||||
|
{
|
||||||
|
Standard_Real aParam = -PI2 + jj*aDelta;
|
||||||
|
gp_Pnt aPnt = aMeridian->Value (aParam);
|
||||||
|
ElSLib::Parameters (sp, aPnt, aU, aV);
|
||||||
|
gp_Pnt2d aP2d (aU, aV);
|
||||||
|
aStatus = aClassifier.Perform (aP2d);
|
||||||
|
if (aStatus != TopAbs_OUT)
|
||||||
|
{
|
||||||
|
IsInnerPointFound = Standard_True;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (IsInnerPointFound)
|
||||||
|
{
|
||||||
|
aEmap.Add(anEdge);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gp_Ax3 anAxisOfNewSphere (aCentre, anUp, XDirOfCircle);
|
||||||
|
aNewSurface = new Geom_SphericalSurface (anAxisOfNewSphere, Radius);
|
||||||
|
break;
|
||||||
|
} //for (; itw.More(); itw.Next()) (iteration on outer wire)
|
||||||
|
if (!aNewSurface.IsNull())
|
||||||
|
break;
|
||||||
|
} //for (Standard_Integer ii = 1; ii <= 2; ii++) (two passes)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aNewSurface.IsNull())
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
|
|
||||||
|
theNewSurface = aNewSurface;
|
||||||
|
return Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
Standard_Boolean BlockFix_SphereSpaceModifier::NewSurface(const TopoDS_Face& F,
|
Standard_Boolean BlockFix_SphereSpaceModifier::NewSurface(const TopoDS_Face& F,
|
||||||
|
Loading…
Reference in New Issue
Block a user