mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-02 17:46:22 +03:00
The following classes have been removed as obsolete: - BRepAlgo_BooleanOperation - BRepAlgo_Fuse - BRepAlgo_Cut - BRepAlgo_Common - BRepAlgo_Section The corresponding classes from BRepAlgoAPI package have to be used instead. Draw commands: - fuse - cut - common - section/psection have also been removed as obsolete. The corresponding commands for modern Boolean operations algorithm (bfuse/bcut/bcommon/bsection) have to be used instead. Adjustment of the test cases to use the commands for modern algorithm.
4202 lines
130 KiB
C++
4202 lines
130 KiB
C++
// Created on: 1995-10-23
|
|
// Created by: Yves FRICAUD
|
|
// Copyright (c) 1995-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// 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.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <BRepOffset_Tool.hxx>
|
|
|
|
#include <Bnd_Box2d.hxx>
|
|
#include <BndLib_Add3dCurve.hxx>
|
|
#include <BOPAlgo_PaveFiller.hxx>
|
|
#include <BOPDS_DS.hxx>
|
|
#include <BOPTools_AlgoTools.hxx>
|
|
#include <BOPTools_AlgoTools2D.hxx>
|
|
#include <BRep_CurveRepresentation.hxx>
|
|
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
|
|
#include <BRep_TEdge.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRepAdaptor_Curve.hxx>
|
|
#include <BRepAdaptor_Curve2d.hxx>
|
|
#include <BRepAdaptor_Surface.hxx>
|
|
#include <BRepAlgo_AsDes.hxx>
|
|
#include <BRepAlgo_Image.hxx>
|
|
#include <BRepBndLib.hxx>
|
|
#include <BRepLib.hxx>
|
|
#include <BRepLib_MakeEdge.hxx>
|
|
#include <BRepLib_MakeFace.hxx>
|
|
#include <BRepLib_MakePolygon.hxx>
|
|
#include <BRepLib_MakeVertex.hxx>
|
|
#include <BRepOffset_Analyse.hxx>
|
|
#include <BRepOffset_Interval.hxx>
|
|
#include <BRepOffset_ListOfInterval.hxx>
|
|
#include <BRepTools.hxx>
|
|
#include <BRepTools_Modifier.hxx>
|
|
#include <BRepTools_TrsfModification.hxx>
|
|
#include <BRepTools_WireExplorer.hxx>
|
|
#include <BRepTopAdaptor_FClass2d.hxx>
|
|
#include <ElCLib.hxx>
|
|
#include <ElSLib.hxx>
|
|
#include <Extrema_ExtPC.hxx>
|
|
#include <Extrema_ExtPC2d.hxx>
|
|
#include <BRepExtrema_DistShapeShape.hxx>
|
|
#include <GCPnts_AbscissaPoint.hxx>
|
|
#include <GCPnts_QuasiUniformDeflection.hxx>
|
|
#include <GCPnts_UniformAbscissa.hxx>
|
|
#include <Geom2d_BezierCurve.hxx>
|
|
#include <Geom2d_BSplineCurve.hxx>
|
|
#include <Geom2d_Circle.hxx>
|
|
#include <Geom2d_Curve.hxx>
|
|
#include <Geom2d_Ellipse.hxx>
|
|
#include <Geom2d_Hyperbola.hxx>
|
|
#include <Geom2d_Line.hxx>
|
|
#include <Geom2d_Parabola.hxx>
|
|
#include <Geom2d_TrimmedCurve.hxx>
|
|
#include <Geom2dAdaptor_Curve.hxx>
|
|
#include <Geom2dConvert_ApproxCurve.hxx>
|
|
#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
|
|
#include <Geom2dInt_GInter.hxx>
|
|
#include <Geom_BezierSurface.hxx>
|
|
#include <Geom_BSplineCurve.hxx>
|
|
#include <Geom_BSplineSurface.hxx>
|
|
#include <Geom_Conic.hxx>
|
|
#include <Geom_ConicalSurface.hxx>
|
|
#include <Geom_Curve.hxx>
|
|
#include <Geom_Line.hxx>
|
|
#include <Geom_OffsetSurface.hxx>
|
|
#include <Geom_Plane.hxx>
|
|
#include <Geom_RectangularTrimmedSurface.hxx>
|
|
#include <Geom_Surface.hxx>
|
|
#include <Geom_SurfaceOfLinearExtrusion.hxx>
|
|
#include <Geom_SurfaceOfRevolution.hxx>
|
|
#include <Geom_TrimmedCurve.hxx>
|
|
#include <GeomAdaptor_Surface.hxx>
|
|
#include <GeomAPI.hxx>
|
|
#include <GeomAPI_ExtremaCurveCurve.hxx>
|
|
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
|
#include <GeomConvert_ApproxCurve.hxx>
|
|
#include <GeomConvert_CompCurveToBSplineCurve.hxx>
|
|
#include <GeomInt_IntSS.hxx>
|
|
#include <GeomLib.hxx>
|
|
#include <GeomProjLib.hxx>
|
|
#include <gp.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Vec.hxx>
|
|
#include <IntRes2d_IntersectionPoint.hxx>
|
|
#include <IntRes2d_IntersectionSegment.hxx>
|
|
#include <IntTools_FaceFace.hxx>
|
|
#include <Precision.hxx>
|
|
#include <ProjLib_HProjectedCurve.hxx>
|
|
#include <ProjLib_ProjectedCurve.hxx>
|
|
#include <ShapeCustom_Curve2d.hxx>
|
|
#include <Standard_ConstructionError.hxx>
|
|
#include <TColgp_Array1OfPnt2d.hxx>
|
|
#include <TopAbs.hxx>
|
|
#include <TopExp.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Compound.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Iterator.hxx>
|
|
#include <TopoDS_Shape.hxx>
|
|
#include <TopoDS_Vertex.hxx>
|
|
#include <TopoDS_Wire.hxx>
|
|
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
|
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
|
#include <TopTools_SequenceOfShape.hxx>
|
|
|
|
#include <stdio.h>
|
|
|
|
// The constant defines the maximal value to enlarge surfaces.
|
|
// It is limited to 1.e+7. This limitation is justified by the
|
|
// floating point format. As we can have only 15
|
|
// valuable decimal numbers, then during intersection of surfaces with
|
|
// bounds of 1.e+8 the possible inaccuracy might appear already in seventh
|
|
// decimal place which will be more than Precision::Confusion value -
|
|
// 1.e-7, default tolerance value for the section curves.
|
|
// By decreasing the max enlarge value to 1.e+7 the inaccuracy will be
|
|
// shifted to eighth decimal place, i.e. the inaccuracy will be
|
|
// decreased to values less than 1.e-7.
|
|
const Standard_Real TheInfini = 1.e+7;
|
|
|
|
//tma: for new boolean operation
|
|
#ifdef DRAW
|
|
#include <DBRep.hxx>
|
|
#include <Geom2d_Conic.hxx>
|
|
#include <Geom_BoundedCurve.hxx>
|
|
Standard_Boolean AffichInter = Standard_False;
|
|
static Standard_Integer NbNewEdges = 1;
|
|
static Standard_Integer NbFaces = 1;
|
|
static Standard_Integer NbFOB = 1;
|
|
static Standard_Integer NbFTE = 1;
|
|
static Standard_Integer NbExtE = 1;
|
|
#endif
|
|
|
|
#ifdef OCCT_DEBUG
|
|
static Standard_Boolean AffichExtent = Standard_False;
|
|
#endif
|
|
|
|
static
|
|
void PerformPlanes(const TopoDS_Face& theFace1,
|
|
const TopoDS_Face& theFace2,
|
|
const TopAbs_State theState,
|
|
TopTools_ListOfShape& theL1,
|
|
TopTools_ListOfShape& theL2);
|
|
|
|
static void UpdateVertexTolerances(const TopoDS_Face& theFace);
|
|
|
|
inline
|
|
Standard_Boolean IsInf(const Standard_Real theVal);
|
|
|
|
//=======================================================================
|
|
//function : EdgeVertices
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
|
|
TopoDS_Vertex& V1,
|
|
TopoDS_Vertex& V2)
|
|
{
|
|
if (E.Orientation() == TopAbs_REVERSED) {
|
|
TopExp::Vertices(E,V2,V1);
|
|
}
|
|
else {
|
|
TopExp::Vertices(E,V1,V2);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FindPeriod
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static void FindPeriod (const TopoDS_Face& F,
|
|
Standard_Real& umin,
|
|
Standard_Real& umax,
|
|
Standard_Real& vmin,
|
|
Standard_Real& vmax)
|
|
{
|
|
|
|
Bnd_Box2d B;
|
|
TopExp_Explorer exp;
|
|
for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
|
|
const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
|
|
|
|
Standard_Real pf,pl;
|
|
const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
|
|
if (C.IsNull()) return;
|
|
Geom2dAdaptor_Curve PC(C,pf,pl);
|
|
Standard_Real i, nbp = 20;
|
|
if (PC.GetType() == GeomAbs_Line) nbp = 2;
|
|
Standard_Real step = (pl - pf) / nbp;
|
|
gp_Pnt2d P;
|
|
PC.D0(pf,P);
|
|
B.Add(P);
|
|
for (i = 2; i < nbp; i++) {
|
|
pf += step;
|
|
PC.D0(pf,P);
|
|
B.Add(P);
|
|
}
|
|
PC.D0(pl,P);
|
|
B.Add(P);
|
|
B.Get(umin,vmin,umax,vmax);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : PutInBounds
|
|
//purpose : Recadre la courbe 2d dans les bounds de la face
|
|
//=======================================================================
|
|
|
|
static void PutInBounds (const TopoDS_Face& F,
|
|
const TopoDS_Edge& E,
|
|
Handle(Geom2d_Curve)& C2d)
|
|
{
|
|
Standard_Real umin,umax,vmin,vmax;
|
|
Standard_Real f,l;
|
|
BRep_Tool::Range(E,f,l);
|
|
|
|
TopLoc_Location L; // Recup S avec la location pour eviter la copie.
|
|
Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
|
|
|
|
if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
|
|
S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
|
|
}
|
|
//---------------
|
|
// Recadre en U.
|
|
//---------------
|
|
if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
|
|
|
|
FindPeriod (F,umin,umax,vmin,vmax);
|
|
|
|
if (S->IsUPeriodic()) {
|
|
Standard_Real period = S->UPeriod();
|
|
Standard_Real eps = period*1.e-6;
|
|
gp_Pnt2d Pf = C2d->Value(f);
|
|
gp_Pnt2d Pl = C2d->Value(l);
|
|
gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
|
|
Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
|
|
Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
|
|
Standard_Real du = 0.;
|
|
if (minC< umin - eps) {
|
|
du = (int((umin - minC)/period) + 1)*period;
|
|
}
|
|
if (minC > umax + eps) {
|
|
du = -(int((minC - umax)/period) + 1)*period;
|
|
}
|
|
if (du != 0) {
|
|
gp_Vec2d T1(du,0.);
|
|
C2d->Translate(T1);
|
|
minC += du; maxC += du;
|
|
}
|
|
// Ajuste au mieux la courbe dans le domaine.
|
|
if (maxC > umax +100*eps) {
|
|
Standard_Real d1 = maxC - umax;
|
|
Standard_Real d2 = umin - minC + period;
|
|
if (d2 < d1) du =-period;
|
|
if ( du != 0.) {
|
|
gp_Vec2d T2(du,0.);
|
|
C2d->Translate(T2);
|
|
}
|
|
}
|
|
}
|
|
//------------------
|
|
// Recadre en V.
|
|
//------------------
|
|
if (S->IsVPeriodic()) {
|
|
Standard_Real period = S->VPeriod();
|
|
Standard_Real eps = period*1.e-6;
|
|
gp_Pnt2d Pf = C2d->Value(f);
|
|
gp_Pnt2d Pl = C2d->Value(l);
|
|
gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
|
|
Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
|
|
Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
|
|
Standard_Real dv = 0.;
|
|
if (minC< vmin - eps) {
|
|
dv = (int((vmin - minC)/period) + 1)*period;
|
|
}
|
|
if (minC > vmax + eps) {
|
|
dv = -(int((minC - vmax)/period) + 1)*period;
|
|
}
|
|
if (dv != 0) {
|
|
gp_Vec2d T1(0.,dv);
|
|
C2d->Translate(T1);
|
|
minC += dv; maxC += dv;
|
|
}
|
|
// Ajuste au mieux la courbe dans le domaine.
|
|
if (maxC > vmax +100*eps) {
|
|
Standard_Real d1 = maxC - vmax;
|
|
Standard_Real d2 = vmin - minC + period;
|
|
if (d2 < d1) dv =-period;
|
|
if ( dv != 0.) {
|
|
gp_Vec2d T2(0.,dv);
|
|
C2d->Translate(T2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Gabarit
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
|
|
{
|
|
GeomAdaptor_Curve GC( aCurve );
|
|
Bnd_Box aBox;
|
|
BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
|
|
Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
|
|
aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
|
|
dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
|
|
dist = Max( dist, (aZmax-aZmin) );
|
|
return dist;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : BuildPCurves
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static void BuildPCurves (const TopoDS_Edge& E,
|
|
const TopoDS_Face& F)
|
|
{
|
|
Standard_Real ff,ll;
|
|
Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
|
|
if (!C2d.IsNull()) return;
|
|
|
|
//Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
|
|
Standard_Real Tolerance = Precision::Confusion();
|
|
|
|
BRepAdaptor_Surface AS(F,0);
|
|
BRepAdaptor_Curve AC(E);
|
|
|
|
//Try to find pcurve on a bound of BSpline or Bezier surface
|
|
Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
|
|
Handle( Standard_Type ) typS = theSurf->DynamicType();
|
|
if (typS == STANDARD_TYPE(Geom_OffsetSurface))
|
|
typS = Handle(Geom_OffsetSurface)::DownCast (theSurf)->BasisSurface()->DynamicType();
|
|
if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
|
|
{
|
|
gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
|
|
gp_Pnt lpoint = AC.Value( AC.LastParameter() );
|
|
TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
|
|
Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
|
|
TopoDS_Edge theEdge;
|
|
TopExp_Explorer Explo;
|
|
Explo.Init( theFace, TopAbs_EDGE );
|
|
for (; Explo.More(); Explo.Next())
|
|
{
|
|
TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
|
|
BRepAdaptor_Curve aCurve( anEdge );
|
|
Extrema_ExtPC fextr( fpoint, aCurve );
|
|
if (!fextr.IsDone() || fextr.NbExt() < 1)
|
|
continue;
|
|
Standard_Real dist2, dist2min = RealLast();
|
|
Standard_Integer i;
|
|
for (i = 1; i <= fextr.NbExt(); i++)
|
|
{
|
|
dist2 = fextr.SquareDistance(i);
|
|
if (dist2 < dist2min)
|
|
{
|
|
dist2min = dist2;
|
|
U1 = fextr.Point(i).Parameter();
|
|
}
|
|
}
|
|
if (dist2min > TolProj * TolProj)
|
|
continue;
|
|
Extrema_ExtPC lextr( lpoint, aCurve );
|
|
if (!lextr.IsDone() || lextr.NbExt() <1)
|
|
continue;
|
|
dist2min = RealLast();
|
|
for (i = 1; i <= lextr.NbExt(); i++)
|
|
{
|
|
dist2 = lextr.SquareDistance(i);
|
|
if (dist2 < dist2min)
|
|
{
|
|
dist2min = dist2;
|
|
U2 = lextr.Point(i).Parameter();
|
|
}
|
|
}
|
|
if (dist2min <= TolProj * TolProj)
|
|
{
|
|
theEdge = anEdge;
|
|
break;
|
|
}
|
|
} // for (; Explo.More(); Explo.Current())
|
|
|
|
if (! theEdge.IsNull())
|
|
{
|
|
//Construction of pcurve
|
|
if (U2 < U1)
|
|
{
|
|
Standard_Real temp = U1;
|
|
U1 = U2;
|
|
U2 = temp;
|
|
}
|
|
Standard_Real f, l;
|
|
C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
|
|
C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
|
|
|
|
if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
|
|
PutInBounds( F, E, C2d );
|
|
|
|
BRep_Builder B;
|
|
B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
|
|
BRepLib::SameRange( E );
|
|
|
|
return;
|
|
}
|
|
} // if (typS == ...
|
|
|
|
Handle(BRepAdaptor_Surface) HS = new BRepAdaptor_Surface(AS);
|
|
Handle(BRepAdaptor_Curve) HC = new BRepAdaptor_Curve(AC);
|
|
|
|
ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
|
|
|
|
switch ( Proj.GetType()) {
|
|
|
|
case GeomAbs_Line:
|
|
C2d = new Geom2d_Line(Proj.Line());
|
|
break;
|
|
|
|
case GeomAbs_Circle:
|
|
C2d = new Geom2d_Circle(Proj.Circle());
|
|
break;
|
|
|
|
case GeomAbs_Ellipse:
|
|
C2d = new Geom2d_Ellipse(Proj.Ellipse());
|
|
break;
|
|
|
|
case GeomAbs_Parabola:
|
|
C2d = new Geom2d_Parabola(Proj.Parabola());
|
|
break;
|
|
|
|
case GeomAbs_Hyperbola:
|
|
C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
|
|
break;
|
|
|
|
case GeomAbs_BezierCurve:
|
|
C2d = Proj.Bezier();
|
|
break;
|
|
|
|
case GeomAbs_BSplineCurve:
|
|
C2d = Proj.BSpline();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
|
|
PutInBounds(F,E,C2d);
|
|
}
|
|
if (!C2d.IsNull()) {
|
|
BRep_Builder B;
|
|
B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
|
|
}
|
|
else {
|
|
throw Standard_ConstructionError("BRepOffset_Tool::BuildPCurves");
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : OriSect
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
|
|
const TopoDS_Face& F1,
|
|
const TopoDS_Face& F2,
|
|
TopAbs_Orientation& O1,
|
|
TopAbs_Orientation& O2)
|
|
{
|
|
TopLoc_Location L;
|
|
Standard_Real f,l;
|
|
|
|
|
|
Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
|
|
Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
|
|
Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
|
|
Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
|
|
Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
|
|
|
|
BRepAdaptor_Curve BAcurve( E );
|
|
|
|
GCPnts_AbscissaPoint AP(BAcurve,GCPnts_AbscissaPoint::Length(BAcurve)/2.0,f);
|
|
Standard_Real ParOnC;
|
|
|
|
if(AP.IsDone())
|
|
ParOnC = AP.Parameter();
|
|
else
|
|
ParOnC = BOPTools_AlgoTools2D::IntermediatePoint(f, l);
|
|
|
|
gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
|
|
if (T1.SquareMagnitude() > gp::Resolution()) {
|
|
T1.Normalize();
|
|
}
|
|
|
|
gp_Pnt2d P = C1->Value(ParOnC);
|
|
gp_Pnt P3;
|
|
gp_Vec D1U,D1V;
|
|
|
|
S1->D1(P.X(),P.Y(),P3,D1U,D1V);
|
|
gp_Vec DN1(D1U^D1V);
|
|
if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
|
|
|
|
P = C2->Value(ParOnC);
|
|
S2->D1(P.X(),P.Y(),P3,D1U,D1V);
|
|
gp_Vec DN2(D1U^D1V);
|
|
if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
|
|
|
|
gp_Vec ProVec = DN2^T1;
|
|
Standard_Real Prod = DN1.Dot(ProVec);
|
|
if (Prod < 0.0) {
|
|
O1 = TopAbs_FORWARD;
|
|
}
|
|
else {
|
|
O1 = TopAbs_REVERSED;
|
|
}
|
|
ProVec = DN1^T1;
|
|
Prod = DN2.Dot(ProVec);
|
|
if (Prod < 0.0) {
|
|
O2 = TopAbs_FORWARD;
|
|
}
|
|
else {
|
|
O2 = TopAbs_REVERSED;
|
|
}
|
|
if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
|
|
if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FindCommonShapes
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Face& theF1,
|
|
const TopoDS_Face& theF2,
|
|
TopTools_ListOfShape& theLE,
|
|
TopTools_ListOfShape& theLV)
|
|
{
|
|
Standard_Boolean bFoundEdges =
|
|
FindCommonShapes(theF1, theF2, TopAbs_EDGE, theLE);
|
|
Standard_Boolean bFoundVerts =
|
|
FindCommonShapes(theF1, theF2, TopAbs_VERTEX, theLV);
|
|
return bFoundEdges || bFoundVerts;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FindCommonShapes
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Shape& theS1,
|
|
const TopoDS_Shape& theS2,
|
|
const TopAbs_ShapeEnum theType,
|
|
TopTools_ListOfShape& theLSC)
|
|
{
|
|
theLSC.Clear();
|
|
//
|
|
TopTools_MapOfShape aMS;
|
|
TopExp_Explorer aExp(theS1, theType);
|
|
for (; aExp.More(); aExp.Next()) {
|
|
aMS.Add(aExp.Current());
|
|
}
|
|
//
|
|
if (aMS.IsEmpty()) {
|
|
return Standard_False;
|
|
}
|
|
//
|
|
TopTools_MapOfShape aMFence;
|
|
aExp.Init(theS2, theType);
|
|
for (; aExp.More(); aExp.Next()) {
|
|
const TopoDS_Shape& aS2 = aExp.Current();
|
|
if (aMS.Contains(aS2)) {
|
|
if (aMFence.Add(aS2)) {
|
|
theLSC.Append(aS2);
|
|
}
|
|
}
|
|
}
|
|
//
|
|
return !theLSC.IsEmpty();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ToSmall
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
|
|
{
|
|
Standard_Real Tol = 10*Precision::Confusion();
|
|
Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
|
|
gp_Pnt P1 = C->Value(C->FirstParameter());
|
|
gp_Pnt P2 = C->Value(C->LastParameter());
|
|
gp_Pnt P3 = C->Value(m);
|
|
if (P1.Distance(P2) > Tol) return Standard_False;
|
|
if (P2.Distance(P3) > Tol) return Standard_False;
|
|
return Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsOnSurface
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
|
|
const Handle(Geom_Surface)& S,
|
|
Standard_Real TolConf,
|
|
Standard_Real& TolReached)
|
|
{
|
|
Standard_Real f = C->FirstParameter();
|
|
Standard_Real l = C->LastParameter();
|
|
Standard_Integer n = 5;
|
|
Standard_Real du = (f-l)/(n-1);
|
|
TolReached = 0.;
|
|
|
|
gp_Pnt P;
|
|
Standard_Real U,V;
|
|
|
|
GeomAdaptor_Surface AS(S);
|
|
|
|
switch ( AS.GetType()) {
|
|
case GeomAbs_Plane:
|
|
{
|
|
gp_Ax3 Ax = AS.Plane().Position();
|
|
for ( Standard_Integer i = 0; i < n; i++) {
|
|
P = C->Value(f+i*du);
|
|
ElSLib::PlaneParameters(Ax,P,U,V);
|
|
TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
|
|
if ( TolReached > TolConf)
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
}
|
|
case GeomAbs_Cylinder:
|
|
{
|
|
gp_Ax3 Ax = AS.Cylinder().Position();
|
|
Standard_Real Rad = AS.Cylinder().Radius();
|
|
for ( Standard_Integer i = 0; i < n; i++) {
|
|
P = C->Value(f+i*du);
|
|
ElSLib::CylinderParameters(Ax,Rad,P,U,V);
|
|
TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
|
|
if ( TolReached > TolConf)
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
}
|
|
case GeomAbs_Cone:
|
|
{
|
|
gp_Ax3 Ax = AS.Cone().Position();
|
|
Standard_Real Rad = AS.Cone().RefRadius();
|
|
Standard_Real Alp = AS.Cone().SemiAngle();
|
|
for ( Standard_Integer i = 0; i < n; i++) {
|
|
P = C->Value(f+i*du);
|
|
ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
|
|
TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
|
|
if ( TolReached > TolConf)
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
}
|
|
case GeomAbs_Sphere:
|
|
{
|
|
gp_Ax3 Ax = AS.Sphere().Position();
|
|
Standard_Real Rad = AS.Sphere().Radius();
|
|
for ( Standard_Integer i = 0; i < n; i++) {
|
|
P = C->Value(f+i*du);
|
|
ElSLib::SphereParameters(Ax,Rad,P,U,V);
|
|
TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
|
|
if ( TolReached > TolConf)
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
}
|
|
case GeomAbs_Torus:
|
|
{
|
|
gp_Ax3 Ax = AS.Torus().Position();
|
|
Standard_Real R1 = AS.Torus().MajorRadius();
|
|
Standard_Real R2 = AS.Torus().MinorRadius();
|
|
for ( Standard_Integer i = 0; i < n; i++) {
|
|
P = C->Value(f+i*du);
|
|
ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
|
|
TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
|
|
if ( TolReached > TolConf)
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : PipeInter
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
|
|
const TopoDS_Face& F2,
|
|
TopTools_ListOfShape& L1,
|
|
TopTools_ListOfShape& L2,
|
|
const TopAbs_State Side)
|
|
{
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"FF_%d",NbFaces++);
|
|
DBRep::Set(name,F1);
|
|
sprintf(name,"FF_%d",NbFaces++);
|
|
DBRep::Set(name,F2);
|
|
}
|
|
#endif
|
|
|
|
Handle (Geom_Curve) CI;
|
|
TopAbs_Orientation O1,O2;
|
|
L1.Clear(); L2.Clear();
|
|
BRep_Builder B;
|
|
Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
|
|
Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
|
|
|
|
GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
|
|
|
|
if (Inter.IsDone()) {
|
|
for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
|
|
CI = Inter.Line(i);
|
|
if (ToSmall(CI)) continue;
|
|
TopoDS_Edge E = BRepLib_MakeEdge(CI);
|
|
if (Inter.HasLineOnS1(i)) {
|
|
Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
|
|
PutInBounds (F1,E,C2);
|
|
B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
|
|
}
|
|
else {
|
|
BuildPCurves (E,F1);
|
|
}
|
|
if (Inter.HasLineOnS2(i)) {
|
|
Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
|
|
PutInBounds (F2,E,C2);
|
|
B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
|
|
}
|
|
else {
|
|
BuildPCurves (E,F2);
|
|
}
|
|
OrientSection (E,F1,F2,O1,O2);
|
|
if (Side == TopAbs_OUT) {
|
|
O1 = TopAbs::Reverse(O1);
|
|
O2 = TopAbs::Reverse(O2);
|
|
}
|
|
L1.Append (E.Oriented(O1));
|
|
L2.Append (E.Oriented(O2));
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"EI_%d",NbNewEdges++);
|
|
DBRep::Set(name,E.Oriented(O1));
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IsAutonomVertex
|
|
//purpose : Checks whether a vertex is "autonom" or not
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& theVertex,
|
|
const BOPDS_PDS& thePDS,
|
|
const TopoDS_Face& theFace1,
|
|
const TopoDS_Face& theFace2)
|
|
{
|
|
Standard_Integer nV = thePDS->Index(theVertex);
|
|
Standard_Integer nF [2];
|
|
nF[0] = thePDS->Index(theFace1);
|
|
nF[1] = thePDS->Index(theFace2);
|
|
|
|
for (Standard_Integer i = 0; i < 2; i++)
|
|
{
|
|
const BOPDS_FaceInfo& aFaceInfo = thePDS->FaceInfo(nF[i]);
|
|
const TColStd_MapOfInteger& IndMap = aFaceInfo.VerticesOn();
|
|
if (IndMap.Contains(nV))
|
|
return Standard_False;
|
|
}
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IsAutonomVertex
|
|
//purpose : Checks whether a vertex is "autonom" or not
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
|
|
const BOPDS_PDS& pDS)
|
|
{
|
|
Standard_Integer index;
|
|
Standard_Integer aNbVVs, aNbEEs, aNbEFs, aInt;
|
|
//
|
|
index = pDS->Index(aVertex);
|
|
if (index == -1) {
|
|
Standard_Integer i, i1, i2;
|
|
i1=pDS->NbSourceShapes();
|
|
i2=pDS->NbShapes();
|
|
for (i=i1; i<i2; ++i) {
|
|
const TopoDS_Shape& aSx=pDS->Shape(i);
|
|
if(aSx.IsSame(aVertex)) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//
|
|
if (!pDS->IsNewShape(index)) {
|
|
return Standard_False;
|
|
}
|
|
//check if vertex with index "index" is not created in VV or EE or EF interference
|
|
//VV
|
|
BOPDS_VectorOfInterfVV& aVVs=pDS->InterfVV();
|
|
aNbVVs = aVVs.Length();
|
|
for(aInt = 0; aInt < aNbVVs; aInt++) {
|
|
const BOPDS_InterfVV& aVV = aVVs(aInt);
|
|
if (aVV.HasIndexNew()) {
|
|
if (aVV.IndexNew() == index) {
|
|
return Standard_False;
|
|
}
|
|
}
|
|
}
|
|
//EE
|
|
BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
|
|
aNbEEs = aEEs.Length();
|
|
for(aInt = 0; aInt < aNbEEs; aInt++) {
|
|
const BOPDS_InterfEE& aEE = aEEs(aInt);
|
|
IntTools_CommonPrt aCP = aEE.CommonPart();
|
|
if(aCP.Type() == TopAbs_VERTEX) {
|
|
if (aEE.IndexNew() == index) {
|
|
return Standard_False;
|
|
}
|
|
}
|
|
}
|
|
//EF
|
|
BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
|
|
aNbEFs = aEFs.Length();
|
|
for(aInt = 0; aInt < aNbEFs; aInt++) {
|
|
const BOPDS_InterfEF& aEF = aEFs(aInt);
|
|
IntTools_CommonPrt aCP = aEF.CommonPart();
|
|
if(aCP.Type() == TopAbs_VERTEX) {
|
|
if (aEF.IndexNew() == index) {
|
|
return Standard_False;
|
|
}
|
|
}
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : AreConnex
|
|
//purpose : define if two shapes are connex by a vertex (vertices)
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
|
|
const TopoDS_Wire& W2)
|
|
{
|
|
TopoDS_Vertex V11, V12, V21, V22;
|
|
TopExp::Vertices( W1, V11, V12 );
|
|
TopExp::Vertices( W2, V21, V22 );
|
|
|
|
if (V11.IsSame(V21) || V11.IsSame(V22) ||
|
|
V12.IsSame(V21) || V12.IsSame(V22))
|
|
return Standard_True;
|
|
|
|
return Standard_False;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : AreClosed
|
|
//purpose : define if two edges are connex by two vertices
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean AreClosed(const TopoDS_Edge& E1,
|
|
const TopoDS_Edge& E2)
|
|
{
|
|
TopoDS_Vertex V11, V12, V21, V22;
|
|
TopExp::Vertices( E1, V11, V12 );
|
|
TopExp::Vertices( E2, V21, V22 );
|
|
|
|
if ((V11.IsSame(V21) && V12.IsSame(V22)) ||
|
|
(V11.IsSame(V22) && V12.IsSame(V21)))
|
|
return Standard_True;
|
|
|
|
return Standard_False;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : BSplineEdges
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean BSplineEdges(const TopoDS_Edge& E1,
|
|
const TopoDS_Edge& E2,
|
|
const Standard_Integer par1,
|
|
const Standard_Integer par2,
|
|
Standard_Real& angle)
|
|
{
|
|
Standard_Real first1, last1, first2, last2, Param1, Param2;
|
|
|
|
Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, first1, last1 );
|
|
if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
|
|
C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
|
|
|
|
Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, first2, last2 );
|
|
if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
|
|
C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
|
|
|
|
if (!C1->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)) ||
|
|
!C2->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
|
|
return Standard_False;
|
|
|
|
Param1 = (par1 == 0)? first1 : last1;
|
|
Param2 = (par2 == 0)? first2 : last2;
|
|
|
|
gp_Pnt Pnt1, Pnt2;
|
|
gp_Vec Der1, Der2;
|
|
C1->D1( Param1, Pnt1, Der1 );
|
|
C2->D1( Param2, Pnt2, Der2 );
|
|
|
|
if (Der1.Magnitude() <= gp::Resolution() ||
|
|
Der2.Magnitude() <= gp::Resolution())
|
|
angle = M_PI/2.;
|
|
else
|
|
angle = Der1.Angle(Der2);
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : AngleWireEdge
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Real AngleWireEdge(const TopoDS_Wire& aWire,
|
|
const TopoDS_Edge& anEdge)
|
|
{
|
|
TopoDS_Vertex V11, V12, V21, V22, CV;
|
|
TopExp::Vertices( aWire, V11, V12 );
|
|
TopExp::Vertices( anEdge, V21, V22 );
|
|
CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
|
|
TopoDS_Edge FirstEdge;
|
|
TopoDS_Iterator itw(aWire);
|
|
for (; itw.More(); itw.Next())
|
|
{
|
|
FirstEdge = TopoDS::Edge(itw.Value());
|
|
TopoDS_Vertex v1, v2;
|
|
TopExp::Vertices( FirstEdge, v1, v2 );
|
|
if (v1.IsSame(CV) || v2.IsSame(CV))
|
|
{
|
|
V11 = v1;
|
|
V12 = v2;
|
|
break;
|
|
}
|
|
}
|
|
Standard_Real Angle;
|
|
if (V11.IsSame(CV) && V21.IsSame(CV))
|
|
{
|
|
BSplineEdges( FirstEdge, anEdge, 0, 0, Angle );
|
|
Angle = M_PI - Angle;
|
|
}
|
|
else if (V11.IsSame(CV) && V22.IsSame(CV))
|
|
BSplineEdges( FirstEdge, anEdge, 0, 1, Angle );
|
|
else if (V12.IsSame(CV) && V21.IsSame(CV))
|
|
BSplineEdges( FirstEdge, anEdge, 1, 0, Angle );
|
|
else
|
|
{
|
|
BSplineEdges( FirstEdge, anEdge, 1, 1, Angle );
|
|
Angle = M_PI - Angle;
|
|
}
|
|
return Angle;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ReconstructPCurves
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static void ReconstructPCurves(const TopoDS_Edge& anEdge)
|
|
{
|
|
Standard_Real f, l;
|
|
Handle(Geom_Curve) C3d = BRep_Tool::Curve(anEdge, f, l);
|
|
|
|
BRep_ListIteratorOfListOfCurveRepresentation
|
|
itcr( (Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->ChangeCurves() );
|
|
for (; itcr.More(); itcr.Next())
|
|
{
|
|
Handle( BRep_CurveRepresentation ) CurveRep = itcr.Value();
|
|
if (CurveRep->IsCurveOnSurface())
|
|
{
|
|
Handle(Geom_Surface) theSurf = CurveRep->Surface();
|
|
TopLoc_Location theLoc = CurveRep->Location();
|
|
theLoc = anEdge.Location() * theLoc;
|
|
theSurf = Handle(Geom_Surface)::DownCast
|
|
(theSurf->Transformed(theLoc.Transformation()));
|
|
Handle(Geom2d_Curve) ProjPCurve =
|
|
GeomProjLib::Curve2d( C3d, f, l, theSurf );
|
|
if(!ProjPCurve.IsNull())
|
|
{
|
|
CurveRep->PCurve( ProjPCurve );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ConcatPCurves
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
|
|
const TopoDS_Edge& E2,
|
|
const TopoDS_Face& F,
|
|
const Standard_Boolean After,
|
|
Standard_Real& newFirst,
|
|
Standard_Real& newLast)
|
|
{
|
|
Standard_Real Tol = 1.e-7;
|
|
GeomAbs_Shape Continuity = GeomAbs_C1;
|
|
Standard_Integer MaxDeg = 14;
|
|
Standard_Integer MaxSeg = 16;
|
|
|
|
Standard_Real first1, last1, first2, last2;
|
|
Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
|
|
|
|
PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
|
|
if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
|
|
PCurve1 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve1)->BasisCurve();
|
|
|
|
PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
|
|
if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
|
|
PCurve2 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve2)->BasisCurve();
|
|
|
|
if (PCurve1 == PCurve2)
|
|
{
|
|
newPCurve = PCurve1;
|
|
newFirst = Min( first1, first2 );
|
|
newLast = Max( last1, last2 );
|
|
}
|
|
else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
|
|
(PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
|
|
PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
|
|
{
|
|
newPCurve = PCurve1;
|
|
gp_Pnt2d P1, P2;
|
|
P1 = PCurve2->Value( first2 );
|
|
P2 = PCurve2->Value( last2 );
|
|
if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
|
|
{
|
|
Handle(Geom2d_Line) Lin1 = Handle(Geom2d_Line)::DownCast (PCurve1);
|
|
gp_Lin2d theLin = Lin1->Lin2d();
|
|
first2 = ElCLib::Parameter( theLin, P1 );
|
|
last2 = ElCLib::Parameter( theLin, P2 );
|
|
}
|
|
else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
|
|
{
|
|
Handle(Geom2d_Circle) Circ1 = Handle(Geom2d_Circle)::DownCast (PCurve1);
|
|
gp_Circ2d theCirc = Circ1->Circ2d();
|
|
first2 = ElCLib::Parameter( theCirc, P1 );
|
|
last2 = ElCLib::Parameter( theCirc, P2 );
|
|
}
|
|
else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
|
|
{
|
|
Handle(Geom2d_Ellipse) Ell1 = Handle(Geom2d_Ellipse)::DownCast (PCurve1);
|
|
gp_Elips2d theElips = Ell1->Elips2d();
|
|
first2 = ElCLib::Parameter( theElips, P1 );
|
|
last2 = ElCLib::Parameter( theElips, P2 );
|
|
}
|
|
else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
|
|
{
|
|
Handle(Geom2d_Parabola) Parab1 = Handle(Geom2d_Parabola)::DownCast (PCurve1);
|
|
gp_Parab2d theParab = Parab1->Parab2d();
|
|
first2 = ElCLib::Parameter( theParab, P1 );
|
|
last2 = ElCLib::Parameter( theParab, P2 );
|
|
}
|
|
else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
|
|
{
|
|
Handle(Geom2d_Hyperbola) Hypr1 = Handle(Geom2d_Hyperbola)::DownCast (PCurve1);
|
|
gp_Hypr2d theHypr = Hypr1->Hypr2d();
|
|
first2 = ElCLib::Parameter( theHypr, P1 );
|
|
last2 = ElCLib::Parameter( theHypr, P2 );
|
|
}
|
|
newFirst = Min( first1, first2 );
|
|
newLast = Max( last1, last2 );
|
|
}
|
|
else
|
|
{
|
|
Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
|
|
Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
|
|
Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
|
|
Concat2d.Add( TC2, Precision::Confusion(), After );
|
|
newPCurve = Concat2d.BSplineCurve();
|
|
if (newPCurve->Continuity() < GeomAbs_C1)
|
|
{
|
|
Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
|
|
if (Approx2d.HasResult())
|
|
newPCurve = Approx2d.Curve();
|
|
}
|
|
newFirst = newPCurve->FirstParameter();
|
|
newLast = newPCurve->LastParameter();
|
|
}
|
|
|
|
return newPCurve;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Glue
|
|
//purpose : glue two edges.
|
|
//=======================================================================
|
|
|
|
static TopoDS_Edge Glue(const TopoDS_Edge& E1,
|
|
const TopoDS_Edge& E2,
|
|
const TopoDS_Vertex& Vfirst,
|
|
const TopoDS_Vertex& Vlast,
|
|
const Standard_Boolean After,
|
|
const TopoDS_Face& F1,
|
|
const Standard_Boolean addPCurve1,
|
|
const TopoDS_Face& F2,
|
|
const Standard_Boolean addPCurve2,
|
|
const Standard_Real theGlueTol)
|
|
{
|
|
TopoDS_Edge newEdge;
|
|
|
|
Standard_Real Tol = 1.e-7;
|
|
GeomAbs_Shape Continuity = GeomAbs_C1;
|
|
Standard_Integer MaxDeg = 14;
|
|
Standard_Integer MaxSeg = 16;
|
|
|
|
Handle(Geom_Curve) C1, C2, newCurve;
|
|
Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
|
|
Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
|
|
Standard_Boolean IsCanonic = Standard_False;
|
|
|
|
C1 = BRep_Tool::Curve( E1, first1, last1 );
|
|
if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
|
|
C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
|
|
|
|
C2 = BRep_Tool::Curve( E2, first2, last2 );
|
|
if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
|
|
C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
|
|
|
|
if (C1 == C2)
|
|
{
|
|
newCurve = C1;
|
|
fparam = Min( first1, first2 );
|
|
lparam = Max( last1, last2 );
|
|
}
|
|
else if (C1->DynamicType() == C2->DynamicType() &&
|
|
(C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
|
|
C1->IsKind(STANDARD_TYPE(Geom_Conic))))
|
|
{
|
|
IsCanonic = Standard_True;
|
|
newCurve = C1;
|
|
}
|
|
else
|
|
{
|
|
Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
|
|
Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
|
|
GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
|
|
if (!Concat.Add( TC2, theGlueTol, After ))
|
|
return newEdge;
|
|
newCurve = Concat.BSplineCurve();
|
|
if (newCurve->Continuity() < GeomAbs_C1)
|
|
{
|
|
GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
|
|
if (Approx3d.HasResult())
|
|
newCurve = Approx3d.Curve();
|
|
}
|
|
fparam = newCurve->FirstParameter();
|
|
lparam = newCurve->LastParameter();
|
|
}
|
|
|
|
BRep_Builder BB;
|
|
|
|
if (IsCanonic)
|
|
newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
|
|
else
|
|
newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
|
|
|
|
Standard_Real newFirst, newLast;
|
|
if (addPCurve1)
|
|
{
|
|
newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
|
|
BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
|
|
BB.Range( newEdge, F1, newFirst, newLast );
|
|
}
|
|
if (addPCurve2)
|
|
{
|
|
newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
|
|
BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
|
|
BB.Range( newEdge, F2, newFirst, newLast );
|
|
}
|
|
|
|
return newEdge;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CheckIntersFF
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static void CheckIntersFF(const BOPDS_PDS& pDS,
|
|
const TopoDS_Edge& RefEdge,
|
|
TopTools_IndexedMapOfShape& TrueEdges)
|
|
{
|
|
BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
|
|
Standard_Integer aNb = aFFs.Length();
|
|
Standard_Integer i, j, nbe = 0;
|
|
|
|
TopoDS_Compound Edges;
|
|
BRep_Builder BB;
|
|
BB.MakeCompound(Edges);
|
|
|
|
for (i = 0; i < aNb; ++i)
|
|
{
|
|
BOPDS_InterfFF& aFFi=aFFs(i);
|
|
const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
|
|
Standard_Integer aNbCurves = aBCurves.Length();
|
|
|
|
for (j = 0; j < aNbCurves; ++j)
|
|
{
|
|
const BOPDS_Curve& aBC=aBCurves(j);
|
|
const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
|
|
|
|
BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
|
|
aPBIt.Initialize(aSectEdges);
|
|
|
|
for (; aPBIt.More(); aPBIt.Next())
|
|
{
|
|
const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
|
|
Standard_Integer nSect = aPB->Edge();
|
|
const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
|
|
BB.Add(Edges, anEdge);
|
|
nbe++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nbe == 0)
|
|
return;
|
|
|
|
TopTools_ListOfShape CompList;
|
|
BOPTools_AlgoTools::MakeConnexityBlocks(Edges, TopAbs_VERTEX, TopAbs_EDGE, CompList);
|
|
|
|
TopoDS_Shape NearestCompound;
|
|
if (CompList.Extent() == 1)
|
|
NearestCompound = CompList.First();
|
|
else
|
|
{
|
|
BRepAdaptor_Curve BAcurve(RefEdge);
|
|
gp_Pnt Pref = BAcurve.Value((BAcurve.FirstParameter()+BAcurve.LastParameter())/2);
|
|
TopoDS_Vertex Vref = BRepLib_MakeVertex(Pref);
|
|
Standard_Real MinDist = RealLast();
|
|
TopTools_ListIteratorOfListOfShape itl(CompList);
|
|
for (; itl.More(); itl.Next())
|
|
{
|
|
const TopoDS_Shape& aCompound = itl.Value();
|
|
|
|
BRepExtrema_DistShapeShape Projector(Vref, aCompound);
|
|
if (!Projector.IsDone() || Projector.NbSolution() == 0)
|
|
continue;
|
|
|
|
Standard_Real aDist = Projector.Value();
|
|
if (aDist < MinDist)
|
|
{
|
|
MinDist = aDist;
|
|
NearestCompound = aCompound;
|
|
}
|
|
}
|
|
}
|
|
|
|
TopExp::MapShapes(NearestCompound, TopAbs_EDGE, TrueEdges);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : AssembleEdge
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
|
|
const TopoDS_Face& F1,
|
|
const TopoDS_Face& F2,
|
|
const Standard_Boolean addPCurve1,
|
|
const Standard_Boolean addPCurve2,
|
|
const TopTools_SequenceOfShape& EdgesForConcat)
|
|
{
|
|
TopoDS_Edge NullEdge;
|
|
TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
|
|
Standard_Real aGlueTol = Precision::Confusion();
|
|
|
|
for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
|
|
{
|
|
TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
|
|
Standard_Boolean After = Standard_False;
|
|
TopoDS_Vertex Vfirst, Vlast;
|
|
Standard_Boolean AreClosedWire = AreClosed( CurEdge, anEdge );
|
|
if (AreClosedWire)
|
|
{
|
|
TopoDS_Vertex V1, V2;
|
|
TopExp::Vertices( CurEdge, V1, V2 );
|
|
Standard_Boolean IsAutonomV1 = IsAutonomVertex( V1, pDS, F1, F2 );
|
|
Standard_Boolean IsAutonomV2 = IsAutonomVertex( V2, pDS, F1, F2 );
|
|
if (IsAutonomV1)
|
|
{
|
|
After = Standard_False;
|
|
Vfirst = Vlast = V2;
|
|
}
|
|
else if (IsAutonomV2)
|
|
{
|
|
After = Standard_True;
|
|
Vfirst = Vlast = V1;
|
|
}
|
|
else
|
|
return NullEdge;
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Vertex CV, V11, V12, V21, V22;
|
|
TopExp::CommonVertex( CurEdge, anEdge, CV );
|
|
Standard_Boolean IsAutonomCV = Standard_False;
|
|
if (!CV.IsNull())
|
|
{
|
|
IsAutonomCV = IsAutonomVertex(CV, pDS, F1, F2);
|
|
}
|
|
if (IsAutonomCV)
|
|
{
|
|
aGlueTol = BRep_Tool::Tolerance(CV);
|
|
TopExp::Vertices( CurEdge, V11, V12 );
|
|
TopExp::Vertices( anEdge, V21, V22 );
|
|
if (V11.IsSame(CV) && V21.IsSame(CV))
|
|
{
|
|
Vfirst = V22;
|
|
Vlast = V12;
|
|
}
|
|
else if (V11.IsSame(CV) && V22.IsSame(CV))
|
|
{
|
|
Vfirst = V21;
|
|
Vlast = V12;
|
|
}
|
|
else if (V12.IsSame(CV) && V21.IsSame(CV))
|
|
{
|
|
Vfirst = V11;
|
|
Vlast = V22;
|
|
}
|
|
else
|
|
{
|
|
Vfirst = V11;
|
|
Vlast = V21;
|
|
}
|
|
}
|
|
else
|
|
return NullEdge;
|
|
} //end of else (open wire)
|
|
|
|
TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After,
|
|
F1, addPCurve1, F2, addPCurve2, aGlueTol);
|
|
if (NewEdge.IsNull())
|
|
return NullEdge;
|
|
else
|
|
CurEdge = NewEdge;
|
|
} //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
|
|
|
|
return CurEdge;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Inter3D
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
|
|
const TopoDS_Face& F2,
|
|
TopTools_ListOfShape& L1,
|
|
TopTools_ListOfShape& L2,
|
|
const TopAbs_State Side,
|
|
const TopoDS_Edge& RefEdge,
|
|
const TopoDS_Face& theRefFace1,
|
|
const TopoDS_Face& theRefFace2)
|
|
{
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"FF_%d",NbFaces++);
|
|
DBRep::Set(name,F1);
|
|
sprintf(name,"FF_%d",NbFaces++);
|
|
DBRep::Set(name,F2);
|
|
}
|
|
#endif
|
|
|
|
// Check if the faces are planar and not trimmed - in this case
|
|
// the IntTools_FaceFace intersection algorithm will be used directly.
|
|
BRepAdaptor_Surface aBAS1(F1, Standard_False), aBAS2(F2, Standard_False);
|
|
if (aBAS1.GetType() == GeomAbs_Plane &&
|
|
aBAS2.GetType() == GeomAbs_Plane) {
|
|
aBAS1.Initialize(F1, Standard_True);
|
|
if (IsInf(aBAS1.LastUParameter()) && IsInf(aBAS1.LastVParameter())) {
|
|
aBAS2.Initialize(F2, Standard_True);
|
|
if (IsInf(aBAS2.LastUParameter()) && IsInf(aBAS2.LastVParameter())) {
|
|
// Intersect the planes without pave filler
|
|
PerformPlanes(F1, F2, Side, L1, L2);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// create 3D curves on faces
|
|
BRepLib::BuildCurves3d(F1);
|
|
BRepLib::BuildCurves3d(F2);
|
|
UpdateVertexTolerances(F1);
|
|
UpdateVertexTolerances(F2);
|
|
|
|
BOPAlgo_PaveFiller aPF;
|
|
TopTools_ListOfShape aLS;
|
|
aLS.Append(F1);
|
|
aLS.Append(F2);
|
|
aPF.SetArguments(aLS);
|
|
//
|
|
aPF.Perform();
|
|
|
|
TopTools_IndexedMapOfShape TrueEdges;
|
|
if (!RefEdge.IsNull())
|
|
CheckIntersFF( aPF.PDS(), RefEdge, TrueEdges );
|
|
|
|
Standard_Boolean addPCurve1 = 1;
|
|
Standard_Boolean addPCurve2 = 1;
|
|
|
|
const BOPDS_PDS& pDS = aPF.PDS();
|
|
BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
|
|
Standard_Integer aNb = aFFs.Length();
|
|
Standard_Integer i = 0, j = 0, k;
|
|
// Store Result
|
|
L1.Clear(); L2.Clear();
|
|
TopAbs_Orientation O1,O2;
|
|
BRep_Builder BB;
|
|
//
|
|
const Handle(IntTools_Context)& aContext = aPF.Context();
|
|
//
|
|
for (i = 0; i < aNb; i++) {
|
|
BOPDS_InterfFF& aFFi=aFFs(i);
|
|
const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
|
|
|
|
Standard_Integer aNbCurves = aBCurves.Length();
|
|
|
|
for (j = 0; j < aNbCurves; j++) {
|
|
const BOPDS_Curve& aBC=aBCurves(j);
|
|
const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
|
|
|
|
BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
|
|
aPBIt.Initialize(aSectEdges);
|
|
|
|
for (; aPBIt.More(); aPBIt.Next()) {
|
|
const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
|
|
Standard_Integer nSect = aPB->Edge();
|
|
const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
|
|
if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
|
|
continue;
|
|
|
|
Standard_Real f, l;
|
|
const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
|
|
Handle(Geom_TrimmedCurve) aC3DETrim;
|
|
|
|
if(!aC3DE.IsNull())
|
|
aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
|
|
|
|
Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
|
|
|
|
if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F1)) {
|
|
Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
|
|
if(!aC3DETrim.IsNull()) {
|
|
Handle(Geom2d_Curve) aC2dNew;
|
|
|
|
if(aC3DE->IsPeriodic()) {
|
|
BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l, aC2d, aC2dNew, aContext);
|
|
}
|
|
else {
|
|
BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext);
|
|
}
|
|
aC2d = aC2dNew;
|
|
}
|
|
BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge);
|
|
}
|
|
|
|
if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F2)) {
|
|
Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
|
|
if(!aC3DETrim.IsNull()) {
|
|
Handle(Geom2d_Curve) aC2dNew;
|
|
|
|
if(aC3DE->IsPeriodic()) {
|
|
BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l, aC2d, aC2dNew, aContext);
|
|
}
|
|
else {
|
|
BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext);
|
|
}
|
|
aC2d = aC2dNew;
|
|
}
|
|
BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge);
|
|
}
|
|
|
|
OrientSection (anEdge, F1, F2, O1, O2);
|
|
if (Side == TopAbs_OUT) {
|
|
O1 = TopAbs::Reverse(O1);
|
|
O2 = TopAbs::Reverse(O2);
|
|
}
|
|
|
|
L1.Append (anEdge.Oriented(O1));
|
|
L2.Append (anEdge.Oriented(O2));
|
|
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"EI_%d",NbNewEdges++);
|
|
DBRep::Set(name,anEdge.Oriented(O1));
|
|
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
Standard_Real aSameParTol = Precision::Confusion();
|
|
Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
|
|
|
|
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
|
|
if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
|
|
aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
|
|
if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
|
|
addPCurve1 = Standard_False;
|
|
else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
|
|
isEl1 = Standard_True;
|
|
|
|
aSurf = BRep_Tool::Surface(F2);
|
|
if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
|
|
aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
|
|
if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
|
|
addPCurve2 = Standard_False;
|
|
else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
|
|
isEl2 = Standard_True;
|
|
|
|
if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
|
|
{
|
|
//remove excess edges that are out of range
|
|
TopoDS_Vertex aV1, aV2;
|
|
TopExp::Vertices (RefEdge, aV1, aV2);
|
|
if (!aV1.IsSame(aV2)) //only if RefEdge is open
|
|
{
|
|
Handle(Geom_Surface) aRefSurf1 = BRep_Tool::Surface (theRefFace1);
|
|
Handle(Geom_Surface) aRefSurf2 = BRep_Tool::Surface (theRefFace2);
|
|
if (aRefSurf1->IsUClosed() || aRefSurf1->IsVClosed() ||
|
|
aRefSurf2->IsUClosed() || aRefSurf2->IsVClosed())
|
|
{
|
|
TopoDS_Edge MinAngleEdge;
|
|
Standard_Real MinAngle = Precision::Infinite();
|
|
BRepAdaptor_Curve aRefBAcurve (RefEdge);
|
|
gp_Pnt aRefPnt = aRefBAcurve.Value ((aRefBAcurve.FirstParameter() + aRefBAcurve.LastParameter())/2);
|
|
|
|
TopTools_ListIteratorOfListOfShape itl (L1);
|
|
for (; itl.More(); itl.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge (itl.Value());
|
|
|
|
BRepAdaptor_Curve aBAcurve (anEdge);
|
|
gp_Pnt aMidPntOnEdge = aBAcurve.Value ((aBAcurve.FirstParameter() + aBAcurve.LastParameter())/2);
|
|
gp_Vec RefToMid (aRefPnt, aMidPntOnEdge);
|
|
|
|
Extrema_ExtPC aProjector (aRefPnt, aBAcurve);
|
|
if (aProjector.IsDone())
|
|
{
|
|
Standard_Integer imin = 0;
|
|
Standard_Real MinSqDist = Precision::Infinite();
|
|
for (Standard_Integer ind = 1; ind <= aProjector.NbExt(); ind++)
|
|
{
|
|
Standard_Real aSqDist = aProjector.SquareDistance(ind);
|
|
if (aSqDist < MinSqDist)
|
|
{
|
|
MinSqDist = aSqDist;
|
|
imin = ind;
|
|
}
|
|
}
|
|
if (imin != 0)
|
|
{
|
|
gp_Pnt aProjectionOnEdge = aProjector.Point(imin).Value();
|
|
gp_Vec RefToProj (aRefPnt, aProjectionOnEdge);
|
|
Standard_Real anAngle = RefToProj.Angle(RefToMid);
|
|
if (anAngle < MinAngle)
|
|
{
|
|
MinAngle = anAngle;
|
|
MinAngleEdge = anEdge;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!MinAngleEdge.IsNull())
|
|
{
|
|
TopTools_ListIteratorOfListOfShape itlist1 (L1);
|
|
TopTools_ListIteratorOfListOfShape itlist2 (L2);
|
|
|
|
while (itlist1.More())
|
|
{
|
|
const TopoDS_Shape& anEdge = itlist1.Value();
|
|
if (anEdge.IsSame(MinAngleEdge))
|
|
{
|
|
itlist1.Next();
|
|
itlist2.Next();
|
|
}
|
|
else
|
|
{
|
|
L1.Remove(itlist1);
|
|
L2.Remove(itlist2);
|
|
}
|
|
}
|
|
}
|
|
} //if closed
|
|
} //if (!aV1.IsSame(aV2))
|
|
} //if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
|
|
|
|
if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
|
|
TopTools_SequenceOfShape eseq;
|
|
TopTools_SequenceOfShape EdgesForConcat;
|
|
|
|
if (!TrueEdges.IsEmpty())
|
|
{
|
|
for (i = TrueEdges.Extent(); i >= 1; i--)
|
|
EdgesForConcat.Append( TrueEdges(i) );
|
|
TopoDS_Edge AssembledEdge =
|
|
AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, EdgesForConcat );
|
|
if (AssembledEdge.IsNull())
|
|
for (i = TrueEdges.Extent(); i >= 1; i--)
|
|
eseq.Append( TrueEdges(i) );
|
|
else
|
|
eseq.Append(AssembledEdge);
|
|
}
|
|
else
|
|
{
|
|
TopTools_SequenceOfShape wseq;
|
|
TopTools_SequenceOfShape edges;
|
|
TopTools_ListIteratorOfListOfShape itl(L1);
|
|
for (; itl.More(); itl.Next())
|
|
edges.Append( itl.Value() );
|
|
while (!edges.IsEmpty())
|
|
{
|
|
TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
|
|
TopoDS_Wire aWire, resWire;
|
|
BB.MakeWire(aWire);
|
|
BB.Add( aWire, anEdge );
|
|
TColStd_SequenceOfInteger Candidates;
|
|
for (k = 1; k <= wseq.Length(); k++)
|
|
{
|
|
resWire = TopoDS::Wire(wseq(k));
|
|
if (AreConnex( resWire, aWire ))
|
|
{
|
|
Candidates.Append( 1 );
|
|
break;
|
|
}
|
|
}
|
|
if (Candidates.IsEmpty())
|
|
{
|
|
wseq.Append( aWire );
|
|
edges.Remove(1);
|
|
}
|
|
else
|
|
{
|
|
for (j = 2; j <= edges.Length(); j++)
|
|
{
|
|
anEdge = TopoDS::Edge( edges(j) );
|
|
aWire.Nullify();
|
|
BB.MakeWire(aWire);
|
|
BB.Add( aWire, anEdge );
|
|
if (AreConnex( resWire, aWire ))
|
|
Candidates.Append( j );
|
|
}
|
|
Standard_Integer minind = 1;
|
|
if (Candidates.Length() > 1)
|
|
{
|
|
Standard_Real MinAngle = RealLast();
|
|
for (j = 1; j <= Candidates.Length(); j++)
|
|
{
|
|
anEdge = TopoDS::Edge( edges(Candidates(j)) );
|
|
Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
|
|
if (anAngle < MinAngle)
|
|
{
|
|
MinAngle = anAngle;
|
|
minind = j;
|
|
}
|
|
}
|
|
}
|
|
BB.Add( resWire, TopoDS::Edge(edges(Candidates(minind))) );
|
|
wseq(k) = resWire;
|
|
edges.Remove(Candidates(minind));
|
|
}
|
|
} //end of while (!edges.IsEmpty())
|
|
|
|
for (i = 1; i <= wseq.Length(); i++)
|
|
{
|
|
TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
|
|
TopTools_SequenceOfShape aLocalEdgesForConcat;
|
|
if (aWire.Closed())
|
|
{
|
|
TopoDS_Vertex StartVertex;
|
|
TopoDS_Edge StartEdge;
|
|
Standard_Boolean StartFound = Standard_False;
|
|
TopTools_ListOfShape Elist;
|
|
|
|
TopoDS_Iterator itw(aWire);
|
|
for (; itw.More(); itw.Next())
|
|
{
|
|
TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
|
|
if (StartFound)
|
|
Elist.Append(anEdge);
|
|
else
|
|
{
|
|
TopoDS_Vertex V1, V2;
|
|
TopExp::Vertices( anEdge, V1, V2 );
|
|
if (!IsAutonomVertex( V1, pDS ))
|
|
{
|
|
StartVertex = V2;
|
|
StartEdge = anEdge;
|
|
StartFound = Standard_True;
|
|
}
|
|
else if (!IsAutonomVertex( V2, pDS ))
|
|
{
|
|
StartVertex = V1;
|
|
StartEdge = anEdge;
|
|
StartFound = Standard_True;
|
|
}
|
|
else
|
|
Elist.Append(anEdge);
|
|
}
|
|
} //end of for (; itw.More(); itw.Next())
|
|
if (!StartFound)
|
|
{
|
|
itl.Initialize(Elist);
|
|
StartEdge = TopoDS::Edge(itl.Value());
|
|
Elist.Remove(itl);
|
|
TopoDS_Vertex V1, V2;
|
|
TopExp::Vertices( StartEdge, V1, V2 );
|
|
StartVertex = V1;
|
|
}
|
|
aLocalEdgesForConcat.Append( StartEdge );
|
|
while (!Elist.IsEmpty())
|
|
{
|
|
for (itl.Initialize(Elist); itl.More(); itl.Next())
|
|
{
|
|
TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
|
|
TopoDS_Vertex V1, V2;
|
|
TopExp::Vertices( anEdge, V1, V2 );
|
|
if (V1.IsSame(StartVertex))
|
|
{
|
|
StartVertex = V2;
|
|
aLocalEdgesForConcat.Append( anEdge );
|
|
Elist.Remove(itl);
|
|
break;
|
|
}
|
|
else if (V2.IsSame(StartVertex))
|
|
{
|
|
StartVertex = V1;
|
|
aLocalEdgesForConcat.Append( anEdge );
|
|
Elist.Remove(itl);
|
|
break;
|
|
}
|
|
}
|
|
} //end of while (!Elist.IsEmpty())
|
|
} //end of if (aWire.Closed())
|
|
else
|
|
{
|
|
BRepTools_WireExplorer Wexp( aWire );
|
|
for (; Wexp.More(); Wexp.Next())
|
|
aLocalEdgesForConcat.Append( Wexp.Current() );
|
|
}
|
|
|
|
TopoDS_Edge AssembledEdge =
|
|
AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, aLocalEdgesForConcat );
|
|
if (AssembledEdge.IsNull())
|
|
for (j = aLocalEdgesForConcat.Length(); j >= 1; j--)
|
|
eseq.Append( aLocalEdgesForConcat(j) );
|
|
else
|
|
eseq.Append( AssembledEdge );
|
|
} //for (i = 1; i <= wseq.Length(); i++)
|
|
} //end of else (when TrueEdges is empty)
|
|
|
|
if (eseq.Length() < L1.Extent())
|
|
{
|
|
L1.Clear();
|
|
L2.Clear();
|
|
for (i = 1; i <= eseq.Length(); i++)
|
|
{
|
|
TopoDS_Shape aShape = eseq(i);
|
|
TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
|
|
BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
|
|
Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
|
|
#ifdef OCCT_DEBUG
|
|
std::cout<<"Tolerance of glued E = "<<EdgeTol<<std::endl;
|
|
#endif
|
|
if (EdgeTol > 1.e-2)
|
|
continue;
|
|
|
|
if (EdgeTol >= 1.e-4)
|
|
{
|
|
ReconstructPCurves(anEdge);
|
|
BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
|
|
#ifdef OCCT_DEBUG
|
|
std::cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<std::endl;
|
|
#endif
|
|
}
|
|
|
|
OrientSection( anEdge, F1, F2, O1, O2 );
|
|
if (Side == TopAbs_OUT)
|
|
{
|
|
O1 = TopAbs::Reverse(O1);
|
|
O2 = TopAbs::Reverse(O2);
|
|
}
|
|
|
|
L1.Append( anEdge.Oriented(O1) );
|
|
L2.Append( anEdge.Oriented(O2) );
|
|
}
|
|
}
|
|
} //end of if (L1.Extent() > 1)
|
|
|
|
else
|
|
{
|
|
TopTools_ListIteratorOfListOfShape itl(L1);
|
|
for (; itl.More(); itl.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
|
|
BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TryProject
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepOffset_Tool::TryProject
|
|
(const TopoDS_Face& F1,
|
|
const TopoDS_Face& F2,
|
|
const TopTools_ListOfShape& Edges,
|
|
TopTools_ListOfShape& LInt1,
|
|
TopTools_ListOfShape& LInt2,
|
|
const TopAbs_State Side,
|
|
const Standard_Real TolConf)
|
|
{
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"FF_%d",NbFaces++);
|
|
DBRep::Set(name,F1);
|
|
sprintf(name,"FF_%d",NbFaces++);
|
|
DBRep::Set(name,F2);
|
|
}
|
|
#endif
|
|
|
|
// try to find if the edges <Edges> are laying on the face F1.
|
|
LInt1.Clear(); LInt2.Clear();
|
|
TopTools_ListIteratorOfListOfShape it(Edges);
|
|
Standard_Boolean isOk = Standard_True;
|
|
Standard_Boolean Ok = Standard_True;
|
|
TopAbs_Orientation O1,O2;
|
|
Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
|
|
BRep_Builder B;
|
|
|
|
for ( ; it.More(); it.Next()) {
|
|
TopLoc_Location L;
|
|
Standard_Real f,l;
|
|
TopoDS_Edge CurE = TopoDS::Edge(it.Value());
|
|
Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
|
|
if (C.IsNull()) {
|
|
BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
|
|
C = BRep_Tool::Curve(CurE,L,f,l);
|
|
}
|
|
C = new Geom_TrimmedCurve(C,f,l);
|
|
if ( !L.IsIdentity()) C->Transform(L);
|
|
Standard_Real TolReached;
|
|
isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
|
|
|
|
if ( isOk) {
|
|
B.UpdateEdge(CurE,TolReached);
|
|
BuildPCurves(CurE,F1);
|
|
OrientSection (CurE,F1,F2,O1,O2);
|
|
if (Side == TopAbs_OUT) {
|
|
O1 = TopAbs::Reverse(O1);
|
|
O2 = TopAbs::Reverse(O2);
|
|
}
|
|
LInt1.Append (CurE.Oriented(O1));
|
|
LInt2.Append (CurE.Oriented(O2));
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"EI_%d",NbNewEdges++);
|
|
DBRep::Set(name,CurE.Oriented(O1));
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
Ok = Standard_False;
|
|
}
|
|
return Ok;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : InterOrExtent
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
|
|
const TopoDS_Face& F2,
|
|
TopTools_ListOfShape& L1,
|
|
TopTools_ListOfShape& L2,
|
|
const TopAbs_State Side)
|
|
{
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"FF_%d",NbFaces++);
|
|
DBRep::Set(name,F1);
|
|
sprintf(name,"FF_%d",NbFaces++);
|
|
DBRep::Set(name,F2);
|
|
}
|
|
#endif
|
|
|
|
Handle (Geom_Curve) CI;
|
|
TopAbs_Orientation O1,O2;
|
|
L1.Clear(); L2.Clear();
|
|
Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
|
|
Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
|
|
|
|
if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
|
|
Handle(Geom_RectangularTrimmedSurface) RTS ;
|
|
RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S1);
|
|
if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
|
|
S1 = RTS->BasisSurface();
|
|
}
|
|
}
|
|
if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
|
|
Handle(Geom_RectangularTrimmedSurface) RTS ;
|
|
RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S2);
|
|
if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
|
|
S2 = RTS->BasisSurface();
|
|
}
|
|
}
|
|
|
|
GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
|
|
|
|
if (Inter.IsDone()) {
|
|
for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
|
|
CI = Inter.Line(i);
|
|
|
|
if (ToSmall(CI)) continue;
|
|
TopoDS_Edge E = BRepLib_MakeEdge(CI);
|
|
BuildPCurves (E,F1);
|
|
BuildPCurves (E,F2);
|
|
OrientSection (E,F1,F2,O1,O2);
|
|
if (Side == TopAbs_OUT) {
|
|
O1 = TopAbs::Reverse(O1);
|
|
O2 = TopAbs::Reverse(O2);
|
|
}
|
|
L1.Append (E.Oriented(O1));
|
|
L2.Append (E.Oriented(O2));
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"EI_%d",NbNewEdges++);
|
|
DBRep::Set(name,E.Oriented(O1));
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ExtentEdge
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static void ExtentEdge(const TopoDS_Face& F,
|
|
const TopoDS_Face& EF,
|
|
const TopoDS_Edge& E,
|
|
TopoDS_Edge& NE)
|
|
{
|
|
BRepAdaptor_Curve CE(E);
|
|
GeomAbs_CurveType Type = CE.GetType();
|
|
TopoDS_Shape aLocalEdge = E.EmptyCopied();
|
|
NE = TopoDS::Edge(aLocalEdge);
|
|
// NE = TopoDS::Edge(E.EmptyCopied());
|
|
|
|
if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
|
|
Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
|
|
return;
|
|
}
|
|
// Extension en tangence jusqu'au bord de la surface.
|
|
Standard_Real PMax = 1.e2;
|
|
TopLoc_Location L;
|
|
Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
|
|
Standard_Real umin,umax,vmin,vmax;
|
|
|
|
S->Bounds(umin,umax,vmin,vmax);
|
|
umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
|
|
umax = Min(umax, PMax);vmax = Min(vmax, PMax);
|
|
|
|
|
|
Standard_Real f,l;
|
|
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
|
|
|
|
//calcul point cible . ie point d'intersection du prolongement tangent et des bords.
|
|
gp_Pnt2d P;
|
|
gp_Vec2d Tang;
|
|
C2d->D1(CE.FirstParameter(),P,Tang);
|
|
Standard_Real tx,ty,tmin;
|
|
tx = ty = Precision::Infinite();
|
|
if (Abs(Tang.X()) > Precision::Confusion())
|
|
tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
|
|
if (Abs(Tang.Y()) > Precision::Confusion())
|
|
ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
|
|
tmin = Min (tx,ty);
|
|
Tang = tmin*Tang;
|
|
gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
|
|
|
|
C2d->D1(CE.LastParameter(),P,Tang);
|
|
tx = ty = Precision::Infinite();
|
|
if (Abs(Tang.X()) > Precision::Confusion())
|
|
tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
|
|
if (Abs(Tang.Y()) > Precision::Confusion())
|
|
ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
|
|
tmin = Min (tx,ty);
|
|
Tang = tmin*Tang;
|
|
gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
|
|
|
|
Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
|
|
gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
|
|
gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
|
|
|
|
Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
|
|
if (ExtC.IsNull()) return;
|
|
|
|
GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
|
|
GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
|
|
|
|
Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
|
|
|
|
//Construction de la nouvelle arrete;
|
|
BRep_Builder B;
|
|
B.MakeEdge(NE);
|
|
// B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
|
|
B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
|
|
B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
|
|
NE.Orientation(E.Orientation());
|
|
#ifdef DRAW
|
|
if (AffichExtent) {
|
|
char name[256];
|
|
sprintf (name,"F_%d",NbExtE);
|
|
DBRep::Set(name,EF);
|
|
sprintf (name,"OE_%d",NbExtE);
|
|
DBRep::Set (name,E);
|
|
sprintf (name,"ExtE_%d",NbExtE++);
|
|
DBRep::Set(name,NE);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ProjectVertexOnEdge
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
|
|
const TopoDS_Edge& E,
|
|
Standard_Real TolConf)
|
|
{
|
|
#ifdef DRAW
|
|
if (AffichExtent) {
|
|
DBRep::Set("V",V);
|
|
DBRep::Set("E",E);
|
|
}
|
|
#endif
|
|
BRep_Builder B;
|
|
Standard_Real f,l;
|
|
Standard_Real U = 0.;
|
|
TopLoc_Location L;
|
|
Standard_Boolean found = Standard_False;
|
|
|
|
gp_Pnt P = BRep_Tool::Pnt (V);
|
|
BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
|
|
f = C.FirstParameter(); l = C.LastParameter();
|
|
|
|
if (V.Orientation() == TopAbs_FORWARD) {
|
|
if (Abs(f) < Precision::Infinite()) {
|
|
gp_Pnt PF = C.Value (f);
|
|
if (PF.IsEqual(P,TolConf)) {
|
|
U = f;
|
|
found = Standard_True;
|
|
}
|
|
}
|
|
}
|
|
if (V.Orientation() == TopAbs_REVERSED) {
|
|
if (!found && Abs(l) < Precision::Infinite()) {
|
|
gp_Pnt PL = C.Value (l);
|
|
if (PL.IsEqual(P,TolConf)) {
|
|
U = l;
|
|
found = Standard_True;
|
|
}
|
|
}
|
|
}
|
|
if (!found) {
|
|
Extrema_ExtPC Proj(P,C);
|
|
if (Proj.IsDone() && Proj.NbExt() > 0) {
|
|
Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
|
|
U = Proj.Point(1).Parameter();
|
|
for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
|
|
Dist2 = Proj.SquareDistance(i);
|
|
if (Dist2 < Dist2Min) {
|
|
Dist2Min = Dist2;
|
|
U = Proj.Point(i).Parameter();
|
|
}
|
|
}
|
|
found = Standard_True;
|
|
}
|
|
}
|
|
|
|
#ifdef OCCT_DEBUG
|
|
if (AffichExtent) {
|
|
Standard_Real Dist = P.Distance(C.Value(U));
|
|
if (Dist > TolConf) {
|
|
std::cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<std::endl;
|
|
}
|
|
if (U < f - Precision::Confusion() ||
|
|
U > l + Precision::Confusion()) {
|
|
std::cout << " ProjectVertexOnEdge : hors borne :"<<std::endl;
|
|
std::cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<std::endl;
|
|
}
|
|
}
|
|
if (!found) {
|
|
std::cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<std::endl;
|
|
if (Abs(f) < Precision::Infinite() &&
|
|
Abs(l) < Precision::Infinite()) {
|
|
#ifdef DRAW
|
|
DBRep::Set("E",E);
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
if (found) {
|
|
TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
|
|
TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
|
|
aLocalShape = V.Oriented(TopAbs_INTERNAL);
|
|
// TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
|
|
B.UpdateVertex(TopoDS::Vertex(aLocalShape),
|
|
U,EE,BRep_Tool::Tolerance(E));
|
|
|
|
}
|
|
return found;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Inter2d
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
|
|
const TopoDS_Edge& E1,
|
|
const TopoDS_Edge& E2,
|
|
TopTools_ListOfShape& LV,
|
|
const Standard_Real TolConf)
|
|
{
|
|
#ifdef DRAW
|
|
if (AffichExtent) {
|
|
DBRep::Set("E1",E1);
|
|
DBRep::Set("E2",E2);
|
|
DBRep::Set("F",F);
|
|
}
|
|
#endif
|
|
BRep_Builder B;
|
|
Standard_Real fl1[2],fl2[2];
|
|
LV.Clear();
|
|
|
|
// Si l edge a ete etendu les pcurves ne sont pas forcement
|
|
// a jour.
|
|
BuildPCurves(E1,F);
|
|
BuildPCurves(E2,F);
|
|
|
|
|
|
// Construction des curves 3d si elles n existent pas
|
|
// utile pour coder correctement les parametres des vertex
|
|
// d intersection sur les edges.
|
|
//TopLoc_Location L;
|
|
//Standard_Real f,l;
|
|
//Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
|
|
//if (C3d1.IsNull()) {
|
|
// BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
|
|
//}
|
|
//Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
|
|
//if (C3d2.IsNull()) {
|
|
// BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
|
|
//}
|
|
|
|
Standard_Integer NbPC1 = 1, NbPC2 = 1;
|
|
if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
|
|
if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
|
|
|
|
Handle(Geom_Surface) S = BRep_Tool::Surface(F);
|
|
Handle(Geom2d_Curve) C1, C2;
|
|
Standard_Boolean YaSol = Standard_False;
|
|
Standard_Integer itry = 0;
|
|
|
|
while (!YaSol && itry < 2) {
|
|
for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
|
|
TopoDS_Shape aLocalEdgeReversedE1 = E1.Reversed();
|
|
if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
|
|
else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdgeReversedE1),
|
|
F,fl1[0],fl1[1]);
|
|
// if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
|
|
// else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
|
|
// F,fl1[0],fl1[1]);
|
|
for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
|
|
TopoDS_Shape aLocalEdge = E2.Reversed();
|
|
if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
|
|
else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
|
|
F,fl2[0],fl2[1]);
|
|
// if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
|
|
// else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
|
|
// F,fl2[0],fl2[1]);
|
|
#ifdef OCCT_DEBUG
|
|
if (C1.IsNull() || C2.IsNull()) {
|
|
std::cout <<"Inter2d : Pas de pcurve"<<std::endl;
|
|
#ifdef DRAW
|
|
DBRep::Set("E1",E1);
|
|
DBRep::Set("E2",E2);
|
|
DBRep::Set("F",F);
|
|
#endif
|
|
return;
|
|
}
|
|
#endif
|
|
Standard_Real U1 = 0.,U2 = 0.;
|
|
gp_Pnt2d P2d;
|
|
Standard_Boolean aCurrentFind = Standard_False;
|
|
if (itry == 1) {
|
|
fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
|
|
fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
|
|
}
|
|
Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
|
|
Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
|
|
|
|
if (itry == 0) {
|
|
gp_Pnt2d P1[2],P2[2];
|
|
P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
|
|
P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
|
|
|
|
Standard_Integer i1 ;
|
|
for ( i1 = 0; i1 < 2; i1++) {
|
|
for (Standard_Integer i2 = 0; i2 < 2; i2++) {
|
|
if (Abs(fl1[i1]) < Precision::Infinite() &&
|
|
Abs(fl2[i2]) < Precision::Infinite() ) {
|
|
if (P1[i1].IsEqual(P2[i2],TolConf)) {
|
|
YaSol = Standard_True;
|
|
aCurrentFind = Standard_True;
|
|
U1 = fl1[i1]; U2 = fl2[i2];
|
|
P2d = C1->Value(U1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!YaSol)
|
|
for (i1 = 0; i1 < 2; i1++)
|
|
{
|
|
Extrema_ExtPC2d extr( P1[i1], AC2 );
|
|
if (extr.IsDone() && extr.NbExt() > 0)
|
|
{
|
|
Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
|
|
Standard_Integer IndexMin = 1;
|
|
for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
|
|
{
|
|
Dist2 = extr.SquareDistance(ind);
|
|
if (Dist2 < Dist2Min)
|
|
{
|
|
Dist2Min = Dist2;
|
|
IndexMin = ind;
|
|
}
|
|
}
|
|
if (Dist2Min <= Precision::SquareConfusion())
|
|
{
|
|
YaSol = Standard_True;
|
|
aCurrentFind = Standard_True;
|
|
P2d = P1[i1];
|
|
U1 = fl1[i1];
|
|
U2 = (extr.Point(IndexMin)).Parameter();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!YaSol)
|
|
for (Standard_Integer i2 = 0; i2 < 2; i2++)
|
|
{
|
|
Extrema_ExtPC2d extr( P2[i2], AC1 );
|
|
if (extr.IsDone() && extr.NbExt() > 0)
|
|
{
|
|
Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
|
|
Standard_Integer IndexMin = 1;
|
|
for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
|
|
{
|
|
Dist2 = extr.SquareDistance(ind);
|
|
if (Dist2 < Dist2Min)
|
|
{
|
|
Dist2Min = Dist2;
|
|
IndexMin = ind;
|
|
}
|
|
}
|
|
if (Dist2Min <= Precision::SquareConfusion())
|
|
{
|
|
YaSol = Standard_True;
|
|
aCurrentFind = Standard_True;
|
|
P2d = P2[i2];
|
|
U2 = fl2[i2];
|
|
U1 = (extr.Point(IndexMin)).Parameter();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!YaSol) {
|
|
Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
|
|
|
|
if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
|
|
YaSol = Standard_True;
|
|
aCurrentFind = Standard_True;
|
|
U1 = Inter.Point(1).ParamOnFirst();
|
|
U2 = Inter.Point(1).ParamOnSecond();
|
|
P2d = Inter.Point(1).Value();
|
|
}
|
|
else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
|
|
YaSol = Standard_True;
|
|
aCurrentFind = Standard_True;
|
|
IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
|
|
IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
|
|
IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
|
|
Standard_Real U1on1 = IntP1.ParamOnFirst();
|
|
Standard_Real U1on2 = IntP2.ParamOnFirst();
|
|
Standard_Real U2on1 = IntP1.ParamOnSecond();
|
|
Standard_Real U2on2 = IntP2.ParamOnSecond();
|
|
#ifdef OCCT_DEBUG
|
|
std::cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << std::endl;
|
|
std::cout << " ===> Parametres sur Curve1 : ";
|
|
std::cout << U1on1 << " " << U1on2 << std::endl;
|
|
std::cout << " ===> Parametres sur Curve2 : ";
|
|
std::cout << U2on1 << " " << U2on2 << std::endl;
|
|
#endif
|
|
U1 = (U1on1 + U1on2)/2.;
|
|
U2 = (U2on1 + U2on2)/2.;
|
|
gp_Pnt2d P2d1 = C1->Value(U1);
|
|
gp_Pnt2d P2d2 = C2->Value(U2);
|
|
P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
|
|
P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
|
|
}
|
|
}
|
|
if (aCurrentFind) {
|
|
gp_Pnt P = S->Value(P2d.X(),P2d.Y());
|
|
TopoDS_Vertex V = BRepLib_MakeVertex(P);
|
|
V.Orientation(TopAbs_INTERNAL);
|
|
TopoDS_Shape aLocalEdgeOrientedE1 = E1.Oriented(TopAbs_FORWARD);
|
|
B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
|
|
aLocalEdgeOrientedE1 = E2.Oriented(TopAbs_FORWARD);
|
|
B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
|
|
// B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
|
|
// B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
|
|
LV.Append(V);
|
|
}
|
|
}
|
|
}
|
|
itry++;
|
|
}
|
|
|
|
if (LV.Extent() > 1) {
|
|
//------------------------------------------------
|
|
// garde seulement les vertex les plus proches du
|
|
//debut et de la fin.
|
|
//------------------------------------------------
|
|
TopTools_ListIteratorOfListOfShape it(LV);
|
|
TopoDS_Vertex VF,VL;
|
|
Standard_Real UMin = Precision::Infinite();
|
|
Standard_Real UMax = -Precision::Infinite();
|
|
Standard_Real U;
|
|
|
|
for ( ; it.More(); it.Next()) {
|
|
TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
|
|
TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
|
|
U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
|
|
// U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
|
|
if ( U < UMin) {
|
|
VF = CV; UMin = U;
|
|
}
|
|
if ( U > UMax) {
|
|
VL = CV; UMax = U;
|
|
}
|
|
}
|
|
LV.Clear();LV.Append(VF); LV.Append(VL);
|
|
}
|
|
|
|
#ifdef OCCT_DEBUG
|
|
if (!YaSol) {
|
|
std::cout <<"Inter2d : Pas de solution"<<std::endl;
|
|
#ifdef DRAW
|
|
DBRep::Set("E1",E1);
|
|
DBRep::Set("E2",E2);
|
|
DBRep::Set("F",F);
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SelectEdge
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static void SelectEdge (const TopoDS_Face& /*F*/,
|
|
const TopoDS_Face& /*EF*/,
|
|
const TopoDS_Edge& E,
|
|
TopTools_ListOfShape& LInt)
|
|
{
|
|
//------------------------------------------------------------
|
|
// detrompeur sur les intersections sur les faces periodiques
|
|
//------------------------------------------------------------
|
|
TopTools_ListIteratorOfListOfShape it(LInt);
|
|
Standard_Real dU = 1.0e100;
|
|
TopoDS_Edge GE;
|
|
|
|
Standard_Real Fst, Lst, tmp;
|
|
BRep_Tool::Range(E, Fst, Lst);
|
|
BRepAdaptor_Curve Ad1(E);
|
|
|
|
gp_Pnt PFirst = Ad1.Value( Fst );
|
|
gp_Pnt PLast = Ad1.Value( Lst );
|
|
|
|
//----------------------------------------------------------------------
|
|
// Selection de l edge qui couvre le plus le domaine de l edge initiale.
|
|
//----------------------------------------------------------------------
|
|
for (; it.More(); it.Next()) {
|
|
const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
|
|
|
|
BRep_Tool::Range(EI, Fst, Lst);
|
|
BRepAdaptor_Curve Ad2(EI);
|
|
gp_Pnt P1 = Ad2.Value(Fst);
|
|
gp_Pnt P2 = Ad2.Value(Lst);
|
|
|
|
tmp = P1.Distance(PFirst) + P2.Distance(PLast);
|
|
if( tmp <= dU ) {
|
|
dU = tmp;
|
|
GE = EI;
|
|
}
|
|
|
|
}
|
|
LInt.Clear();
|
|
LInt.Append(GE);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Init
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static void MakeFace(const Handle(Geom_Surface)& S,
|
|
const Standard_Real Um,
|
|
const Standard_Real UM,
|
|
const Standard_Real Vm,
|
|
const Standard_Real VM,
|
|
const Standard_Boolean uclosed,
|
|
const Standard_Boolean vclosed,
|
|
const Standard_Boolean isVminDegen,
|
|
const Standard_Boolean isVmaxDegen,
|
|
TopoDS_Face& F)
|
|
{
|
|
Standard_Real UMin = Um;
|
|
Standard_Real UMax = UM;
|
|
Standard_Real VMin = Vm;
|
|
Standard_Real VMax = VM;
|
|
|
|
// compute infinite flags
|
|
Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
|
|
Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
|
|
Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
|
|
Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
|
|
|
|
// degenerated flags (for cones)
|
|
Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
|
|
Handle(Geom_Surface) theSurf = S;
|
|
if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
|
|
theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
|
|
if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
|
|
{
|
|
Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
|
|
gp_Cone theCone = ConicalS->Cone();
|
|
gp_Pnt theApex = theCone.Apex();
|
|
Standard_Real Uapex, Vapex;
|
|
ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
|
|
if (Abs(VMin - Vapex) <= Precision::Confusion())
|
|
vmindegen = Standard_True;
|
|
if (Abs(VMax - Vapex) <= Precision::Confusion())
|
|
vmaxdegen = Standard_True;
|
|
}
|
|
|
|
// compute vertices
|
|
BRep_Builder B;
|
|
Standard_Real tol = Precision::Confusion();
|
|
|
|
TopoDS_Vertex V00,V10,V11,V01;
|
|
|
|
if (!umininf) {
|
|
if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
|
|
if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
|
|
}
|
|
if (!umaxinf) {
|
|
if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
|
|
if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
|
|
}
|
|
|
|
if (uclosed) {
|
|
V10 = V00;
|
|
V11 = V01;
|
|
}
|
|
|
|
if (vclosed) {
|
|
V01 = V00;
|
|
V11 = V10;
|
|
}
|
|
|
|
if (vmindegen)
|
|
V10 = V00;
|
|
if (vmaxdegen)
|
|
V11 = V01;
|
|
|
|
// make the lines
|
|
Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
|
|
if (!umininf)
|
|
Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
|
|
if (!umaxinf)
|
|
Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
|
|
if (!vmininf)
|
|
Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
|
|
if (!vmaxinf)
|
|
Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
|
|
|
|
Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
|
|
Standard_Real TolApex = 1.e-5;
|
|
//Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
|
|
Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
|
|
if (hasiso) {
|
|
if (!umininf)
|
|
Cumin = S->UIso(UMin);
|
|
if (!umaxinf)
|
|
Cumax = S->UIso(UMax);
|
|
if (!vmininf)
|
|
{
|
|
Cvmin = S->VIso(VMin);
|
|
if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
|
|
vmindegen = Standard_True;
|
|
}
|
|
if (!vmaxinf)
|
|
{
|
|
Cvmax = S->VIso(VMax);
|
|
if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
|
|
vmaxdegen = Standard_True;
|
|
}
|
|
}
|
|
|
|
// make the face
|
|
B.MakeFace(F,S,tol);
|
|
|
|
// make the edges
|
|
TopoDS_Edge eumin,eumax,evmin,evmax;
|
|
|
|
if (!umininf) {
|
|
if (hasiso)
|
|
B.MakeEdge(eumin,Cumin,tol);
|
|
else
|
|
B.MakeEdge(eumin);
|
|
if (uclosed)
|
|
B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
|
|
else
|
|
B.UpdateEdge(eumin,Lumin,F,tol);
|
|
if (!vmininf) {
|
|
V00.Orientation(TopAbs_FORWARD);
|
|
B.Add(eumin,V00);
|
|
}
|
|
if (!vmaxinf) {
|
|
V01.Orientation(TopAbs_REVERSED);
|
|
B.Add(eumin,V01);
|
|
}
|
|
B.Range(eumin,VMin,VMax);
|
|
}
|
|
|
|
if (!umaxinf) {
|
|
if (uclosed)
|
|
eumax = eumin;
|
|
else {
|
|
if (hasiso)
|
|
B.MakeEdge(eumax,Cumax,tol);
|
|
else
|
|
B.MakeEdge(eumax);
|
|
B.UpdateEdge(eumax,Lumax,F,tol);
|
|
if (!vmininf) {
|
|
V10.Orientation(TopAbs_FORWARD);
|
|
B.Add(eumax,V10);
|
|
}
|
|
if (!vmaxinf) {
|
|
V11.Orientation(TopAbs_REVERSED);
|
|
B.Add(eumax,V11);
|
|
}
|
|
B.Range(eumax,VMin,VMax);
|
|
}
|
|
}
|
|
|
|
if (!vmininf) {
|
|
if (hasiso && !vmindegen)
|
|
B.MakeEdge(evmin,Cvmin,tol);
|
|
else
|
|
B.MakeEdge(evmin);
|
|
if (vclosed)
|
|
B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
|
|
else
|
|
B.UpdateEdge(evmin,Lvmin,F,tol);
|
|
if (!umininf) {
|
|
V00.Orientation(TopAbs_FORWARD);
|
|
B.Add(evmin,V00);
|
|
}
|
|
if (!umaxinf) {
|
|
V10.Orientation(TopAbs_REVERSED);
|
|
B.Add(evmin,V10);
|
|
}
|
|
B.Range(evmin,UMin,UMax);
|
|
if (vmindegen)
|
|
B.Degenerated(evmin, Standard_True);
|
|
}
|
|
|
|
if (!vmaxinf) {
|
|
if (vclosed)
|
|
evmax = evmin;
|
|
else {
|
|
if (hasiso && !vmaxdegen)
|
|
B.MakeEdge(evmax,Cvmax,tol);
|
|
else
|
|
B.MakeEdge(evmax);
|
|
B.UpdateEdge(evmax,Lvmax,F,tol);
|
|
if (!umininf) {
|
|
V01.Orientation(TopAbs_FORWARD);
|
|
B.Add(evmax,V01);
|
|
}
|
|
if (!umaxinf) {
|
|
V11.Orientation(TopAbs_REVERSED);
|
|
B.Add(evmax,V11);
|
|
}
|
|
B.Range(evmax,UMin,UMax);
|
|
if (vmaxdegen)
|
|
B.Degenerated(evmax, Standard_True);
|
|
}
|
|
}
|
|
|
|
// make the wires and add them to the face
|
|
eumin.Orientation(TopAbs_REVERSED);
|
|
evmax.Orientation(TopAbs_REVERSED);
|
|
|
|
TopoDS_Wire W;
|
|
|
|
if (!umininf && !umaxinf && vmininf && vmaxinf) {
|
|
// two wires in u
|
|
B.MakeWire(W);
|
|
B.Add(W,eumin);
|
|
B.Add(F,W);
|
|
B.MakeWire(W);
|
|
B.Add(W,eumax);
|
|
B.Add(F,W);
|
|
F.Closed(uclosed);
|
|
}
|
|
|
|
else if (umininf && umaxinf && !vmininf && !vmaxinf) {
|
|
// two wires in v
|
|
B.MakeWire(W);
|
|
B.Add(W,evmin);
|
|
B.Add(F,W);
|
|
B.MakeWire(W);
|
|
B.Add(W,evmax);
|
|
B.Add(F,W);
|
|
F.Closed(vclosed);
|
|
}
|
|
|
|
else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
|
|
// one wire
|
|
B.MakeWire(W);
|
|
if (!umininf) B.Add(W,eumin);
|
|
if (!vmininf) B.Add(W,evmin);
|
|
if (!umaxinf) B.Add(W,eumax);
|
|
if (!vmaxinf) B.Add(W,evmax);
|
|
B.Add(F,W);
|
|
W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
|
|
F.Closed(uclosed && vclosed);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : EnLargeGeometry
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
|
|
Standard_Real& U1,
|
|
Standard_Real& U2,
|
|
Standard_Real& V1,
|
|
Standard_Real& V2,
|
|
Standard_Boolean& IsV1degen,
|
|
Standard_Boolean& IsV2degen,
|
|
const Standard_Real uf1,
|
|
const Standard_Real uf2,
|
|
const Standard_Real vf1,
|
|
const Standard_Real vf2,
|
|
const Standard_Real coeff,
|
|
const Standard_Boolean theGlobalEnlargeU,
|
|
const Standard_Boolean theGlobalEnlargeVfirst,
|
|
const Standard_Boolean theGlobalEnlargeVlast,
|
|
const Standard_Real theLenBeforeUfirst,
|
|
const Standard_Real theLenAfterUlast,
|
|
const Standard_Real theLenBeforeVfirst,
|
|
const Standard_Real theLenAfterVlast)
|
|
{
|
|
const Standard_Real TolApex = 1.e-5;
|
|
|
|
Standard_Boolean SurfaceChange = Standard_False;
|
|
if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
|
|
Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
|
|
EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
|
|
uf1,uf2,vf1,vf2,coeff,
|
|
theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
|
|
theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
|
|
if (!theGlobalEnlargeVfirst)
|
|
V1 = vf1;
|
|
if (!theGlobalEnlargeVlast)
|
|
V2 = vf2;
|
|
if (!theGlobalEnlargeVfirst || !theGlobalEnlargeVlast)
|
|
//Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->SetTrim( U1, U2, V1, V2 );
|
|
S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
|
|
else
|
|
S = BS;
|
|
SurfaceChange = Standard_True;
|
|
}
|
|
else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
|
|
Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface();
|
|
SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
|
|
uf1,uf2,vf1,vf2,coeff,
|
|
theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
|
|
theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
|
|
Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
|
|
}
|
|
else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
|
|
S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
|
|
{
|
|
Standard_Real du_first = 0., du_last = 0.,
|
|
dv_first = 0., dv_last = 0.;
|
|
Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
|
|
Standard_Real u1, u2, v1, v2;
|
|
Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
|
|
Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
|
|
Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
|
|
S->Bounds( u1, u2, v1, v2 );
|
|
if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
|
|
{
|
|
du_first = du_last = uf2-uf1;
|
|
u1 = uf1 - du_first;
|
|
u2 = uf2 + du_last;
|
|
enlargeU = Standard_False;
|
|
}
|
|
else if (S->IsUClosed())
|
|
enlargeU = Standard_False;
|
|
else
|
|
{
|
|
viso = S->VIso( vf1 );
|
|
GeomAdaptor_Curve gac( viso );
|
|
Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
|
|
du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
|
|
du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
|
|
uiso1 = S->UIso( uf1 );
|
|
uiso2 = S->UIso( uf2 );
|
|
if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
|
|
enlargeUfirst = Standard_False;
|
|
if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
|
|
enlargeUlast = Standard_False;
|
|
}
|
|
if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
|
|
{
|
|
dv_first = dv_last = vf2-vf1;
|
|
v1 = vf1 - dv_first;
|
|
v2 = vf2 + dv_last;
|
|
enlargeV = Standard_False;
|
|
}
|
|
else if (S->IsVClosed())
|
|
enlargeV = Standard_False;
|
|
else
|
|
{
|
|
uiso = S->UIso( uf1 );
|
|
GeomAdaptor_Curve gac( uiso );
|
|
Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
|
|
dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
|
|
dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
|
|
viso1 = S->VIso( vf1 );
|
|
viso2 = S->VIso( vf2 );
|
|
if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
|
|
{
|
|
enlargeVfirst = Standard_False;
|
|
IsV1degen = Standard_True;
|
|
}
|
|
if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
|
|
{
|
|
enlargeVlast = Standard_False;
|
|
IsV2degen = Standard_True;
|
|
}
|
|
}
|
|
Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
|
|
if (enlargeU)
|
|
{
|
|
if (enlargeUfirst && du_first != 0.)
|
|
GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
|
|
if (enlargeUlast && du_last != 0.)
|
|
GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
|
|
}
|
|
if (enlargeV)
|
|
{
|
|
if (enlargeVfirst && dv_first != 0.)
|
|
GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
|
|
if (enlargeVlast && dv_last != 0.)
|
|
GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
|
|
}
|
|
S = aSurf;
|
|
S->Bounds( U1, U2, V1, V2 );
|
|
SurfaceChange = Standard_True;
|
|
}
|
|
else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
|
|
S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
|
|
{
|
|
Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
|
|
Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
|
|
Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
|
|
if (S->IsUClosed())
|
|
enlargeU = Standard_False;
|
|
if (S->IsVClosed())
|
|
enlargeV = Standard_False;
|
|
|
|
Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
|
|
Standard_Real u1, u2, v1, v2;
|
|
S->Bounds( u1, u2, v1, v2 );
|
|
|
|
Standard_Real du_first = 0., du_last = 0.,
|
|
dv_first = 0., dv_last = 0.;
|
|
Handle( Geom_Curve ) uiso1, uiso2, viso1, viso2;
|
|
Standard_Real gabarit_uiso1, gabarit_uiso2, gabarit_viso1, gabarit_viso2;
|
|
|
|
uiso1 = S->UIso( u1 );
|
|
uiso2 = S->UIso( u2 );
|
|
viso1 = S->VIso( v1 );
|
|
viso2 = S->VIso( v2 );
|
|
gabarit_uiso1 = BRepOffset_Tool::Gabarit( uiso1 );
|
|
gabarit_uiso2 = BRepOffset_Tool::Gabarit( uiso2 );
|
|
gabarit_viso1 = BRepOffset_Tool::Gabarit( viso1 );
|
|
gabarit_viso2 = BRepOffset_Tool::Gabarit( viso2 );
|
|
if (gabarit_viso1 <= TolApex ||
|
|
gabarit_viso2 <= TolApex)
|
|
enlargeU = Standard_False;
|
|
if (gabarit_uiso1 <= TolApex ||
|
|
gabarit_uiso2 <= TolApex)
|
|
enlargeV = Standard_False;
|
|
|
|
GeomAdaptor_Curve gac;
|
|
if (enlargeU)
|
|
{
|
|
gac.Load( viso1 );
|
|
Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
|
|
du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
|
|
du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
|
|
if (gabarit_uiso1 <= TolApex)
|
|
enlargeUfirst = Standard_False;
|
|
if (gabarit_uiso2 <= TolApex)
|
|
enlargeUlast = Standard_False;
|
|
}
|
|
if (enlargeV)
|
|
{
|
|
gac.Load( uiso1 );
|
|
Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
|
|
dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
|
|
dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
|
|
if (gabarit_viso1 <= TolApex)
|
|
{
|
|
enlargeVfirst = Standard_False;
|
|
IsV1degen = Standard_True;
|
|
}
|
|
if (gabarit_viso2 <= TolApex)
|
|
{
|
|
enlargeVlast = Standard_False;
|
|
IsV2degen = Standard_True;
|
|
}
|
|
}
|
|
|
|
Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
|
|
if (enlargeU)
|
|
{
|
|
if (enlargeUfirst && uf1-u1 < duf && du_first != 0.)
|
|
GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
|
|
if (enlargeUlast && u2-uf2 < duf && du_last != 0.)
|
|
GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
|
|
}
|
|
if (enlargeV)
|
|
{
|
|
if (enlargeVfirst && vf1-v1 < dvf && dv_first != 0.)
|
|
GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
|
|
if (enlargeVlast && v2-vf2 < dvf && dv_last != 0.)
|
|
GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
|
|
}
|
|
S = aSurf;
|
|
|
|
S->Bounds( U1, U2, V1, V2 );
|
|
SurfaceChange = Standard_True;
|
|
}
|
|
else {
|
|
Standard_Real UU1,UU2,VV1,VV2;
|
|
S->Bounds(UU1,UU2,VV1,VV2);
|
|
// Pas d extension au dela des bornes de la surface.
|
|
U1 = Max(UU1,U1);
|
|
V1 = Max(VV1,V1);
|
|
U2 = Min(UU2,U2);
|
|
V2 = Min(VV2,V2);
|
|
}
|
|
return SurfaceChange;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : UpDatePCurve
|
|
//purpose : Mise a jour des pcurves de F sur la surface de de BF.
|
|
// F and BF has to be FORWARD,
|
|
//=======================================================================
|
|
|
|
static void UpdatePCurves (const TopoDS_Face& F,
|
|
TopoDS_Face& BF)
|
|
{
|
|
Standard_Real f,l;
|
|
Standard_Integer i;
|
|
BRep_Builder B;
|
|
TopTools_IndexedMapOfShape Emap;
|
|
Handle(Geom2d_Curve) NullPCurve;
|
|
|
|
TopExp::MapShapes( F, TopAbs_EDGE, Emap );
|
|
|
|
for (i = 1; i <= Emap.Extent(); i++)
|
|
{
|
|
TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
|
|
CE.Orientation( TopAbs_FORWARD );
|
|
Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
|
|
if (!C2.IsNull())
|
|
{
|
|
if (BRep_Tool::IsClosed( CE, F ))
|
|
{
|
|
CE.Reverse();
|
|
Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
|
|
B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
|
|
B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
|
|
}
|
|
else
|
|
{
|
|
B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
|
|
B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
|
|
}
|
|
|
|
B.Range(CE,f,l);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function :CompactUVBounds
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static void CompactUVBounds (const TopoDS_Face& F,
|
|
Standard_Real& UMin,
|
|
Standard_Real& UMax,
|
|
Standard_Real& VMin,
|
|
Standard_Real& VMax)
|
|
{
|
|
// Calcul serre pour que les bornes ne couvrent pas plus d une periode
|
|
Standard_Real U1,U2;
|
|
Standard_Real N = 33;
|
|
Bnd_Box2d B;
|
|
|
|
TopExp_Explorer exp;
|
|
for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
|
|
const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
|
|
BRepAdaptor_Curve2d C(E,F);
|
|
BRep_Tool::Range(E,U1,U2);
|
|
gp_Pnt2d P;
|
|
Standard_Real U = U1;
|
|
Standard_Real DU = (U2-U1)/(N-1);
|
|
for (Standard_Integer j=1;j<N;j++) {
|
|
C.D0(U,P);
|
|
U+=DU;
|
|
B.Add(P);
|
|
}
|
|
C.D0(U2,P);
|
|
B.Add(P);
|
|
}
|
|
|
|
if (!B.IsVoid())
|
|
B.Get(UMin,VMin,UMax,VMax);
|
|
else
|
|
BRep_Tool::Surface(F)->Bounds (UMin, UMax, VMin, VMax);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CheckBounds
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
|
|
const BRepOffset_Analyse& Analyse,
|
|
Standard_Boolean& enlargeU,
|
|
Standard_Boolean& enlargeVfirst,
|
|
Standard_Boolean& enlargeVlast)
|
|
{
|
|
enlargeU = Standard_True;
|
|
enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
|
|
|
|
Standard_Integer Ubound = 0, Vbound = 0;
|
|
Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
|
|
Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
|
|
|
|
Standard_Real UF1,UF2,VF1,VF2;
|
|
CompactUVBounds(F,UF1,UF2,VF1,VF2);
|
|
|
|
Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
|
|
if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
|
|
theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (theSurf)->BasisSurface();
|
|
|
|
if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
|
|
theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
|
|
theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
|
|
theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
|
|
{
|
|
TopExp_Explorer Explo(F, TopAbs_EDGE);
|
|
for (; Explo.More(); Explo.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
|
|
const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
|
|
if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
|
|
{
|
|
ChFiDS_TypeOfConcavity OT = L.First().Type();
|
|
if (OT == ChFiDS_Tangential || BRep_Tool::Degenerated(anEdge))
|
|
{
|
|
Standard_Real fpar, lpar;
|
|
Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
|
|
if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
|
|
aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve)->BasisCurve();
|
|
|
|
Handle(Geom2d_Line) theLine;
|
|
if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
|
|
theLine = Handle(Geom2d_Line)::DownCast (aCurve);
|
|
else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
|
|
aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
|
|
{
|
|
Standard_Real newFpar, newLpar, deviation;
|
|
theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
|
|
newFpar, newLpar, deviation);
|
|
}
|
|
|
|
if (!theLine.IsNull())
|
|
{
|
|
gp_Dir2d theDir = theLine->Direction();
|
|
if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
|
|
{
|
|
Vbound++;
|
|
if (BRep_Tool::Degenerated(anEdge))
|
|
{
|
|
if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
|
|
enlargeVfirst = Standard_False;
|
|
else //theLine->Location().Y() is near VF2
|
|
enlargeVlast = Standard_False;
|
|
}
|
|
else
|
|
{
|
|
if (theLine->Location().Y() < Vfirst)
|
|
Vfirst = theLine->Location().Y();
|
|
if (theLine->Location().Y() > Vlast)
|
|
Vlast = theLine->Location().Y();
|
|
}
|
|
}
|
|
else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
|
|
{
|
|
Ubound++;
|
|
if (theLine->Location().X() < Ufirst)
|
|
Ufirst = theLine->Location().X();
|
|
if (theLine->Location().X() > Ulast)
|
|
Ulast = theLine->Location().X();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Ubound >= 2 || Vbound >= 2)
|
|
{
|
|
if (Ubound >= 2 &&
|
|
Abs(UF1-Ufirst) <= Precision::Confusion() &&
|
|
Abs(UF2-Ulast) <= Precision::Confusion())
|
|
enlargeU = Standard_False;
|
|
if (Vbound >= 2 &&
|
|
Abs(VF1-Vfirst) <= Precision::Confusion() &&
|
|
Abs(VF2-Vlast) <= Precision::Confusion())
|
|
{
|
|
enlargeVfirst = Standard_False;
|
|
enlargeVlast = Standard_False;
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : EnLargeFace
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BRepOffset_Tool::EnLargeFace
|
|
(const TopoDS_Face& F,
|
|
TopoDS_Face& BF,
|
|
const Standard_Boolean CanExtentSurface,
|
|
const Standard_Boolean UpdatePCurve,
|
|
const Standard_Boolean theEnlargeU,
|
|
const Standard_Boolean theEnlargeVfirst,
|
|
const Standard_Boolean theEnlargeVlast,
|
|
const Standard_Integer theExtensionMode,
|
|
const Standard_Real theLenBeforeUfirst,
|
|
const Standard_Real theLenAfterUlast,
|
|
const Standard_Real theLenBeforeVfirst,
|
|
const Standard_Real theLenAfterVlast)
|
|
{
|
|
//---------------------------
|
|
// extension de la geometrie.
|
|
//---------------------------
|
|
TopLoc_Location L;
|
|
Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
|
|
Standard_Real UU1,VV1,UU2,VV2;
|
|
Standard_Boolean uperiodic = Standard_False, vperiodic = Standard_False;
|
|
Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
|
|
Standard_Real US1,VS1,US2,VS2;
|
|
Standard_Real UF1,VF1,UF2,VF2;
|
|
Standard_Boolean SurfaceChange = Standard_False;
|
|
|
|
if (S->IsUPeriodic() || S->IsVPeriodic()) {
|
|
// Calcul serre pour que les bornes ne couvre pas plus d une periode
|
|
CompactUVBounds(F,UF1,UF2,VF1,VF2);
|
|
}
|
|
else {
|
|
BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
|
|
}
|
|
|
|
S->Bounds (US1,US2,VS1,VS2);
|
|
Standard_Real coeff;
|
|
if (theExtensionMode == 1)
|
|
{
|
|
UU1 = VV1 = - TheInfini;
|
|
UU2 = VV2 = TheInfini;
|
|
coeff = 0.25;
|
|
}
|
|
else
|
|
{
|
|
Standard_Real FaceDU = UF2 - UF1;
|
|
Standard_Real FaceDV = VF2 - VF1;
|
|
UU1 = UF1 - 10*FaceDU;
|
|
UU2 = UF2 + 10*FaceDU;
|
|
VV1 = VF1 - 10*FaceDV;
|
|
VV2 = VF2 + 10*FaceDV;
|
|
coeff = 1.;
|
|
}
|
|
|
|
if (CanExtentSurface) {
|
|
SurfaceChange = EnlargeGeometry(S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, coeff,
|
|
theEnlargeU, theEnlargeVfirst, theEnlargeVlast,
|
|
theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
|
|
}
|
|
else {
|
|
UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
|
|
VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
|
|
}
|
|
|
|
if (S->IsUPeriodic()) {
|
|
uperiodic = Standard_True;
|
|
Standard_Real Period = S->UPeriod();
|
|
Standard_Real Delta = Period - (UF2 - UF1);
|
|
Standard_Real alpha = 0.1;
|
|
UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
|
|
if ((UU2 - UU1) > Period) {
|
|
UU2 = UU1 + Period;
|
|
}
|
|
}
|
|
if (S->IsVPeriodic()) {
|
|
vperiodic = Standard_True;
|
|
Standard_Real Period = S->VPeriod();
|
|
Standard_Real Delta = Period - (VF2 - VF1);
|
|
Standard_Real alpha = 0.1;
|
|
VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
|
|
if ((VV2 - VV1) > Period) {
|
|
VV2 = VV1 + Period;
|
|
}
|
|
}
|
|
|
|
//Special treatment for conical surfaces
|
|
Handle(Geom_Surface) theSurf = S;
|
|
if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
|
|
theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
|
|
if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
|
|
{
|
|
Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
|
|
gp_Cone theCone = ConicalS->Cone();
|
|
gp_Pnt theApex = theCone.Apex();
|
|
Standard_Real Uapex, Vapex;
|
|
ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
|
|
if (VV1 < Vapex && Vapex < VV2)
|
|
{
|
|
//consider that VF1 and VF2 are on the same side from apex
|
|
Standard_Real TolApex = 1.e-5;
|
|
if (Vapex - VF1 >= TolApex ||
|
|
Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
|
|
VV2 = Vapex;
|
|
else
|
|
VV1 = Vapex;
|
|
}
|
|
}
|
|
|
|
if (!theEnlargeU)
|
|
{
|
|
UU1 = UF1; UU2 = UF2;
|
|
}
|
|
if (!theEnlargeVfirst)
|
|
VV1 = VF1;
|
|
if (!theEnlargeVlast)
|
|
VV2 = VF2;
|
|
|
|
//Detect closedness in U and V directions
|
|
Standard_Boolean uclosed = Standard_False, vclosed = Standard_False;
|
|
BRepTools::DetectClosedness(F, uclosed, vclosed);
|
|
if (uclosed && !uperiodic &&
|
|
(theLenBeforeUfirst != 0. || theLenAfterUlast != 0.))
|
|
uclosed = Standard_False;
|
|
if (vclosed && !vperiodic &&
|
|
(theLenBeforeVfirst != 0. && theLenAfterVlast != 0.))
|
|
vclosed = Standard_False;
|
|
|
|
MakeFace(S,UU1,UU2,VV1,VV2,uclosed,vclosed,isVV1degen,isVV2degen,BF);
|
|
BF.Location(L);
|
|
/*
|
|
if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
|
|
BRep_Builder B;
|
|
//----------------------------------------------------------------
|
|
// utile pour les bouchons on ne doit pas changer leur geometrie.
|
|
// (Ce que fait BRepLib_MakeFace si S est restreinte).
|
|
// On remet S et on update les pcurves.
|
|
//----------------------------------------------------------------
|
|
TopExp_Explorer exp;
|
|
exp.Init(BF,TopAbs_EDGE);
|
|
Standard_Real f=0.,l=0.;
|
|
for (; exp.More(); exp.Next()) {
|
|
TopoDS_Edge CE = TopoDS::Edge(exp.Current());
|
|
Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
|
|
B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
|
|
}
|
|
B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
|
|
}
|
|
*/
|
|
if (SurfaceChange && UpdatePCurve) {
|
|
TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
|
|
UpdatePCurves(TopoDS::Face(aLocalFace),BF);
|
|
//UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
|
|
BRep_Builder BB;
|
|
BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
|
|
}
|
|
|
|
BF.Orientation(F.Orientation());
|
|
return SurfaceChange;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : TryParameter
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
|
|
TopoDS_Vertex& V,
|
|
const TopoDS_Edge& NE,
|
|
Standard_Real TolConf)
|
|
{
|
|
BRepAdaptor_Curve OC(OE);
|
|
BRepAdaptor_Curve NC(NE);
|
|
Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
|
|
Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
|
|
Standard_Real U = 0.;
|
|
gp_Pnt P = BRep_Tool::Pnt(V);
|
|
Standard_Boolean OK = Standard_False;
|
|
|
|
if (P.Distance(OC.Value(Of)) < TolConf) {
|
|
if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
|
|
OK = Standard_True;
|
|
U = Of;
|
|
}
|
|
}
|
|
if (P.Distance(OC.Value(Ol)) < TolConf) {
|
|
if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
|
|
OK = Standard_True;
|
|
U = Ol;
|
|
}
|
|
}
|
|
if (OK) {
|
|
BRep_Builder B;
|
|
TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
|
|
TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
|
|
// TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
|
|
aLocalShape = V.Oriented(TopAbs_INTERNAL);
|
|
B.UpdateVertex(TopoDS::Vertex(aLocalShape),
|
|
U,NE,BRep_Tool::Tolerance(NE));
|
|
// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
|
|
// U,NE,BRep_Tool::Tolerance(NE));
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function :
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
|
|
TopTools_DataMapOfShapeListOfShape& MEV)
|
|
{
|
|
TopExp_Explorer exp;
|
|
exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
|
|
TopTools_MapOfShape DejaVu;
|
|
for ( ; exp.More(); exp.Next()) {
|
|
const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
|
|
if (DejaVu.Add(E)) {
|
|
TopoDS_Vertex V1,V2;
|
|
TopExp::Vertices (E,V1,V2);
|
|
if (!MEV.IsBound(V1)) {
|
|
TopTools_ListOfShape empty;
|
|
MEV.Bind(V1,empty);
|
|
}
|
|
MEV(V1).Append(E);
|
|
if (!V1.IsSame(V2)) {
|
|
if (!MEV.IsBound(V2)) {
|
|
TopTools_ListOfShape empty;
|
|
MEV.Bind(V2,empty);
|
|
}
|
|
MEV(V2).Append(E);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function :
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
|
|
const TopoDS_Face& F,
|
|
TopTools_DataMapOfShapeShape& NOnV1,
|
|
TopTools_DataMapOfShapeShape& NOnV2)
|
|
{
|
|
TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
|
|
TopoDS_Edge CurE,FirstE,PrecE;
|
|
BRepTools_WireExplorer wexp;
|
|
|
|
TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
|
|
TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
|
|
wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
|
|
// wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
|
|
// TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
|
|
CurE = FirstE = PrecE = wexp.Current();
|
|
TopExp::Vertices(CurE,V1,V2);
|
|
FV1 = VP1 = V1; FV2 = VP2 = V2;
|
|
wexp.Next();
|
|
while (wexp.More()) {
|
|
CurE = wexp.Current();
|
|
TopExp::Vertices(CurE,V1,V2);
|
|
if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
|
|
if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
|
|
if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
|
|
if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
|
|
PrecE = CurE;
|
|
VP1 = V1; VP2 = V2;
|
|
wexp.Next();
|
|
}
|
|
if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
|
|
if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
|
|
if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
|
|
if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ExtentFace
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
|
|
TopTools_DataMapOfShapeShape& ConstShapes,
|
|
TopTools_DataMapOfShapeShape& ToBuild,
|
|
const TopAbs_State Side,
|
|
const Standard_Real TolConf,
|
|
TopoDS_Face& NF)
|
|
{
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"FTE_%d",NbFTE++);
|
|
DBRep::Set(name,F);
|
|
}
|
|
#endif
|
|
|
|
TopExp_Explorer exp,exp2;
|
|
TopTools_DataMapOfShapeShape Build;
|
|
TopTools_DataMapOfShapeShape Extent;
|
|
TopoDS_Edge FirstE,PrecE,CurE,NE;
|
|
BRep_Builder B;
|
|
TopoDS_Face EF;
|
|
|
|
// Construction de la boite englobante de la face a etendre et des bouchons pour
|
|
// limiter les extensions.
|
|
//Bnd_Box ContextBox;
|
|
//BRepBndLib::Add(F,B);
|
|
//TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
|
|
//for (; itTB.More(); itTB.Next()) {
|
|
//BRepBndLib::Add(TopBuild.Value(), ContextBox);
|
|
//}
|
|
|
|
|
|
Standard_Boolean SurfaceChange;
|
|
SurfaceChange = EnLargeFace (F,EF,Standard_True);
|
|
|
|
TopoDS_Shape aLocalShape = EF.EmptyCopied();
|
|
NF = TopoDS::Face(aLocalShape);
|
|
// NF = TopoDS::Face(EF.EmptyCopied());
|
|
NF.Orientation(TopAbs_FORWARD);
|
|
|
|
if (SurfaceChange) {
|
|
//------------------------------------------------
|
|
// Mise a jour des pcurves sur la surface de base.
|
|
//------------------------------------------------
|
|
TopoDS_Face Fforward = F;
|
|
Fforward.Orientation(TopAbs_FORWARD);
|
|
TopTools_IndexedMapOfShape Emap;
|
|
TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
|
|
Standard_Real f,l;
|
|
for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
|
|
TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
|
|
CE.Orientation(TopAbs_FORWARD);
|
|
TopoDS_Edge Ecs; //patch
|
|
Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
|
|
if (!C2.IsNull()) {
|
|
if (ConstShapes.IsBound(CE)) {
|
|
Ecs = TopoDS::Edge(ConstShapes(CE));
|
|
BRep_Tool::Range(Ecs,f,l);
|
|
}
|
|
if (BRep_Tool::IsClosed(CE,Fforward)) {
|
|
TopoDS_Shape aLocalShapeReversedCE = CE.Reversed();
|
|
Handle(Geom2d_Curve) C2R =
|
|
BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShapeReversedCE),Fforward,f,l);
|
|
// Handle(Geom2d_Curve) C2R =
|
|
// BRep_Tool::CurveOnSurface(TopoDS::Edge(CE.Reversed()),F,f,l);
|
|
B.UpdateEdge (CE,C2,C2R,EF,BRep_Tool::Tolerance(CE));
|
|
if (! Ecs.IsNull())
|
|
B.UpdateEdge (Ecs,C2,C2R,EF,BRep_Tool::Tolerance(CE));
|
|
}
|
|
else {
|
|
B.UpdateEdge (CE,C2,EF,BRep_Tool::Tolerance(CE));
|
|
if (! Ecs.IsNull())
|
|
B.UpdateEdge (Ecs,C2,EF,BRep_Tool::Tolerance(CE));
|
|
}
|
|
B.Range(CE,f,l);
|
|
if (! Ecs.IsNull())
|
|
B.Range(Ecs,f,l);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
|
|
exp.More();
|
|
exp.Next()) {
|
|
const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
|
|
TopTools_DataMapOfShapeListOfShape MVE; // Vertex -> Edges incidentes.
|
|
TopTools_DataMapOfShapeShape NOnV1;
|
|
TopTools_DataMapOfShapeShape NOnV2;
|
|
|
|
MapVertexEdges (W,MVE);
|
|
BuildNeighbour (W,F,NOnV1,NOnV2);
|
|
|
|
TopTools_ListOfShape LInt1,LInt2;
|
|
TopoDS_Face StopFace;
|
|
//------------------------------------------------
|
|
// Construction edges
|
|
//------------------------------------------------
|
|
for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
|
|
exp2.More(); exp2.Next()) {
|
|
const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
|
|
if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
|
|
if (ToBuild.IsBound(E)) {
|
|
TopTools_ListOfShape LOE;
|
|
LOE.Append(E);
|
|
BRepOffset_Tool::TryProject (TopoDS::Face(ToBuild(E)),
|
|
EF,LOE,LInt2,LInt1,Side,TolConf);
|
|
if (!LInt1.IsEmpty())
|
|
ToBuild.UnBind(E);
|
|
}
|
|
}
|
|
|
|
for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
|
|
exp2.More(); exp2.Next()) {
|
|
const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
|
|
if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
|
|
if (ToBuild.IsBound(E)) {
|
|
EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
|
|
TopoDS_Face NullFace;
|
|
BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,NullFace,NullFace);
|
|
// No intersection, it may happen for example for a chosen (non-offsetted) planar face and
|
|
// its neighbour offseted cylindrical face, if the offset is directed so that
|
|
// the radius of the cylinder becomes smaller.
|
|
if (LInt1.IsEmpty())
|
|
continue;
|
|
if (LInt1.Extent() > 1) {
|
|
// l intersection est en plusieurs edges (franchissement de couture)
|
|
SelectEdge (F,EF,E,LInt1);
|
|
}
|
|
NE = TopoDS::Edge(LInt1.First());
|
|
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &NE.TShape());
|
|
TE->Tolerance( TE->Tolerance()*10. ); //????
|
|
if (NE.Orientation() == E.Orientation()) {
|
|
Build.Bind(E,NE.Oriented(TopAbs_FORWARD));
|
|
}
|
|
else {
|
|
Build.Bind(E,NE.Oriented(TopAbs_REVERSED));
|
|
}
|
|
const TopoDS_Edge& EOnV1 = TopoDS::Edge(NOnV1(E));
|
|
if (!ToBuild .IsBound(EOnV1) &&
|
|
!ConstShapes.IsBound(EOnV1) &&
|
|
!Build .IsBound(EOnV1)) {
|
|
ExtentEdge (F,EF,EOnV1,NE);
|
|
Build.Bind (EOnV1,NE.Oriented(TopAbs_FORWARD));
|
|
}
|
|
const TopoDS_Edge& EOnV2 = TopoDS::Edge(NOnV2(E));
|
|
if (!ToBuild .IsBound(EOnV2) &&
|
|
!ConstShapes.IsBound(EOnV2) &&
|
|
!Build .IsBound(EOnV2)) {
|
|
ExtentEdge (F,EF,EOnV2,NE);
|
|
Build.Bind (EOnV2,NE.Oriented (TopAbs_FORWARD));
|
|
}
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------
|
|
// Construction Vertex.
|
|
//------------------------------------------------
|
|
TopTools_ListOfShape LV;
|
|
Standard_Real f,l;
|
|
TopoDS_Edge ERef;
|
|
TopoDS_Vertex V1,V2;
|
|
|
|
for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp2.More(); exp2.Next())
|
|
{
|
|
const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
|
|
TopExp::Vertices (E,V1,V2);
|
|
BRep_Tool::Range (E,f,l);
|
|
TopoDS_Vertex V;
|
|
if (Build.IsBound(E))
|
|
{
|
|
const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
|
|
if (Build.IsBound(NEOnV1) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1)))
|
|
{
|
|
if (E.IsSame(NEOnV1))
|
|
V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
|
|
else
|
|
{
|
|
//---------------
|
|
// intersection.
|
|
//---------------
|
|
if (!Build.IsBound(V1))
|
|
{
|
|
Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
|
|
|
|
if(!LV.IsEmpty())
|
|
{
|
|
if (Build(E).Orientation() == TopAbs_FORWARD)
|
|
{
|
|
V = TopoDS::Vertex(LV.First());
|
|
}
|
|
else
|
|
{
|
|
V = TopoDS::Vertex(LV.Last());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
V = TopoDS::Vertex(Build(V1));
|
|
if (MVE (V1).Extent() > 2)
|
|
{
|
|
V.Orientation(TopAbs_FORWARD);
|
|
if (Build(E).Orientation() == TopAbs_REVERSED)
|
|
V.Orientation(TopAbs_REVERSED);
|
|
|
|
ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//------------
|
|
//projection
|
|
//------------
|
|
V = V1;
|
|
if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
|
|
V.Orientation(TopAbs_FORWARD);
|
|
if (Build(E).Orientation() == TopAbs_REVERSED)
|
|
V.Orientation(TopAbs_REVERSED);
|
|
if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
|
|
ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
|
|
}
|
|
|
|
ConstShapes.Bind(V1,V);
|
|
Build.Bind (V1,V);
|
|
const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
|
|
if (Build.IsBound(NEOnV2) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2)))
|
|
{
|
|
if (E.IsSame(NEOnV2))
|
|
V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
|
|
else
|
|
{
|
|
//--------------
|
|
// intersection.
|
|
//---------------
|
|
|
|
if (!Build.IsBound(V2))
|
|
{
|
|
Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
|
|
|
|
if(!LV.IsEmpty())
|
|
{
|
|
if (Build(E).Orientation() == TopAbs_FORWARD)
|
|
{
|
|
V = TopoDS::Vertex(LV.Last());
|
|
}
|
|
else
|
|
{
|
|
V = TopoDS::Vertex(LV.First());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
V = TopoDS::Vertex(Build(V2));
|
|
if (MVE (V2).Extent() > 2)
|
|
{
|
|
V.Orientation(TopAbs_REVERSED);
|
|
if (Build(E).Orientation() == TopAbs_REVERSED)
|
|
V.Orientation(TopAbs_FORWARD);
|
|
|
|
ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//------------
|
|
//projection
|
|
//------------
|
|
V = V2;
|
|
if (ConstShapes.IsBound(V2))
|
|
V = TopoDS::Vertex(ConstShapes(V2));
|
|
V.Orientation(TopAbs_REVERSED);
|
|
if (Build(E).Orientation() == TopAbs_REVERSED)
|
|
V.Orientation(TopAbs_FORWARD);
|
|
if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
|
|
ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
|
|
}
|
|
ConstShapes.Bind(V2,V);
|
|
Build.Bind(V2,V);
|
|
}
|
|
}
|
|
|
|
TopoDS_Wire NW;
|
|
TopoDS_Vertex NV1,NV2;
|
|
TopAbs_Orientation Or;
|
|
Standard_Real U1,U2;
|
|
Standard_Real eps = Precision::Confusion();
|
|
|
|
#ifdef OCCT_DEBUG
|
|
TopLoc_Location L;
|
|
#endif
|
|
B.MakeWire(NW);
|
|
|
|
//-----------------
|
|
// Reconstruction.
|
|
//-----------------
|
|
for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
|
|
exp2.More(); exp2.Next()) {
|
|
const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
|
|
TopExp::Vertices (E,V1,V2);
|
|
if (Build.IsBound(E)) {
|
|
NE = TopoDS::Edge(Build(E));
|
|
BRep_Tool::Range(NE,f,l);
|
|
Or = NE.Orientation();
|
|
//-----------------------------------------------------
|
|
// Copy pour virer les vertex deja sur la nouvelle edge.
|
|
//-----------------------------------------------------
|
|
NV1 = TopoDS::Vertex(ConstShapes(V1));
|
|
NV2 = TopoDS::Vertex(ConstShapes(V2));
|
|
|
|
TopoDS_Shape aLocalVertexOrientedNV1 = NV1.Oriented(TopAbs_INTERNAL);
|
|
TopoDS_Shape aLocalEdge = NE.Oriented(TopAbs_INTERNAL);
|
|
|
|
U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalVertexOrientedNV1),
|
|
TopoDS::Edge (aLocalEdge));
|
|
aLocalVertexOrientedNV1 = NV2.Oriented(TopAbs_INTERNAL);
|
|
aLocalEdge = NE.Oriented(TopAbs_FORWARD);
|
|
U2 = BRep_Tool::Parameter (TopoDS::Vertex(aLocalVertexOrientedNV1),TopoDS::Edge (aLocalEdge));
|
|
// U1 = BRep_Tool::Parameter
|
|
// (TopoDS::Vertex(NV1.Oriented(TopAbs_INTERNAL)),
|
|
// TopoDS::Edge (NE .Oriented(TopAbs_FORWARD)));
|
|
// U2 = BRep_Tool::Parameter
|
|
// (TopoDS::Vertex(NV2.Oriented(TopAbs_INTERNAL)),
|
|
// TopoDS::Edge (NE.Oriented(TopAbs_FORWARD)));
|
|
aLocalEdge = NE.EmptyCopied();
|
|
NE = TopoDS::Edge(aLocalEdge);
|
|
NE.Orientation(TopAbs_FORWARD);
|
|
if (NV1.IsSame(NV2))
|
|
{
|
|
//--------------
|
|
// edge ferme.
|
|
//--------------
|
|
if (Or == TopAbs_FORWARD) {U1 = f; U2 = l;}
|
|
else {U1 = l; U2 = f;}
|
|
if (Or == TopAbs_FORWARD)
|
|
{
|
|
if (U1 > U2)
|
|
{
|
|
if (Abs(U1-l) < eps) U1 = f;
|
|
if (Abs(U2-f) < eps) U2 = l;
|
|
}
|
|
TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
// B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
|
|
// B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
|
|
B.Range(NE,U1,U2);
|
|
ConstShapes.Bind(E,NE);
|
|
NE.Orientation(E.Orientation());
|
|
}
|
|
else
|
|
{
|
|
if (U2 > U1)
|
|
{
|
|
if (Abs(U2-l) < eps) U2 = f;
|
|
if (Abs(U1-f) < eps) U1 = l;
|
|
}
|
|
TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
// B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
|
|
// B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
|
|
B.Range(NE,U2,U1);
|
|
ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
|
|
NE.Orientation(TopAbs::Reverse(E.Orientation()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//-------------------
|
|
// edge is not ferme.
|
|
//-------------------
|
|
if (Or == TopAbs_FORWARD) {
|
|
if (U1 > U2) {
|
|
TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
// B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
|
|
// B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
|
|
B.Range(NE,U2,U1);
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
// B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
|
|
// B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
|
|
B.Range(NE,U1,U2);
|
|
}
|
|
ConstShapes.Bind(E,NE);
|
|
NE.Orientation(E.Orientation());
|
|
}
|
|
else {
|
|
if (U2 > U1) {
|
|
TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
// B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
|
|
// B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
|
|
B.Range(NE,U1,U2);
|
|
ConstShapes.Bind(E,NE);
|
|
NE.Orientation(E.Orientation());
|
|
}
|
|
else
|
|
{
|
|
TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
|
|
B.Add (NE,TopoDS::Vertex(aLocalVertex));
|
|
// B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
|
|
// B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
|
|
B.Range(NE,U2,U1);
|
|
ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
|
|
NE.Orientation(TopAbs::Reverse(E.Orientation()));
|
|
}
|
|
}
|
|
}
|
|
Build.UnBind(E);
|
|
} // Build.IsBound(E)
|
|
else if (ConstShapes.IsBound(E)) { // !Build.IsBound(E)
|
|
NE = TopoDS::Edge(ConstShapes(E));
|
|
BuildPCurves(NE,NF);
|
|
Or = NE.Orientation();
|
|
if (Or == TopAbs_REVERSED) {
|
|
NE.Orientation(TopAbs::Reverse(E.Orientation()));
|
|
}
|
|
else {
|
|
NE.Orientation(E.Orientation());
|
|
}
|
|
}
|
|
else {
|
|
NE = E;
|
|
ConstShapes.Bind(E,NE.Oriented(TopAbs_FORWARD));
|
|
}
|
|
B.Add(NW,NE);
|
|
}
|
|
B.Add(NF,NW.Oriented(W.Orientation()));
|
|
}
|
|
NF.Orientation(F.Orientation());
|
|
BRepTools::Update(NF); // Maj des UVPoints
|
|
|
|
#ifdef DRAW
|
|
if (AffichInter) {
|
|
char name[256];
|
|
sprintf(name,"FOB_%d",NbFOB++);
|
|
DBRep::Set(name,NF);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Deboucle3D
|
|
//purpose :
|
|
//=======================================================================
|
|
TopoDS_Shape BRepOffset_Tool::Deboucle3D(const TopoDS_Shape& S,
|
|
const TopTools_MapOfShape& Boundary)
|
|
{
|
|
TopoDS_Shape SS;
|
|
switch (S.ShapeType())
|
|
{
|
|
case TopAbs_SHELL:
|
|
{
|
|
// if the shell contains free borders that do not belong to the
|
|
// free borders of caps ( Boundary) it is removed.
|
|
TopTools_IndexedDataMapOfShapeListOfShape Map;
|
|
TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, Map);
|
|
|
|
Standard_Boolean JeGarde = Standard_True;
|
|
for (Standard_Integer i = 1; i <= Map.Extent() && JeGarde; i++) {
|
|
const TopTools_ListOfShape& aLF = Map(i);
|
|
if (aLF.Extent() < 2) {
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(Map.FindKey(i));
|
|
if (anEdge.Orientation() == TopAbs_INTERNAL) {
|
|
const TopoDS_Face& aFace = TopoDS::Face(aLF.First());
|
|
if (aFace.Orientation() != TopAbs_INTERNAL) {
|
|
continue;
|
|
}
|
|
}
|
|
if (!Boundary.Contains(anEdge) &&
|
|
!BRep_Tool::Degenerated(anEdge))
|
|
JeGarde = Standard_False;
|
|
}
|
|
}
|
|
if (JeGarde) SS = S;
|
|
}
|
|
break;
|
|
|
|
case TopAbs_COMPOUND:
|
|
case TopAbs_SOLID:
|
|
{
|
|
// iterate on sub-shapes and add non-empty.
|
|
TopoDS_Iterator it(S);
|
|
TopoDS_Shape SubShape;
|
|
Standard_Integer NbSub = 0;
|
|
BRep_Builder B;
|
|
if (S.ShapeType() == TopAbs_COMPOUND) {
|
|
B.MakeCompound(TopoDS::Compound(SS));
|
|
}
|
|
else {
|
|
B.MakeSolid(TopoDS::Solid(SS));
|
|
}
|
|
for (; it.More(); it.Next()) {
|
|
const TopoDS_Shape& CurS = it.Value();
|
|
SubShape = Deboucle3D(CurS, Boundary);
|
|
if (!SubShape.IsNull()) {
|
|
B.Add(SS, SubShape);
|
|
NbSub++;
|
|
}
|
|
}
|
|
if (NbSub == 0)
|
|
{
|
|
SS = TopoDS_Shape();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return SS;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IsInOut
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean IsInOut (BRepTopAdaptor_FClass2d& FC,
|
|
Geom2dAdaptor_Curve AC,
|
|
const TopAbs_State& S )
|
|
{
|
|
Standard_Real Def = 100*Precision::Confusion();
|
|
GCPnts_QuasiUniformDeflection QU(AC,Def);
|
|
|
|
for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
|
|
gp_Pnt2d P = AC.Value(QU.Parameter(i));
|
|
if (FC.Perform(P) != S) {
|
|
return Standard_False;
|
|
}
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CorrectOrientation
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape& SI,
|
|
const TopTools_IndexedMapOfShape& NewEdges,
|
|
Handle(BRepAlgo_AsDes)& AsDes,
|
|
BRepAlgo_Image& InitOffset,
|
|
const Standard_Real Offset)
|
|
{
|
|
|
|
TopExp_Explorer exp;
|
|
exp.Init(SI,TopAbs_FACE);
|
|
Standard_Real f=0.,l=0.;
|
|
|
|
for (; exp.More(); exp.Next()) {
|
|
|
|
const TopoDS_Face& FI = TopoDS::Face(exp.Current());
|
|
const TopTools_ListOfShape& LOF = InitOffset.Image(FI);
|
|
TopTools_ListIteratorOfListOfShape it(LOF);
|
|
for (; it.More(); it.Next()) {
|
|
const TopoDS_Face& OF = TopoDS::Face(it.Value());
|
|
TopTools_ListOfShape& LOE = AsDes->ChangeDescendant(OF);
|
|
TopTools_ListIteratorOfListOfShape itE(LOE);
|
|
|
|
Standard_Boolean YaInt = Standard_False;
|
|
for (; itE.More(); itE.Next()) {
|
|
const TopoDS_Edge& OE = TopoDS::Edge(itE.Value());
|
|
if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
|
|
}
|
|
if (YaInt) {
|
|
TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
|
|
BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
|
|
Precision::Confusion());
|
|
// BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
|
|
// Precision::Confusion());
|
|
for (itE.Initialize(LOE); itE.More(); itE.Next()) {
|
|
TopoDS_Shape& OE = itE.Value();
|
|
if (NewEdges.Contains(OE)) {
|
|
Handle(Geom2d_Curve) CO2d =
|
|
BRep_Tool::CurveOnSurface(TopoDS::Edge(OE),OF,f,l);
|
|
Geom2dAdaptor_Curve AC(CO2d,f,l);
|
|
|
|
if (Offset > 0) {
|
|
if (IsInOut(FC,AC,TopAbs_OUT)) OE.Reverse();
|
|
}
|
|
// else {
|
|
// if (IsInOut(FC,AC,TopAbs_IN)) OE.Reverse();
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CheckNormals
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean BRepOffset_Tool::CheckPlanesNormals(const TopoDS_Face& theFace1,
|
|
const TopoDS_Face& theFace2,
|
|
const Standard_Real theTolAng)
|
|
{
|
|
BRepAdaptor_Surface aBAS1(theFace1, Standard_False), aBAS2(theFace2, Standard_False);
|
|
if (aBAS1.GetType() != GeomAbs_Plane ||
|
|
aBAS2.GetType() != GeomAbs_Plane) {
|
|
return Standard_False;
|
|
}
|
|
//
|
|
gp_Dir aDN1 = aBAS1.Plane().Position().Direction();
|
|
if (theFace1.Orientation() == TopAbs_REVERSED) {
|
|
aDN1.Reverse();
|
|
}
|
|
//
|
|
gp_Dir aDN2 = aBAS2.Plane().Position().Direction();
|
|
if (theFace2.Orientation() == TopAbs_REVERSED) {
|
|
aDN2.Reverse();
|
|
}
|
|
//
|
|
Standard_Real anAngle = aDN1.Angle(aDN2);
|
|
return (anAngle < theTolAng);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : PerformPlanes
|
|
//purpose :
|
|
//=======================================================================
|
|
void PerformPlanes(const TopoDS_Face& theFace1,
|
|
const TopoDS_Face& theFace2,
|
|
const TopAbs_State theSide,
|
|
TopTools_ListOfShape& theL1,
|
|
TopTools_ListOfShape& theL2)
|
|
{
|
|
theL1.Clear();
|
|
theL2.Clear();
|
|
// Intersect the planes using IntTools_FaceFace directly
|
|
IntTools_FaceFace aFF;
|
|
aFF.SetParameters(Standard_True, Standard_True, Standard_True, Precision::Confusion());
|
|
aFF.Perform(theFace1, theFace2);
|
|
//
|
|
if (!aFF.IsDone()) {
|
|
return;
|
|
}
|
|
//
|
|
const IntTools_SequenceOfCurves& aSC = aFF.Lines();
|
|
if (aSC.IsEmpty()) {
|
|
return;
|
|
}
|
|
//
|
|
// In Plane/Plane intersection only one curve is always produced.
|
|
// Make the edge from this section curve.
|
|
TopoDS_Edge aE;
|
|
{
|
|
BRep_Builder aBB;
|
|
const IntTools_Curve& aIC = aSC(1);
|
|
const Handle(Geom_Curve)& aC3D = aIC.Curve();
|
|
aBB.MakeEdge(aE, aC3D, aIC.Tolerance());
|
|
// Get bounds of the curve
|
|
Standard_Real aTF, aTL;
|
|
gp_Pnt aPF, aPL;
|
|
aIC.Bounds(aTF, aTL, aPF, aPL);
|
|
// Make the bounding vertices
|
|
TopoDS_Vertex aVF, aVL;
|
|
aBB.MakeVertex(aVF, aPF, aIC.Tolerance());
|
|
aBB.MakeVertex(aVL, aPL, aIC.Tolerance());
|
|
aVL.Orientation(TopAbs_REVERSED);
|
|
// Add vertices to the edge
|
|
aBB.Add(aE, aVF);
|
|
aBB.Add(aE, aVL);
|
|
// Add 2D curves to the edge
|
|
aBB.UpdateEdge(aE, aIC.FirstCurve2d(), theFace1, aIC.Tolerance());
|
|
aBB.UpdateEdge(aE, aIC.SecondCurve2d(), theFace2, aIC.Tolerance());
|
|
// Update range of the new edge
|
|
aBB.Range(aE, aTF, aTL);
|
|
}
|
|
//
|
|
// Orient section
|
|
TopAbs_Orientation O1, O2;
|
|
BRepOffset_Tool::OrientSection(aE, theFace1, theFace2, O1, O2);
|
|
if (theSide == TopAbs_OUT) {
|
|
O1 = TopAbs::Reverse(O1);
|
|
O2 = TopAbs::Reverse(O2);
|
|
}
|
|
//
|
|
BRepLib::SameParameter(aE, Precision::Confusion(), Standard_True);
|
|
//
|
|
// Add edge to result
|
|
theL1.Append(aE.Oriented(O1));
|
|
theL2.Append(aE.Oriented(O2));
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IsInf
|
|
//purpose : Checks if the given value is close to infinite (TheInfini)
|
|
//=======================================================================
|
|
Standard_Boolean IsInf(const Standard_Real theVal)
|
|
{
|
|
return (theVal > TheInfini*0.9);
|
|
}
|
|
|
|
static void UpdateVertexTolerances(const TopoDS_Face& theFace)
|
|
{
|
|
BRep_Builder BB;
|
|
TopTools_IndexedDataMapOfShapeListOfShape VEmap;
|
|
TopExp::MapShapesAndAncestors(theFace, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
|
|
|
|
for (Standard_Integer i = 1; i <= VEmap.Extent(); i++)
|
|
{
|
|
const TopoDS_Vertex& aVertex = TopoDS::Vertex(VEmap.FindKey(i));
|
|
const TopTools_ListOfShape& Elist = VEmap(i);
|
|
gp_Pnt PntVtx = BRep_Tool::Pnt(aVertex);
|
|
TopTools_ListIteratorOfListOfShape itl(Elist);
|
|
for (; itl.More(); itl.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
|
|
TopoDS_Vertex V1, V2;
|
|
TopExp::Vertices(anEdge, V1, V2);
|
|
Standard_Real fpar, lpar;
|
|
BRep_Tool::Range(anEdge, fpar, lpar);
|
|
Standard_Real aParam = (V1.IsSame(aVertex))? fpar : lpar;
|
|
if (!BRep_Tool::Degenerated(anEdge))
|
|
{
|
|
BRepAdaptor_Curve BAcurve(anEdge);
|
|
gp_Pnt aPnt = BAcurve.Value(aParam);
|
|
Standard_Real aDist = PntVtx.Distance(aPnt);
|
|
BB.UpdateVertex(aVertex, aDist);
|
|
if (V1.IsSame(V2))
|
|
{
|
|
aPnt = BAcurve.Value(lpar);
|
|
aDist = PntVtx.Distance(aPnt);
|
|
BB.UpdateVertex(aVertex, aDist);
|
|
}
|
|
}
|
|
BRepAdaptor_Curve BAcurveonsurf(anEdge, theFace);
|
|
gp_Pnt aPnt = BAcurveonsurf.Value(aParam);
|
|
Standard_Real aDist = PntVtx.Distance(aPnt);
|
|
BB.UpdateVertex(aVertex, aDist);
|
|
if (V1.IsSame(V2))
|
|
{
|
|
aPnt = BAcurveonsurf.Value(lpar);
|
|
aDist = PntVtx.Distance(aPnt);
|
|
BB.UpdateVertex(aVertex, aDist);
|
|
}
|
|
}
|
|
}
|
|
}
|