mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-31 11:15:31 +03:00
0026440: Invalid shape as a result of solid construction in BRepOffset_MakeOffset
Fixed degeneration in wall building in thicksolid mode.
This commit is contained in:
parent
574ea6faba
commit
b01be5abf8
@ -238,5 +238,7 @@ fields
|
|||||||
|
|
||||||
myMakeLoops : MakeLoops from BRepOffset;
|
myMakeLoops : MakeLoops from BRepOffset;
|
||||||
myBadShape : Shape from TopoDS;
|
myBadShape : Shape from TopoDS;
|
||||||
|
myIsPerformSewing: Boolean from Standard; -- Handle bad walls in thicksolid mode.
|
||||||
|
|
||||||
|
|
||||||
end MakeOffset;
|
end MakeOffset;
|
||||||
|
@ -119,6 +119,8 @@
|
|||||||
// POP for NT
|
// POP for NT
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <NCollection_Vector.hxx>
|
#include <NCollection_Vector.hxx>
|
||||||
|
#include <BRepBuilderAPI_Sewing.hxx>
|
||||||
|
#include <Geom_Line.hxx>
|
||||||
|
|
||||||
#ifdef DRAW
|
#ifdef DRAW
|
||||||
|
|
||||||
@ -532,6 +534,7 @@ void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S,
|
|||||||
myJoin = Join;
|
myJoin = Join;
|
||||||
myThickening = Thickening;
|
myThickening = Thickening;
|
||||||
myDone = Standard_False;
|
myDone = Standard_False;
|
||||||
|
myIsPerformSewing = Standard_False;
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,6 +670,7 @@ static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : MakeOffsetShape
|
//function : MakeOffsetShape
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -769,6 +773,14 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
|
|||||||
|
|
||||||
CorrectConicalFaces();
|
CorrectConicalFaces();
|
||||||
|
|
||||||
|
if (myIsPerformSewing)
|
||||||
|
{
|
||||||
|
BRepBuilderAPI_Sewing aSew(myTol);
|
||||||
|
aSew.Add(myOffsetShape);
|
||||||
|
aSew.Perform();
|
||||||
|
myOffsetShape = aSew.SewedShape();
|
||||||
|
}
|
||||||
|
|
||||||
myDone = Standard_True;
|
myDone = Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2482,7 +2494,6 @@ static void UpdateInitOffset (BRepAlgo_Image& myInitOffset,
|
|||||||
//function : MakeMissingWalls
|
//function : MakeMissingWalls
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
void BRepOffset_MakeOffset::MakeMissingWalls ()
|
void BRepOffset_MakeOffset::MakeMissingWalls ()
|
||||||
{
|
{
|
||||||
TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
|
TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
|
||||||
@ -2501,23 +2512,59 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
|
|||||||
Standard_Boolean FirstStep = Standard_True;
|
Standard_Boolean FirstStep = Standard_True;
|
||||||
TopoDS_Edge PrevEdge;
|
TopoDS_Edge PrevEdge;
|
||||||
TopoDS_Vertex PrevVertex = StartVertex;
|
TopoDS_Vertex PrevVertex = StartVertex;
|
||||||
|
Standard_Boolean isBuildFromScratch = Standard_False; // Problems with edges.
|
||||||
for (; itl.More(); itl.Next())
|
for (; itl.More(); itl.Next())
|
||||||
{
|
{
|
||||||
TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
|
TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
|
||||||
|
|
||||||
|
// Check for offset existence.
|
||||||
if (!myInitOffsetEdge.HasImage(anEdge))
|
if (!myInitOffsetEdge.HasImage(anEdge))
|
||||||
continue;
|
continue;
|
||||||
//if (BRep_Tool::Degenerated(anEdge))
|
|
||||||
//continue;
|
// Check for existence of two different vertices.
|
||||||
TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
|
|
||||||
//TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First());
|
|
||||||
TopTools_ListOfShape LOE, LOE2;
|
TopTools_ListOfShape LOE, LOE2;
|
||||||
myInitOffsetEdge.LastImage( anEdge, LOE );
|
myInitOffsetEdge.LastImage( anEdge, LOE );
|
||||||
myImageOffset.LastImage( LOE.Last(), LOE2 );
|
myImageOffset.LastImage( LOE.Last(), LOE2 );
|
||||||
TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
|
TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
TopoDS_Vertex V1, V2, V3, V4;
|
TopoDS_Vertex V1, V2, V3, V4;
|
||||||
TopExp::Vertices(anEdge, V1, V2/*, Standard_True*/);
|
TopExp::Vertices(OE, V4, V3);
|
||||||
TopExp::Vertices(OE, V4, V3/*, Standard_True*/);
|
TopExp::Vertices(anEdge, V1, V2);
|
||||||
|
Standard_Real aF, aL;
|
||||||
|
const Handle(Geom_Curve) &aC = BRep_Tool::Curve(anEdge, aF, aL);
|
||||||
|
if (!aC.IsNull() &&
|
||||||
|
(!aC->IsClosed() && !aC->IsPeriodic()))
|
||||||
|
{
|
||||||
|
gp_Pnt aPntF = BRep_Tool::Pnt(V1);
|
||||||
|
gp_Pnt aPntL = BRep_Tool::Pnt(V2);
|
||||||
|
Standard_Real aDistE = aPntF.SquareDistance(aPntL);
|
||||||
|
if ( aDistE < Precision::SquareConfusion())
|
||||||
|
{
|
||||||
|
// Bad case: non closed, but vertexes mapped to same 3d point.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Real anEdgeTol = BRep_Tool::Tolerance(anEdge);
|
||||||
|
if (aDistE < anEdgeTol)
|
||||||
|
{
|
||||||
|
// Potential problems not detected via checkshape.
|
||||||
|
gp_Pnt aPntOF = BRep_Tool::Pnt(V4);
|
||||||
|
gp_Pnt aPntOL = BRep_Tool::Pnt(V3);
|
||||||
|
if (aPntOF.SquareDistance(aPntOL) > gp::Resolution())
|
||||||
|
{
|
||||||
|
Standard_Real anAngle = gp_Vec(aPntF, aPntL).Angle(gp_Vec(aPntOF, aPntOL));
|
||||||
|
if (aC->DynamicType() == STANDARD_TYPE(Geom_Line) &&
|
||||||
|
Abs (anAngle - M_PI_2) < anEdgeTol) // For small values sin is equal to its argument.
|
||||||
|
{
|
||||||
|
// anEdge near perpendicular to offseting surface.
|
||||||
|
isBuildFromScratch = Standard_True;
|
||||||
|
myIsPerformSewing = Standard_True;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
|
||||||
Standard_Boolean ToReverse = Standard_False;
|
Standard_Boolean ToReverse = Standard_False;
|
||||||
if (!V1.IsSame(PrevVertex))
|
if (!V1.IsSame(PrevVertex))
|
||||||
{
|
{
|
||||||
@ -2525,23 +2572,30 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
|
|||||||
aVtx = V3; V3 = V4; V4 = aVtx;
|
aVtx = V3; V3 = V4; V4 = aVtx;
|
||||||
ToReverse = Standard_True;
|
ToReverse = Standard_True;
|
||||||
}
|
}
|
||||||
//Temporary
|
|
||||||
//anEdge.Reverse();
|
|
||||||
OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
|
OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
|
||||||
TopoDS_Edge E3, E4;
|
TopoDS_Edge E3, E4;
|
||||||
if (FirstStep)
|
Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
|
||||||
|
if (FirstStep || isBuildFromScratch)
|
||||||
{
|
{
|
||||||
E4 = BRepLib_MakeEdge( V1, V4 );
|
E4 = BRepLib_MakeEdge( V1, V4 );
|
||||||
|
if (FirstStep)
|
||||||
StartEdge = E4;
|
StartEdge = E4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
E4 = PrevEdge;
|
E4 = PrevEdge;
|
||||||
Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
|
|
||||||
if (V2.IsSame(StartVertex) && !ArcOnV2)
|
if (V2.IsSame(StartVertex) && !ArcOnV2)
|
||||||
E3 = StartEdge;
|
E3 = StartEdge;
|
||||||
else
|
else
|
||||||
E3 = BRepLib_MakeEdge( V2, V3 );
|
E3 = BRepLib_MakeEdge( V2, V3 );
|
||||||
E4.Reverse();
|
E4.Reverse();
|
||||||
|
|
||||||
|
if (isBuildFromScratch)
|
||||||
|
{
|
||||||
|
E3.Reverse();
|
||||||
|
E4.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
|
TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
|
||||||
const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
|
const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
|
||||||
Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
|
Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
|
||||||
@ -2563,6 +2617,7 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
|
|||||||
BB.Add(theWire, OE);
|
BB.Add(theWire, OE);
|
||||||
BB.Add(theWire, E4);
|
BB.Add(theWire, E4);
|
||||||
}
|
}
|
||||||
|
|
||||||
BRepLib::BuildCurves3d( theWire, myTol );
|
BRepLib::BuildCurves3d( theWire, myTol );
|
||||||
theWire.Closed(Standard_True);
|
theWire.Closed(Standard_True);
|
||||||
TopoDS_Face NewFace;
|
TopoDS_Face NewFace;
|
||||||
@ -2842,9 +2897,18 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (isBuildFromScratch)
|
||||||
|
{
|
||||||
|
PrevEdge = TopoDS::Edge(E4);
|
||||||
|
PrevVertex = V1;
|
||||||
|
isBuildFromScratch = Standard_False;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
PrevEdge = E3;
|
PrevEdge = E3;
|
||||||
PrevVertex = V2;
|
PrevVertex = V2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
FirstStep = Standard_False;
|
FirstStep = Standard_False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user