Add the case of closed, smooth but not periodic surface (unification of faces lying on it if the flag "myConcatBSplines" is true - modify the underlying surface to make it periodic).
return aDeriv.Transformed(mySurfaceTrsf);
}
+ gp_Dir Normal()
+ {
+ gp_Dir aNormal = mySurfaceProps.Normal();
+ return aNormal.Transformed(mySurfaceTrsf);
+ }
+
// Calculate principal curvatures, which consist of minimal and maximal normal curvatures and
// the directions on the tangent plane (principal direction) where the extremums are reached
void Curvature(gp_Dir& thePrincipalDir1, Standard_Real& theCurvature1,
//purpose : check the angle at the border between two squares.
// Two shares should have a shared front edge.
//=======================================================================
-static GeomAbs_Shape tgtfaces(const TopoDS_Edge& Ed,
- const TopoDS_Face& F1,
- const TopoDS_Face& F2,
- const Standard_Real theAngleTol)
+GeomAbs_Shape BRepLib::ContinuityOfFaces(const TopoDS_Edge& theEdge,
+ const TopoDS_Face& theFace1,
+ const TopoDS_Face& theFace2,
+ const Standard_Real theAngleTol)
{
- Standard_Boolean isSeam = F1.IsEqual(F2);
-
- TopoDS_Edge E = Ed;
+ Standard_Boolean isSeam = theFace1.IsEqual(theFace2);
- // Check if pcurves exist on both faces of edge
- Standard_Real aFirst,aLast;
- E.Orientation(TopAbs_FORWARD);
- Handle(Geom2d_Curve) aCurve1 = BRep_Tool::CurveOnSurface(E, F1, aFirst, aLast);
- if(aCurve1.IsNull())
- return GeomAbs_C0;
+ TopoDS_Edge anEdgeInFace1, anEdgeInFace2;
+ Handle(Geom2d_Curve) aCurve1, aCurve2;
+
+ Standard_Real aFirst, aLast;
+
+ if (!theFace1.IsSame (theFace2) &&
+ BRep_Tool::IsClosed (theEdge, theFace1) &&
+ BRep_Tool::IsClosed (theEdge, theFace2))
+ {
+ //Find the edge in the face 1: this edge will have correct orientation
+ TopoDS_Face aFace1 = theFace1;
+ aFace1.Orientation (TopAbs_FORWARD);
+ TopExp_Explorer anExplo (aFace1, TopAbs_EDGE);
+ for (; anExplo.More(); anExplo.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
+ if (anEdge.IsSame (theEdge))
+ {
+ anEdgeInFace1 = anEdge;
+ break;
+ }
+ }
+ if (anEdgeInFace1.IsNull())
+ return GeomAbs_C0;
+
+ aCurve1 = BRep_Tool::CurveOnSurface (anEdgeInFace1, aFace1, aFirst, aLast);
+ TopoDS_Face aFace2 = theFace2;
+ aFace2.Orientation (TopAbs_FORWARD);
+ anEdgeInFace2 = anEdgeInFace1;
+ anEdgeInFace2.Reverse();
+ aCurve2 = BRep_Tool::CurveOnSurface (anEdgeInFace2, aFace2, aFirst, aLast);
+ }
+ else
+ {
+ // Obtaining of pcurves of edge on two faces.
+ anEdgeInFace1 = anEdgeInFace2 = theEdge;
+ aCurve1 = BRep_Tool::CurveOnSurface (anEdgeInFace1, theFace1, aFirst, aLast);
+ //For the case of seam edge
+ if (theFace1.IsSame(theFace2))
+ anEdgeInFace2.Reverse();
+ aCurve2 = BRep_Tool::CurveOnSurface (anEdgeInFace2, theFace2, aFirst, aLast);
+ }
- if (isSeam)
- E.Orientation(TopAbs_REVERSED);
- Handle(Geom2d_Curve) aCurve2 = BRep_Tool::CurveOnSurface(E, F2, aFirst, aLast);
- if(aCurve2.IsNull())
+ if (aCurve1.IsNull() || aCurve2.IsNull())
return GeomAbs_C0;
TopLoc_Location aLoc1, aLoc2;
- Handle(Geom_Surface) aSurface1 = BRep_Tool::Surface(F1, aLoc1);
+ Handle(Geom_Surface) aSurface1 = BRep_Tool::Surface (theFace1, aLoc1);
const gp_Trsf& aSurf1Trsf = aLoc1.Transformation();
- Handle(Geom_Surface) aSurface2 = BRep_Tool::Surface(F2, aLoc2);
+ Handle(Geom_Surface) aSurface2 = BRep_Tool::Surface (theFace2, aLoc2);
const gp_Trsf& aSurf2Trsf = aLoc2.Transformation();
if (aSurface1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
return GeomAbs_CN;
}
- SurfaceProperties aSP1(aSurface1, aSurf1Trsf, aCurve1, F1.Orientation() == TopAbs_REVERSED);
- SurfaceProperties aSP2(aSurface2, aSurf2Trsf, aCurve2, F2.Orientation() == TopAbs_REVERSED);
+ SurfaceProperties aSP1(aSurface1, aSurf1Trsf, aCurve1, theFace1.Orientation() == TopAbs_REVERSED);
+ SurfaceProperties aSP2(aSurface2, aSurf2Trsf, aCurve2, theFace2.Orientation() == TopAbs_REVERSED);
Standard_Real f, l, eps;
- BRep_Tool::Range(E,f,l);
+ BRep_Tool::Range (theEdge,f,l);
Extrema_LocateExtPC ext;
Handle(BRepAdaptor_Curve) aHC2;
const Standard_Real anAngleTol2 = theAngleTol * theAngleTol;
gp_Vec aDer1, aDer2;
- gp_Vec aNorm1;
Standard_Real aSqLen1, aSqLen2;
gp_Dir aCrvDir1[2], aCrvDir2[2];
Standard_Real aCrvLen1[2], aCrvLen2[2];
aDer2 = aSP2.Derivative();
aSqLen2 = aDer2.SquareMagnitude();
Standard_Boolean isSmoothSuspect = (aDer1.CrossSquareMagnitude(aDer2) <= anAngleTol2 * aSqLen1 * aSqLen2);
+ if (isSmoothSuspect)
+ {
+ gp_Dir aNormal1 = aSP1.Normal();
+ if (theFace1.Orientation() == TopAbs_REVERSED)
+ aNormal1.Reverse();
+ gp_Dir aNormal2 = aSP2.Normal();
+ if (theFace2.Orientation() == TopAbs_REVERSED)
+ aNormal2.Reverse();
+
+ if (aNormal1 * aNormal2 < 0.)
+ return GeomAbs_C0;
+ }
+
if (!isSmoothSuspect)
{
// Refine by projection
if (aHC2.IsNull())
{
// adaptor for pcurve on the second surface
- aHC2 = new BRepAdaptor_Curve (E, F2);
+ aHC2 = new BRepAdaptor_Curve (anEdgeInFace2, theFace2);
ext.Initialize(*aHC2, f, l, Precision::PConfusion());
}
ext.Perform(aSP1.Value(), u);
BRep_Builder B;
if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0){
try {
- GeomAbs_Shape aCont = tgtfaces(E, F1, F2, TolAng);
+ GeomAbs_Shape aCont = ContinuityOfFaces(E, F1, F2, TolAng);
B.Continuity(E,F1,F2,aCont);
-
}
catch(Standard_Failure const&)
{
//! orientation to have matter in the solid. Returns
//! False if the solid is unOrientable (open or incoherent)
Standard_EXPORT static Standard_Boolean OrientClosedSolid (TopoDS_Solid& solid);
-
+
+ //! Returns the order of continuity between two faces
+ //! connected by an edge
+ Standard_EXPORT static GeomAbs_Shape ContinuityOfFaces(const TopoDS_Edge& theEdge,
+ const TopoDS_Face& theFace1,
+ const TopoDS_Face& theFace2,
+ const Standard_Real theAngleTol);
+
//! Encodes the Regularity of edges on a Shape.
//! Warning: <TolAng> is an angular tolerance, expressed in Rad.
//! Warning: If the edges's regularity are coded before, nothing
//function : IsTangentFaces
//purpose :
//=======================================================================
-Standard_Boolean ChFi3d::IsTangentFaces(const TopoDS_Edge& theEdge,
- const TopoDS_Face& theFace1,
- const TopoDS_Face& theFace2,
- const GeomAbs_Shape Order)
+Standard_Boolean ChFi3d::IsTangentFaces(const TopoDS_Edge& theEdge,
+ const TopoDS_Face& theFace1,
+ const TopoDS_Face& theFace2,
+ const GeomAbs_Shape theOrder)
{
- if (Order == GeomAbs_G1 && BRep_Tool::Continuity(theEdge, theFace1, theFace2) != GeomAbs_C0)
+ if (theOrder == 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);
- //For the case of seam edge
- TopoDS_Edge EE = theEdge;
- if (theFace1.IsSame(theFace2))
- EE.Reverse();
- const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
- (EE, theFace2, aFirst, aLast);
+ Handle(Geom2d_Curve) aC2d1, aC2d2;
+
+ if (!theFace1.IsSame (theFace2) &&
+ BRep_Tool::IsClosed (theEdge, theFace1) &&
+ BRep_Tool::IsClosed (theEdge, theFace2))
+ {
+ //Find the edge in the face 1: this edge will have correct orientation
+ TopoDS_Edge anEdgeInFace1;
+ TopoDS_Face aFace1 = theFace1;
+ aFace1.Orientation (TopAbs_FORWARD);
+ TopExp_Explorer anExplo (aFace1, TopAbs_EDGE);
+ for (; anExplo.More(); anExplo.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
+ if (anEdge.IsSame (theEdge))
+ {
+ anEdgeInFace1 = anEdge;
+ break;
+ }
+ }
+ if (anEdgeInFace1.IsNull())
+ return Standard_False;
+
+ aC2d1 = BRep_Tool::CurveOnSurface (anEdgeInFace1, aFace1, aFirst, aLast);
+ TopoDS_Face aFace2 = theFace2;
+ aFace2.Orientation (TopAbs_FORWARD);
+ anEdgeInFace1.Reverse();
+ aC2d2 = BRep_Tool::CurveOnSurface (anEdgeInFace1, aFace2, aFirst, aLast);
+ }
+ else
+ {
+ // Obtaining of pcurves of edge on two faces.
+ aC2d1 = BRep_Tool::CurveOnSurface (theEdge, theFace1, aFirst, aLast);
+ //For the case of seam edge
+ TopoDS_Edge EE = theEdge;
+ if (theFace1.IsSame(theFace2))
+ EE.Reverse();
+ aC2d2 = BRep_Tool::CurveOnSurface (EE, theFace2, aFirst, aLast);
+ }
+
if (aC2d1.IsNull() || aC2d2.IsNull())
return Standard_False;
if (i == aNbSamples) aPar = aLast;
LocalAnalysis_SurfaceContinuity aCont(aC2d1, aC2d2, aPar,
- aSurf1, aSurf2, Order,
+ aSurf1, aSurf2, theOrder,
0.001, TolC0, 0.1, 0.1, 0.1);
if (!aCont.IsDone())
{
+ if (theOrder == GeomAbs_C2 &&
+ aCont.StatusError() == LocalAnalysis_NullSecondDerivative)
+ continue;
+
nbNotDone++;
continue;
}
- if (Order == GeomAbs_G1)
+ if (theOrder == GeomAbs_G1)
{
if (!aCont.IsG1())
return Standard_False;
#include <Geom_TrimmedCurve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomConvert.hxx>
+#include <GeomConvert_ApproxSurface.hxx>
#include <GeomConvert_CompCurveToBSplineCurve.hxx>
#include <GeomLib_IsPlanarSurface.hxx>
#include <gp_Cylinder.hxx>
{
Standard_Real f, l;
// get 2d curve to get point in 2d
- const Handle(Geom2d_Curve)& aC2d = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
+ Handle(Geom2d_Curve) aC2d;
+ if (BRep_Tool::IsClosed(theEdge, theFace))
+ {
+ //Find the edge in the face: it will have correct orientation
+ TopoDS_Edge anEdgeInFace;
+ TopoDS_Face aFace = theFace;
+ aFace.Orientation (TopAbs_FORWARD);
+ TopExp_Explorer anExplo (aFace, TopAbs_EDGE);
+ for (; anExplo.More(); anExplo.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge (anExplo.Current());
+ if (anEdge.IsSame (theEdge))
+ {
+ anEdgeInFace = anEdge;
+ break;
+ }
+ }
+ if (anEdgeInFace.IsNull())
+ return Standard_False;
+
+ aC2d = BRep_Tool::CurveOnSurface (anEdgeInFace, aFace, f, l);
+ }
+ else
+ aC2d = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l);
+
if (aC2d.IsNull()) {
return Standard_False;
}
TopTools_IndexedDataMapOfShapeListOfShape VEmap;
for (Standard_Integer ind = 1; ind <= edges.Length(); ind++)
TopExp::MapShapesAndUniqueAncestors(edges(ind), TopAbs_VERTEX, TopAbs_EDGE, VEmap);
-
- //Perform relocating to new U-origin
- //Define boundaries in 2d space of RefFace
- if (Uperiod != 0.)
+
+ //Try to find seam edge and an edge that is not seam but has 2 pcurves on the surface
+ Standard_Boolean SeamFound = Standard_False;
+ TopoDS_Edge EdgeWith2pcurves;
+ for (Standard_Integer ii = 1; ii <= faces.Length(); ii++)
{
- //try to find a real seam edge - if it exists, do nothing
- Standard_Boolean SeamFound = Standard_False;
- for (Standard_Integer ii = 1; ii <= faces.Length(); ii++)
+ const TopoDS_Face& face_ii = TopoDS::Face(faces(ii));
+ TopoDS_Wire anOuterWire = BRepTools::OuterWire(face_ii);
+ TopoDS_Iterator itw(anOuterWire);
+ for (; itw.More(); itw.Next())
{
- const TopoDS_Face& face_ii = TopoDS::Face(faces(ii));
- TopoDS_Wire anOuterWire = BRepTools::OuterWire(face_ii);
- TopoDS_Iterator itw(anOuterWire);
- for (; itw.More(); itw.Next())
+ const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
+ if (BRep_Tool::IsClosed (anEdge, face_ii))
{
- const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
if (BRepTools::IsReallyClosed(anEdge, face_ii))
- {
SeamFound = Standard_True;
- break;
+ else
+ EdgeWith2pcurves = anEdge;
+ }
+ }
+ }
+
+ Standard_Boolean aIsEdgeWith2pcurvesSmooth = Standard_False;
+ if (myConcatBSplines && !EdgeWith2pcurves.IsNull() && !SeamFound)
+ {
+ const TopTools_ListOfShape& aFaceList = theGMapEdgeFaces.FindFromKey (EdgeWith2pcurves);
+ const TopoDS_Face& aFace1 = TopoDS::Face (aFaceList.First());
+ const TopoDS_Face& aFace2 = TopoDS::Face (aFaceList.Last());
+ GeomAbs_Shape anOrderOfCont = BRepLib::ContinuityOfFaces (EdgeWith2pcurves,
+ aFace1, aFace2,
+ myAngTol);
+ aIsEdgeWith2pcurvesSmooth = (anOrderOfCont >= GeomAbs_G1);
+ }
+
+ if (aIsEdgeWith2pcurvesSmooth)
+ {
+ Handle(Geom2d_Curve) aPC1, aPC2;
+ Standard_Real aFirst, aLast;
+ aPC1 = BRep_Tool::CurveOnSurface (EdgeWith2pcurves, F_RefFace, aFirst, aLast);
+ EdgeWith2pcurves.Reverse();
+ aPC2 = BRep_Tool::CurveOnSurface (EdgeWith2pcurves, F_RefFace, aFirst, aLast);
+ gp_Pnt2d aPnt1 = aPC1->Value (aFirst);
+ gp_Pnt2d aPnt2 = aPC2->Value (aFirst);
+ Standard_Boolean anIsUclosed = (Abs(aPnt1.X() - aPnt2.X()) > Abs(aPnt1.Y() - aPnt2.Y()));
+ Standard_Boolean aToMakeUPeriodic = Standard_False, aToMakeVPeriodic = Standard_False;
+ if (anIsUclosed && Uperiod == 0.)
+ aToMakeUPeriodic = Standard_True;
+ if (!anIsUclosed && Vperiod == 0.)
+ aToMakeVPeriodic = Standard_True;
+
+ if (aToMakeUPeriodic || aToMakeVPeriodic)
+ {
+ Handle(Geom_BSplineSurface) aBSplineSurface = Handle(Geom_BSplineSurface)::DownCast(aBaseSurface);
+ if (aBSplineSurface.IsNull())
+ {
+ Standard_Real aTol = 1.e-4;
+ GeomAbs_Shape aUCont = GeomAbs_C1, aVCont = GeomAbs_C1;
+ Standard_Integer degU = 14, degV = 14;
+ Standard_Integer nmax = 16;
+ Standard_Integer aPrec = 1;
+ GeomConvert_ApproxSurface Approximator(aBaseSurface,aTol,aUCont,aVCont,degU,degV,nmax,aPrec);
+ aBSplineSurface = Approximator.Surface();
+ }
+
+ if (aToMakeUPeriodic)
+ {
+ aBSplineSurface->SetUPeriodic();
+ Uperiod = aBSplineSurface->UPeriod();
+ }
+ if (aToMakeVPeriodic)
+ {
+ aBSplineSurface->SetVPeriodic();
+ Vperiod = aBSplineSurface->VPeriod();
+ }
+
+ //Update ref face and pcurves if the surface changed
+ if (aBSplineSurface != aBaseSurface)
+ {
+ TopoDS_Face OldRefFace = RefFace;
+ Handle(Geom2d_Curve) NullPCurve;
+ RefFace.Nullify();
+ BB.MakeFace(RefFace, aBSplineSurface, aBaseLocation, 0.);
+ for (Standard_Integer ii = 1; ii <= edges.Length(); ii++)
+ {
+ TopoDS_Edge anEdge = TopoDS::Edge(edges(ii));
+ Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (anEdge, OldRefFace, aFirst, aLast);
+ if (MapEdgesWithTemporaryPCurves.Contains(anEdge))
+ BB.UpdateEdge(anEdge, NullPCurve, OldRefFace, 0.);
+ BB.UpdateEdge(anEdge, aPCurve, RefFace, 0.);
}
+ F_RefFace = RefFace;
+ F_RefFace.Orientation(TopAbs_FORWARD);
}
}
-
+ } //if (myConcatBSplines && !EdgeWith2pcurves.IsNull() && !SeamFound)
+
+ //Perform relocating to new U-origin
+ //Define boundaries in 2d space of RefFace
+ if (Uperiod != 0.)
+ {
+ //if seam edge exists, do nothing
if (!SeamFound)
{
//try to find the origin of U in 2d space
+++ /dev/null
-puts "================================================================================"
-puts "OCC29382: ShapeUpgrade_UnifySameDomain algorithm incorrectly processes the shape"
-puts "================================================================================"
-puts ""
-
-restore [locate_data_file bug29382_Group_3.brep] a
-
-unifysamedom result a
-
-checkshape result
-checkshape a
-
-checknbshapes result -solid 3 -shell 3 -face 18 -wire 18 -edge 36 -vertex 22
-
-set tolres [checkmaxtol result]
-
-if { ${tolres} > 1.8066863810061599e-05} {
- puts "Error: bad tolerance of result"
-}
-
-explode result
-checkprops result_1 -v 4.41996e-06
-checkprops result_2 -v 1.30453e-06
-checkprops result_3 -v 1.16532e-06
--- /dev/null
+puts "================================================================================"
+puts "OCC29382: ShapeUpgrade_UnifySameDomain algorithm incorrectly processes the shape"
+puts "================================================================================"
+puts ""
+
+restore [locate_data_file bug29382_Group_3.brep] a
+
+unifysamedom result a
+
+checkshape result
+checkshape a
+
+checknbshapes result -solid 3 -shell 3 -face 18 -wire 18 -edge 36 -vertex 22
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 1.8066863810061599e-05} {
+ puts "Error: bad tolerance of result"
+}
+
+explode result
+checkprops result_1 -v 4.41996e-06
+checkprops result_2 -v 1.30453e-06
+checkprops result_3 -v 1.16532e-06
--- /dev/null
+puts "================================================================================"
+puts "OCC29382: ShapeUpgrade_UnifySameDomain algorithm incorrectly processes the shape"
+puts "================================================================================"
+puts ""
+
+restore [locate_data_file bug29382_Group_3.brep] a
+
+unifysamedom result a +b
+
+checkshape result
+checkshape a
+
+checknbshapes result -solid 3 -shell 3 -face 16 -wire 16 -edge 30 -vertex 18
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 1.8066863810061599e-05} {
+ puts "Error: bad tolerance of result"
+}
+
+explode result
+checkprops result_1 -v 4.41996e-06
+checkprops result_2 -v 1.30453e-06
+checkprops result_3 -v 1.16532e-06
--- /dev/null
+puts "================================================================================"
+puts "OCC29382: ShapeUpgrade_UnifySameDomain algorithm incorrectly processes the shape"
+puts "================================================================================"
+puts ""
+
+beziercurve a 5 0 0 0 1 0 0 2 2 0 0 0.5 0 0 0 0
+mkedge a a
+wire a a
+mkplane a a
+prism a a 0 0 1
+box b -0.3 -0.2 0 1 0.4 1
+bcommon shape a b
+
+unifysamedom result shape +b
+
+checkshape result
+
+checknbshapes result -solid 1 -shell 1 -face 5 -wire 5 -edge 9 -vertex 5
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 6.e-6} {
+ puts "Error: bad tolerance of result"
+}