Synchronization of the ShapeAnalysis_Edge behavior with the BRepCheck_Edge by adding check for 2d curves on planes.
Implementation of the BRep_Tool::CurveOnPlane method to avoid code duplication for making PCurve of the edge on planar face.
itcr.Next();
}
- // for planar surface and 3d curve try a projection
- // modif 21-05-97 : for RectangularTrimmedSurface, try a projection
+ // Curve is not found. Try projection on plane
+ return CurveOnPlane(E, S, L, First, Last);
+}
+
+//=======================================================================
+//function : CurveOnPlane
+//purpose : For planar surface returns projection of the edge on the plane
+//=======================================================================
+Handle(Geom2d_Curve) BRep_Tool::CurveOnPlane(const TopoDS_Edge& E,
+ const Handle(Geom_Surface)& S,
+ const TopLoc_Location& L,
+ Standard_Real& First,
+ Standard_Real& Last)
+{
+ First = Last = 0.;
+
+ // Check if the surface is planar
Handle(Geom_Plane) GP;
Handle(Geom_RectangularTrimmedSurface) GRTS;
GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
else
GP = Handle(Geom_Plane)::DownCast(S);
- //fin modif du 21-05-97
-
- if (!GP.IsNull())
- {
- Handle(GeomAdaptor_HCurve) HC;
- Handle(GeomAdaptor_HSurface) HS;
-
- HC = new GeomAdaptor_HCurve();
- HS = new GeomAdaptor_HSurface();
- TopLoc_Location aCurveLocation;
+ if (GP.IsNull())
+ // not a plane
+ return nullPCurve;
- Standard_Real f, l;// for those who call with (u,u).
- Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, aCurveLocation, f, l);
+ // Check existence of 3d curve in edge
+ Standard_Real f, l;
+ TopLoc_Location aCurveLocation;
+ Handle(Geom_Curve) C3D = BRep_Tool::Curve(E, aCurveLocation, f, l);
- if (C3d.IsNull())
- {
- First = Last = 0.;
- return nullPCurve;
- }
-
- aCurveLocation = aCurveLocation.Predivided(L);
- First = f; Last = l; //Range of edge must not be modified
+ if (C3D.IsNull())
+ // no 3d curve
+ return nullPCurve;
- if (!aCurveLocation.IsIdentity())
- {
- const gp_Trsf& T = aCurveLocation.Transformation();
- Handle(Geom_Geometry) GC3d = C3d->Transformed(T);
- C3d = Handle(Geom_Curve)::DownCast (GC3d);
- f = C3d->TransformedParameter(f, T);
- l = C3d->TransformedParameter(l, T);
- }
- GeomAdaptor_Surface& GAS = HS->ChangeSurface();
- GAS.Load(GP);
+ aCurveLocation = aCurveLocation.Predivided(L);
+ First = f; Last = l;
- Handle(Geom_Curve) ProjOnPlane =
- GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l,Standard_True,Standard_False),
- GP,
- GP->Position().Direction(),
- Standard_True);
+ // Transform curve and update parameters in account of scale factor
+ if (!aCurveLocation.IsIdentity())
+ {
+ const gp_Trsf& aTrsf = aCurveLocation.Transformation();
+ C3D = Handle(Geom_Curve)::DownCast(C3D->Transformed(aTrsf));
+ f = C3D->TransformedParameter(f, aTrsf);
+ l = C3D->TransformedParameter(l, aTrsf);
+ }
- GeomAdaptor_Curve& GAC = HC->ChangeCurve();
- GAC.Load(ProjOnPlane);
+ // Perform projection
+ Handle(Geom_Curve) ProjOnPlane =
+ GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3D, f, l, Standard_True, Standard_False),
+ GP,
+ GP->Position().Direction(),
+ Standard_True);
- ProjLib_ProjectedCurve Proj(HS,HC);
- Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
+ Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(GP);
+ Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(ProjOnPlane);
- if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
- Handle(Geom2d_TrimmedCurve) TC =
- Handle(Geom2d_TrimmedCurve)::DownCast (pc);
- pc = TC->BasisCurve();
- }
+ ProjLib_ProjectedCurve Proj(HS, HC);
+ Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
- return pc;
+ if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
+ Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(pc);
+ pc = TC->BasisCurve();
}
-
- First = Last = 0.;
- return nullPCurve;
+
+ return pc;
}
//=======================================================================
Standard_Real& Last,
const Standard_Integer Index)
{
- Standard_Integer i = 0;
- Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
+ if (Index < 1)
+ return;
+ Standard_Integer i = 0;
// find the representation
const BRep_TEdge* TE = static_cast<const BRep_TEdge*>(E.TShape().get());
BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
-
- while (itcr.More()) {
+ for (; itcr.More(); itcr.Next())
+ {
const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
- if (cr->IsCurveOnSurface()) {
+ if (cr->IsCurveOnSurface())
+ {
const BRep_GCurve* GC = static_cast<const BRep_GCurve*>(cr.get());
- i++;
- if (i > Index) break;
- if (i == Index) {
- // JMB le 21 Mai 1999
- // it is done as in the other CurveOnSurface methods, ie. take into account
- // the orientation in case of cut edges (return PCurve2)
- // otherwise there is a risk to loop curves or to not get the prover one.
- if (GC->IsCurveOnClosedSurface() && Eisreversed)
- C = GC->PCurve2();
- else
- C = GC->PCurve();
- S = GC->Surface();
- L = E.Location() * GC->Location();
- GC->Range(First,Last);
- return;
- }
+ ++i;
+ // Compare index taking into account the fact that for the curves on
+ // closed surfaces there are two PCurves
+ if (i == Index)
+ C = GC->PCurve();
+ else if (GC->IsCurveOnClosedSurface() && (++i == Index))
+ C = GC->PCurve2();
+ else
+ continue;
+
+ S = GC->Surface();
+ L = E.Location() * GC->Location();
+ GC->Range(First, Last);
+ return;
}
- itcr.Next();
}
C.Nullify();
//! handle if this curve does not exist. Returns in
//! <First> and <Last> the parameter range.
Standard_EXPORT static Handle(Geom2d_Curve) CurveOnSurface (const TopoDS_Edge& E, const Handle(Geom_Surface)& S, const TopLoc_Location& L, Standard_Real& First, Standard_Real& Last);
+
+ //! For the planar surface builds the 2d curve for the edge
+ //! by projection of the edge on plane.
+ //! Returns a NULL handle if the surface is not planar or
+ //! the projection failed.
+ Standard_EXPORT static Handle(Geom2d_Curve) CurveOnPlane (const TopoDS_Edge& E,
+ const Handle(Geom_Surface)& S,
+ const TopLoc_Location& L,
+ Standard_Real& First,
+ Standard_Real& Last);
//! Returns in <C>, <S>, <L> a 2d curve, a surface and
//! a location for the edge <E>. <C> and <S> are null
if (BRep_Tool::Degenerated (edge)) return Standard_False;
maxdev = 0;
-
+
+ // Get same parameter flag
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
Standard_Boolean SameParameter = TE->SameParameter();
- GeomAdaptor_Curve AC3d;
-
- // find 3d curve
- BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
- for ( ; itcr.More(); itcr.Next() ) {
- Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
- if ( GC.IsNull() || ! GC->IsCurve3D() ) continue;
- Handle(Geom_Curve) C3d = GC->Curve3D();
- if ( C3d.IsNull() ) continue; //:s1 abv 22 Apr 99: PRO7226 #489490
- TopLoc_Location loc = GC->Location();
- if ( ! loc.IsIdentity() )
- C3d = Handle(Geom_Curve)::DownCast ( C3d->Transformed ( loc ) );
- else C3d = Handle(Geom_Curve)::DownCast ( C3d->Copy() ); //:s4 abv 26 Apr 99: sim6049.igs 21677: necessary to get True SP (!!?)
- Standard_Real First, Last;
- GC->Range ( First, Last );
- AC3d.Load ( C3d, First, Last );
- break;
- }
-
- if ( ! itcr.More() ) {
- myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
+ // Get 3D curve of the edge
+ Standard_Real aFirst, aLast;
+ TopLoc_Location aCurveLoc;
+ Handle(Geom_Curve) aC3D = BRep_Tool::Curve(edge, aCurveLoc, aFirst, aLast);
+ if (aC3D.IsNull()) {
+ myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
return Standard_False;
}
- Handle(Geom_Surface) aFaceSurf;
- TopLoc_Location L;
- if ( !face.IsNull() )
+ if (!aCurveLoc.IsIdentity())
{
- aFaceSurf = BRep_Tool::Surface(face, L);
+ const gp_Trsf& aTrsf = aCurveLoc.Transformation();
+ aC3D = Handle(Geom_Curve)::DownCast(aC3D->Transformed(aTrsf));
+ aFirst = aC3D->TransformedParameter(aFirst, aTrsf);
+ aLast = aC3D->TransformedParameter(aLast, aTrsf);
}
- // iterate on pcurves
- itcr.Initialize ( TE->Curves() );
- for ( ; itcr.More(); itcr.Next() )
+ // Create adaptor for the curve
+ GeomAdaptor_Curve aGAC(aC3D, aFirst, aLast);
+
+ Handle(Geom_Surface) aFaceSurf;
+ TopLoc_Location aFaceLoc;
+ if (!face.IsNull())
+ aFaceSurf = BRep_Tool::Surface(face, aFaceLoc);
+
+ Standard_Boolean IsPCurveFound = Standard_False;
+ Standard_Integer i = 1;
+
+ // Iterate on all curve representations
+ for (;;)
{
- Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
- if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
+ Handle(Geom2d_Curve) aPC;
+ Handle(Geom_Surface) aS;
+ TopLoc_Location aLoc;
+ Standard_Real f, l;
+
+ BRep_Tool::CurveOnSurface(edge, aPC, aS, aLoc, f, l, i);
+
+ if (aPC.IsNull())
+ // No more curves
+ break;
+
+ ++i;
- if ( !(face.IsNull()) ) // Face is not null.
+ // If the input face is not null, check that the curve is on its surface
+ if (!aFaceSurf.IsNull())
{
- // Check for different surface.
- if (!GC->IsCurveOnSurface(aFaceSurf, GC->Location()))
+ if (aFaceSurf != aS || aFaceLoc != aLoc)
+ {
continue;
+ }
}
- Standard_Real f, l;
- GC->Range ( f, l );
- Handle(Geom_Surface) Su = GC->Surface();
- TopLoc_Location loc = GC->Location();
- if (!loc.IsIdentity())
- Su = Handle(Geom_Surface)::DownCast ( Su->Transformed ( loc ) );
- Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Su);
-
- Handle(Geom2d_Curve) PC = GC->PCurve();
- Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l);
- //Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
- Adaptor3d_CurveOnSurface ACS;
- ACS.Load(GHPC, GAHS);
- if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) )
+ IsPCurveFound = Standard_True;
+
+ // Apply transformations for the surface
+ Handle(Geom_Surface) aST = Handle(Geom_Surface)::
+ DownCast(aS->Transformed(aLoc.Transformation()));
+
+ // Compute deviation between curves
+ Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(aPC, f, l);
+ Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aST);
+
+ Adaptor3d_CurveOnSurface ACS(GHPC, GAHS);
+ if (!ComputeDeviation(aGAC, ACS, SameParameter, maxdev, NbControl - 1))
{
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
}
+ }
- if ( GC->IsCurveOnClosedSurface() )
+ // For the planar face and non-existing 2d curve
+ // check the deviation for the projection of the 3d curve on plane
+ if (!IsPCurveFound && !aFaceSurf.IsNull())
+ {
+ Standard_Real f, l;
+ Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnPlane(edge, aFaceSurf, aFaceLoc, f, l);
+ if (!aPC.IsNull())
{
- GHPC->ChangeCurve2d().Load ( GC->PCurve2(), f, l ); // same bounds
- ACS.Load(GHPC, GAHS); // sans doute inutile
- if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) )
+ Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(aPC, aFirst, aLast);
+
+ Handle(Geom_Surface) aST =
+ Handle(Geom_Surface)::DownCast(aFaceSurf->Transformed(aFaceLoc.Transformation()));
+ Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aST);
+
+ Adaptor3d_CurveOnSurface ACS(GHPC, GAHS);
+
+ if (!ComputeDeviation(aGAC, ACS, SameParameter, maxdev, NbControl - 1))
{
- myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
+ myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
}
}
}
-
- if ( maxdev > TE->Tolerance() )
- myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
- if ( ! SameParameter )
- myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
+
+ if (maxdev > TE->Tolerance())
+ myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE1);
+ if (!SameParameter)
+ myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2);
return Status ( ShapeExtend_DONE );
}
-
//=======================================================================
//function : IsOverlapPartEdges
//purpose :
-puts "TODO OCC27004 ALL: Faulty shapes in variables faulty_1 to"
-
puts "========"
puts "OCC27004"
puts "========"
checkshape result
+checknbshapes result -vertex 12 -edge 18 -wire 8 -face 8 -solid 1
+checkprops result -s 223704 -v 3.27888e+006
+
checkview -display result -2d -path ${imagedir}/${test_image}.png
--- /dev/null
+puts "======="
+puts "0028995"
+puts "======="
+puts ""
+##################################################
+# UnifySameDomain produces invalid shape
+##################################################
+
+brestore [locate_data_file bug28995_s1.brep] s1
+brestore [locate_data_file bug28995_s2.brep] s2
+
+# perform fuse operation
+bfuse rfuse s1 s2
+
+# check the result of fuse
+checkshape rfuse
+
+if {![regexp "This shape seems to be OK" [bopcheck rfuse]]} {
+ puts "Error: The result of FUSE operation is a self-intersecting shape."
+}
+
+# unify faces and edges in the fused shape
+unifysamedom result rfuse
+
+# check unified result
+checkshape result
+
+if {![regexp "This shape seems to be OK" [bopcheck result]]} {
+ puts "Error: The result of UnifySameDomain algorithm is a self-intersecting shape."
+}
+
+checknbshapes result -vertex 200 -edge 300 -wire 104 -face 103 -solid 1
+checkprops result -s 1.59154e+006 -v 1.1497e+007
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
-# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR23096 ALL: CHECKSHAPE : Faulty"
puts "TODO CR23096 ALL: STATSHAPE : Faulty"
-puts "TODO OCC28995 ALL: Faulty shapes"
-
puts "======="
puts "0028913"
puts "======="
-puts "TODO OCC28995 ALL: Faulty shapes"
-
puts "======="
puts "0028913"
puts "======="