#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <BRepTopAdaptor_TopolTool.hxx>
+#include <LocalAnalysis_SurfaceContinuity.hxx>
#include <BRepOffset_Analyse.hxx>
#include <BRepOffset_Interval.hxx>
#include <BRepOffset_ListIteratorOfListOfInterval.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
+#include <TopOpeBRepTool_TOOL.hxx>
+#include <IntTools_Tools.hxx>
//
static void Correct2dPoint(const TopoDS_Face& theF, gp_Pnt2d& theP2d);
const TopoDS_Face& F2,
const Standard_Real SinTol,
const Standard_Boolean CorrectPoint);
+
+static Standard_Boolean IsTangentFaces(const TopoDS_Edge &theEdge,
+ const TopoDS_Face &theFace1,
+ const TopoDS_Face &theFace2,
+ const GeomAbs_Shape Order);
//
static void CorrectOrientationOfTangent(gp_Vec& TangVec,
const TopoDS_Vertex& aVertex,
const Standard_Real SinTol,
BRepOffset_ListOfInterval& LI)
{
-
Standard_Real f,l;
BRep_Tool::Range(E, F1, f, l);
BRepOffset_Interval I;
I.First(f); I.Last(l);
- //
- // Tangent if the regularity is at least G1.
- if (BRep_Tool::HasContinuity(E,F1,F2)) {
- if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0) {
- I.Type(BRepOffset_Tangent);
- LI.Append(I);
- return;
- }
+ //
+ BRepAdaptor_Surface aBAsurf1(F1, Standard_False);
+ GeomAbs_SurfaceType aSurfType1 = aBAsurf1.GetType();
+
+ BRepAdaptor_Surface aBAsurf2(F2, Standard_False);
+ GeomAbs_SurfaceType aSurfType2 = aBAsurf2.GetType();
+
+ Standard_Boolean isTwoPlanes = (aSurfType1 == GeomAbs_Plane && aSurfType2 == GeomAbs_Plane);
+
+ BRepOffset_Type ConnectType = BRepOffset_Other;
+
+ if (isTwoPlanes) //then use only strong condition
+ {
+ if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0)
+ ConnectType = BRepOffset_Tangent;
+ else
+ ConnectType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
}
- //
- BRepOffset_Type aType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
- if(aType != BRepOffset_Tangent)
+ else
{
- aType = DefineConnectType(E, F1, F2, SinTol, Standard_True);
+ if (IsTangentFaces(E, F1, F2, GeomAbs_G1)) //weak condition
+ ConnectType = BRepOffset_Tangent;
+ else
+ ConnectType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
}
- I.Type(aType);
+
+ I.Type(ConnectType);
LI.Append(I);
}
const Standard_Real SinTol,
const Standard_Boolean CorrectPoint)
{
- TopLoc_Location L;
- Standard_Real f,l;
-
const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1);
const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2);
//
+ Standard_Real f,l;
Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
- Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
+ //For the case of seam edge
+ TopoDS_Edge EE = E;
+ if (F1.IsSame(F2))
+ EE.Reverse();
+ Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(EE,F2,f,l);
+ if (C1.IsNull() || C2.IsNull())
+ return BRepOffset_Other;
BRepAdaptor_Curve C(E);
f = C.FirstParameter();
l = C.LastParameter();
//
Standard_Real ParOnC = 0.5*(f+l);
- gp_Vec T1 = C.DN(ParOnC,1).Transformed(L.Transformation());
+ gp_Vec T1 = C.DN(ParOnC,1);
+ if (T1.SquareMagnitude() <= gp::Resolution())
+ {
+ ParOnC = IntTools_Tools::IntermediatePoint(f,l);
+ T1 = C.DN(ParOnC,1);
+ }
if (T1.SquareMagnitude() > gp::Resolution()) {
T1.Normalize();
}
gp_Vec ProVec = DN1^DN2;
Standard_Real NormProVec = ProVec.Magnitude();
-
- if (Abs(NormProVec) < SinTol) {
+ if (NormProVec < SinTol) {
// plane
if (DN1.Dot(DN2) > 0) {
//Tangent
}
}
}
+
+//=======================================================================
+//function : IsTangentFaces
+//purpose :
+//=======================================================================
+Standard_Boolean IsTangentFaces(const TopoDS_Edge &theEdge,
+ const TopoDS_Face &theFace1,
+ const TopoDS_Face &theFace2,
+ const GeomAbs_Shape Order)
+{
+ if (Order == GeomAbs_G1 &&
+ BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0)
+ return Standard_True;
+
+ Standard_Real TolC0 = Max(0.001, 1.5*BRep_Tool::Tolerance(theEdge));
+
+ Standard_Real aFirst;
+ Standard_Real aLast;
+
+// Obtaining of pcurves of edge on two faces.
+ const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
+ (theEdge, theFace1, aFirst, aLast);
+ const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
+ (theEdge, theFace2, aFirst, aLast);
+ if (aC2d1.IsNull() || aC2d2.IsNull())
+ return Standard_False;
+
+// Obtaining of two surfaces from adjacent faces.
+ Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
+ Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
+
+ if (aSurf1.IsNull() || aSurf2.IsNull())
+ return Standard_False;
+
+// Computation of the number of samples on the edge.
+ BRepAdaptor_Surface aBAS1(theFace1);
+ BRepAdaptor_Surface aBAS2(theFace2);
+ Handle(BRepAdaptor_HSurface) aBAHS1 = new BRepAdaptor_HSurface(aBAS1);
+ Handle(BRepAdaptor_HSurface) aBAHS2 = new BRepAdaptor_HSurface(aBAS2);
+ Handle(BRepTopAdaptor_TopolTool) aTool1 = new BRepTopAdaptor_TopolTool(aBAHS1);
+ Handle(BRepTopAdaptor_TopolTool) aTool2 = new BRepTopAdaptor_TopolTool(aBAHS2);
+ Standard_Integer aNbSamples1 = aTool1->NbSamples();
+ Standard_Integer aNbSamples2 = aTool2->NbSamples();
+ Standard_Integer aNbSamples = Max(aNbSamples1, aNbSamples2);
+
+
+// Computation of the continuity.
+ Standard_Real aPar;
+ Standard_Real aDelta = (aLast - aFirst)/(aNbSamples - 1);
+ Standard_Integer i, nbNotDone = 0;
+
+ for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) {
+ if (i == aNbSamples) aPar = aLast;
+
+ LocalAnalysis_SurfaceContinuity aCont(aC2d1, aC2d2, aPar,
+ aSurf1, aSurf2, Order,
+ 0.001, TolC0, 0.1, 0.1, 0.1);
+ if (!aCont.IsDone())
+ {
+ nbNotDone++;
+ continue;
+ }
+
+ if (Order == GeomAbs_G1)
+ {
+ if (!aCont.IsG1())
+ return Standard_False;
+ }
+ else if (!aCont.IsG2())
+ return Standard_False;
+ }
+
+ if (nbNotDone == aNbSamples)
+ return Standard_False;
+
+ //Compare normals of tangent faces in the middle point
+ Standard_Real MidPar = (aFirst + aLast)/2.;
+ gp_Pnt2d uv1 = aC2d1->Value(MidPar);
+ gp_Pnt2d uv2 = aC2d2->Value(MidPar);
+ gp_Dir normal1, normal2;
+ TopOpeBRepTool_TOOL::Nt( uv1, theFace1, normal1 );
+ TopOpeBRepTool_TOOL::Nt( uv2, theFace2, normal2 );
+ Standard_Real dot = normal1.Dot(normal2);
+ if (dot < 0.)
+ return Standard_False;
+ return Standard_True;
+}