#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TShort_HArray1OfShortReal.hxx>
+#include <TColgp_Array1OfXY.hxx>
// TODO - not thread-safe static variables
static Standard_Real thePrecision = Precision::Confusion();
return Standard_True;
}
-
//=======================================================================
//function : tgtfaces
//purpose : check the angle at the border between two squares.
// Two shares should have a shared front edge.
//=======================================================================
-
-static Standard_Boolean tgtfaces(const TopoDS_Edge& Ed,
+static GeomAbs_Shape tgtfaces(const TopoDS_Edge& Ed,
const TopoDS_Face& F1,
const TopoDS_Face& F2,
- const Standard_Real ta,
+ const Standard_Real theAngleTol,
const Standard_Boolean couture)
{
// Check if pcurves exist on both faces of edge
Handle(Geom2d_Curve) aCurve;
aCurve = BRep_Tool::CurveOnSurface(Ed,F1,aFirst,aLast);
if(aCurve.IsNull())
- return Standard_False;
+ return GeomAbs_C0;
aCurve = BRep_Tool::CurveOnSurface(Ed,F2,aFirst,aLast);
if(aCurve.IsNull())
- return Standard_False;
-
+ return GeomAbs_C0;
+
Standard_Real u;
TopoDS_Edge E = Ed;
BRepAdaptor_Surface aBAS1(F1,Standard_False);
BRepAdaptor_Surface aBAS2(F2,Standard_False);
- Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface(aBAS1);
+
+ // seam edge on elementary surface is always CN
+ Standard_Boolean isElementary =
+ (aBAS1.Surface().Surface()->IsKind(STANDARD_TYPE(Geom_ElementarySurface)) &&
+ aBAS1.Surface().Surface()->IsKind(STANDARD_TYPE(Geom_ElementarySurface)));
+ if (couture && isElementary)
+ {
+ return GeomAbs_CN;
+ }
+
+ Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface (aBAS1);
Handle(BRepAdaptor_HSurface) HS2;
if(couture) HS2 = HS1;
else HS2 = new BRepAdaptor_HSurface(aBAS2);
-
+ //case when edge lies on the one face
+
E.Orientation(TopAbs_FORWARD);
Handle(BRepAdaptor_HCurve2d) HC2d1 = new BRepAdaptor_HCurve2d();
HC2d1->ChangeCurve2d().Initialize(E,F1);
Standard_Boolean rev1 = (F1.Orientation() == TopAbs_REVERSED);
Standard_Boolean rev2 = (F2.Orientation() == TopAbs_REVERSED);
- Standard_Real f,l,eps, angmax = -M_PI;
- Standard_Real ang =0.;
+ Standard_Real f,l,eps;
BRep_Tool::Range(E,f,l);
Extrema_LocateExtPC ext;
Standard_Boolean IsInitialized = Standard_False;
l -= eps; // points of pointed squares.
gp_Pnt2d p;
gp_Pnt pp1,pp2;//,PP;
- gp_Vec du,dv;
+ gp_Vec du1, dv1, d2u1, d2v1, d2uv1;
+ gp_Vec du2, dv2, d2u2, d2v2, d2uv2;
gp_Vec d1,d2;
Standard_Real uu, vv, norm;
Standard_Integer i;
- Standard_Boolean Nok;
- for(i = 0; (i<= 20) && (angmax<=ta) ; i++){
+ GeomAbs_Shape aCont = (isElementary ? GeomAbs_CN : GeomAbs_C2);
+ for(i = 0; i<= 20 && aCont > GeomAbs_C0; i++)
+ {
// First suppose that this is sameParameter
- Nok = Standard_True;
u = f + (l-f)*i/20;
+
+ // take derivatives of surfaces at the same u, and compute normals
HC2d1->D0(u,p);
- HS1->D1(p.X(),p.Y(),pp1,du,dv);
- d1 = (du.Crossed(dv));
+ HS1->D2 (p.X(), p.Y(), pp1, du1, dv1, d2u1, d2v1, d2uv1);
+ d1 = (du1.Crossed(dv1));
norm = d1.Magnitude();
if (norm > 1.e-12) d1 /= norm;
- else Nok=Standard_False;
+ else continue; // skip degenerated point
if(rev1) d1.Reverse();
HC2d2->D0(u,p);
- HS2->D1(p.X(), p.Y(), pp2, du, dv);
- d2 = (du.Crossed(dv));
+ HS2->D2 (p.X(), p.Y(), pp2, du2, dv2, d2u2, d2v2, d2uv2);
+ d2 = (du2.Crossed(dv2));
norm = d2.Magnitude();
- if (norm> 1.e-12) d2 /= norm;
- else Nok=Standard_False;
+ if (norm > 1.e-12) d2 /= norm;
+ else continue; // skip degenerated point
if(rev2) d2.Reverse();
- if (Nok) ang = d1.Angle(d2);
- if (Nok &&(ang > ta)) { // Refine by projection
+ // check
+ Standard_Real ang = d1.Angle(d2);
+
+ // check special case of precise equality of derivatives,
+ // occurring when edge connects two faces built on equally
+ // defined surfaces (e.g. seam-like edges on periodic surfaces,
+ // or planar faces on the same plane)
+ if (aCont >= GeomAbs_C2 && ang < Precision::Angular() &&
+ d2u1 .IsEqual (d2u2, Precision::PConfusion(), Precision::Angular()) &&
+ d2v1 .IsEqual (d2v2, Precision::PConfusion(), Precision::Angular()) &&
+ d2uv1.IsEqual (d2uv2, Precision::PConfusion(), Precision::Angular()))
+ {
+ continue;
+ }
+
+ aCont = GeomAbs_G1;
+
+ // Refine by projection
+ if (ang > theAngleTol)
+ {
if (! IsInitialized ) {
ext.Initialize(C2,f,l,Precision::PConfusion());
IsInitialized = Standard_True;
HC2d2->D0(v,p);
p.Coord(uu,vv);
- HS2->D1(p.X(), p.Y(), pp2, du, dv);
- d2 = (du.Crossed(dv));
+ HS2->D1(p.X(), p.Y(), pp2, du2, dv2);
+ d2 = (du2.Crossed(dv2));
norm = d2.Magnitude();
if (norm> 1.e-12) d2 /= norm;
- else Nok = Standard_False;
+ else continue; // degenerated point
if(rev2) d2.Reverse();
- if (Nok) ang = d1.Angle(d2);
+ ang = d1.Angle(d2);
}
+ if (ang > theAngleTol)
+ return GeomAbs_C0;
}
- if(ang >= angmax) angmax = ang;
}
- return (angmax<=ta);
-
+ return aCont;
}
if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0){
try {
- if(tgtfaces(E, F1, F2, TolAng, couture)){
- B.Continuity(E,F1,F2,GeomAbs_G1);
- }
+ GeomAbs_Shape aCont = tgtfaces(E, F1, F2, TolAng, couture);
+ B.Continuity(E,F1,F2,aCont);
}
catch(Standard_Failure)
{
BRep_Builder B;
if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0){
try {
- if( tgtfaces(E, F1, F2, TolAng, F1.IsEqual(F2))) {
- B.Continuity(E,F1,F2,GeomAbs_G1);
- }
+ GeomAbs_Shape aCont = tgtfaces(E, F1, F2, TolAng, F1.IsEqual(F2));
+ B.Continuity(E,F1,F2,aCont);
+
}
catch(Standard_Failure)
{
return 0;
}
+static Standard_Integer getedgeregul
+ (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
+{
+ if( argc < 3)
+ {
+ cout<<"Invalid number of arguments. Should be: checkedgeregularity edge face1 [face2]"<<endl;
+ return 1;
+ }
+
+ TopoDS_Shape anEdge = DBRep::Get(argv[1],TopAbs_EDGE);
+ TopoDS_Shape aFace1 = DBRep::Get(argv[2],TopAbs_FACE);
+ TopoDS_Shape aFace2 = (argc > 3 ? DBRep::Get(argv[3],TopAbs_FACE) : aFace1);
+ if( anEdge.IsNull() || aFace1.IsNull() || aFace2.IsNull())
+ {
+ cout<<"Invalid number of arguments. Should be: getedgeregularity edge face1 [face2]"<<endl;
+ return 1;
+ }
+
+ GeomAbs_Shape aRegularity = BRep_Tool::Continuity(TopoDS::Edge(anEdge), TopoDS::Face(aFace1), TopoDS::Face(aFace2));
+ TCollection_AsciiString aStrReg("Regularity of edge : ");
+ switch( aRegularity)
+ {
+ default:
+ case GeomAbs_C0 : aStrReg += "C0"; break;
+ case GeomAbs_G1 : aStrReg += "G1"; break;
+ case GeomAbs_C1 : aStrReg += "C1"; break;
+ case GeomAbs_G2 : aStrReg += "G2"; break;
+ case GeomAbs_C2 : aStrReg += "C2"; break;
+ case GeomAbs_C3 : aStrReg += "C3"; break;
+ case GeomAbs_CN : aStrReg += "CN"; break;
+ };
+
+ di<<aStrReg.ToCString()<<"\n";
+ return 0; // Done
+}
//=======================================================================
//function : SurfaceCommands
theCommands.Add ("fastsewing", "fastsewing result [-tol <value>] <list_of_faces>",
__FILE__, fastsewing, g);
+ theCommands.Add ("getedgeregularity", "getedgeregularity edge face1 [face2]", __FILE__,getedgeregul,g);
}
return 0; // Done
}
-
-static Standard_Integer XSHAPE_edgeregul
- (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
-{
- //cky/rln 03.02.99 To eliminate dependence of SWDRAW on TKXSBase (to use only ShapeHealing)
- Standard_Real tolang = Precision::Angular(); // = Interface_Static::RVal("XSTEP.encoderegularity.angle");
-// if (argc < 3) di<<"Current value for regularity angle : "<<tolang<<"\n";
- if (argc < 3) {
- di<<"Donner nom de shape.\n + option : angle en radian, sinon la valeur courante est prise\n";
- return 0;
- }
- Standard_CString arg1 = argv[1];
- Standard_CString arg2 = argv[2];
- if (argc > 2) tolang = Draw::Atof (arg2);
- if (tolang <= 0) {
- di<<"Not a suitable value : "<<tolang<<"\n";
- return 1 /* Error */;
- }
- TopoDS_Shape Shape = DBRep::Get(arg1);
- if (Shape.IsNull()) { di<<"Shape unknown : "<<arg1<<"\n"; return 1 /* Error */; }
-
- BRepLib::EncodeRegularity (Shape,tolang);
- return 0; // Done
-}
-
static Standard_Integer samerange (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
{
if ( argc ==2 ) {
theCommands.Add ("ssolid","nom shell + nouveau nom solid",
__FILE__,XSHAPE_ssolid,g);
- theCommands.Add ("edgeregul","shape val",
- __FILE__,XSHAPE_edgeregul,g);
-
theCommands.Add ("samerange","{ shape | result curve2d first last newfirst newlast }",
__FILE__,samerange,g);
}