1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0025509: Wrong shape considered as valid by checkshape

New features:

1. class BRepCheck_Solid
The class is to check a solid per se.
The scan area is:
 i.  Shells that overlaps each other
     Status:  BRepCheck_InvalidImbricationOfShells

 ii.  Detached parts of the solid (vertices, edges)
       that have non-internal orientation
       Status:  BRepCheck_BadOrientationOfSubshape

 iii.  For closed, non-internal shells:
 iii.1 Shells containing entities  of the solid that
      are outside towards the shells
      Status:  BRepCheck_SubshapeNotInShape

 iii.2 Shells that encloses other Shells
     (for non-holes)
      Status:  BRepCheck_EnclosedRegion

Changes:

1. enumeration BRepCheck_Status
members:
 InvalidImbricationOfShells,
 EnclosedRegion,
has been added

2. class BRepCheck
method:
void BRepCheck::Print(const BRepCheck_Status stat,
                      Standard_OStream& OS)
has been modified to take into account II.1

3. class BRepCheck_Analyzer
method:
void BRepCheck_Analyzer::Put(const TopoDS_Shape& S,
                             const Standard_Boolean B)
has been modified to take into account I.1

4. class BRepTest
function:
void StructuralDump(Draw_Interpretor& theCommands,
 const BRepCheck_Analyzer &theAna,
 const Standard_CString   ShName,
 const Standard_CString   Pref,
 const TopoDS_Shape       &theShape)
has been modified to take into account I.1, II.1

Test cases for issue CR25509

Correction of test cases for issue CR25509
This commit is contained in:
pkv
2014-12-11 16:53:12 +03:00
committed by bugmaster
parent ccadc126ba
commit 949df2b64b
17 changed files with 715 additions and 78 deletions

View File

@@ -16,8 +16,8 @@
package BRepCheck
---Purpose: This package provides tools to check the validity
-- of the BRep.
---Purpose: This package provides tools to check the validity
-- of the BRep.
uses MMgt,
StdFail,
@@ -41,9 +41,9 @@ is
class Face; -- inherits Shape
class Shell; -- inherits Shape
-- class Solid; -- inherits Shape
class Solid;
class Analyzer;
@@ -87,6 +87,8 @@ is
EmptyShell,
RedundantFace,
-- for solids
InvalidImbricationOfShells,
-- for shapes
UnorientableShape,
@@ -100,11 +102,14 @@ is
InvalidPolygonOnTriangulation,
InvalidToleranceValue,
InvalidToleranceValue,
EnclosedRegion,
-- for exception
CheckFail
end Status;
@@ -113,16 +118,16 @@ is
class DataMapOfShapeListOfStatus instantiates DataMap from TCollection
(Shape from TopoDS,
ListOfStatus from BRepCheck,
ListOfStatus from BRepCheck,
ShapeMapHasher from TopTools);
class DataMapOfShapeResult instantiates DataMap from TCollection
(Shape from TopoDS,
Result from BRepCheck,
(Shape from TopoDS,
Result from BRepCheck,
OrientedShapeMapHasher from TopTools);
-- Package method
Add(List: in out ListOfStatus from BRepCheck;
@@ -134,7 +139,7 @@ is
OS: in out OStream from Standard);
SelfIntersection(W : Wire from TopoDS;
F : Face from TopoDS;
F : Face from TopoDS;
E1 : out Edge from TopoDS;
E2 : out Edge from TopoDS)
returns Boolean from Standard;

View File

@@ -29,7 +29,6 @@
//function : Add
//purpose :
//=======================================================================
void BRepCheck::Add(BRepCheck_ListOfStatus& lst, const BRepCheck_Status stat)
{
BRepCheck_ListIteratorOfListOfStatus it(lst);
@@ -39,40 +38,32 @@ void BRepCheck::Add(BRepCheck_ListOfStatus& lst, const BRepCheck_Status stat)
}
else {
if (it.Value() == stat) {
return;
return;
}
it.Next();
}
}
lst.Append(stat);
}
//=======================================================================
//function : SelfIntersection
//purpose :
//=======================================================================
Standard_Boolean BRepCheck::SelfIntersection(const TopoDS_Wire& W,
const TopoDS_Face& myFace,
TopoDS_Edge& RetE1,
TopoDS_Edge& RetE2)
const TopoDS_Face& myFace,
TopoDS_Edge& RetE1,
TopoDS_Edge& RetE2)
{
Handle(BRepCheck_Wire) chkw = new BRepCheck_Wire(W);
BRepCheck_Status stat = chkw->SelfIntersect(myFace,RetE1,RetE2);
return (stat == BRepCheck_SelfIntersectingWire);
}
//=======================================================================
//function : Print
//purpose :
//=======================================================================
void BRepCheck::Print(const BRepCheck_Status stat,
Standard_OStream& OS)
Standard_OStream& OS)
{
switch (stat) {
@@ -181,7 +172,12 @@ void BRepCheck::Print(const BRepCheck_Status stat,
case BRepCheck_InvalidToleranceValue:
OS << "BRepCheck_InvalidToleranceValue\n";
break;
case BRepCheck_InvalidImbricationOfShells:
OS << "BRepCheck_InvalidImbricationOfShells\n";
break;
case BRepCheck_EnclosedRegion:
OS << "BRepCheck_EnclosedRegion\n";
break;
default:
break;
}

View File

@@ -21,6 +21,7 @@
#include <BRepCheck_Wire.hxx>
#include <BRepCheck_Face.hxx>
#include <BRepCheck_Shell.hxx>
#include <BRepCheck_Solid.hxx>
#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
#include <TopoDS_Iterator.hxx>
@@ -33,13 +34,15 @@
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void BRepCheck_Analyzer::Init(const TopoDS_Shape& S,
const Standard_Boolean B)
const Standard_Boolean B)
{
if (S.IsNull()) {
Standard_NullObject::Raise();
@@ -49,16 +52,12 @@ void BRepCheck_Analyzer::Init(const TopoDS_Shape& S,
Put(S,B);
Perform(S);
}
//=======================================================================
//function : Put
//purpose :
//=======================================================================
void BRepCheck_Analyzer::Put(const TopoDS_Shape& S,
const Standard_Boolean B)
const Standard_Boolean B)
{
if (!myMap.IsBound(S)) {
Handle(BRepCheck_Result) HR;
@@ -82,6 +81,8 @@ void BRepCheck_Analyzer::Put(const TopoDS_Shape& S,
HR = new BRepCheck_Shell(TopoDS::Shell(S));
break;
case TopAbs_SOLID:
HR = new BRepCheck_Solid(TopoDS::Solid(S));
break;
case TopAbs_COMPSOLID:
case TopAbs_COMPOUND:
break;
@@ -94,13 +95,10 @@ void BRepCheck_Analyzer::Put(const TopoDS_Shape& S,
}
}
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S)
{
for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next())
@@ -118,7 +116,7 @@ void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S)
// modified by NIZHNY-MKK Wed May 19 16:56:16 2004.BEGIN
// There is no need to check anything.
// if (myShape.IsSame(S)) {
// myMap(S)->Blind();
// myMap(S)->Blind();
// }
// modified by NIZHNY-MKK Wed May 19 16:56:23 2004.END
@@ -393,43 +391,41 @@ void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S)
break;
case TopAbs_SHELL:
//modified by NIZNHY-PKV Mon Oct 13 14:23:53 2008f
//modified by NIZNHY-PKV Mon Oct 13 14:24:04 2008t
break;
case TopAbs_SOLID:
{
exp.Init(S,TopAbs_SHELL);
exp.Init(S,TopAbs_SHELL);
for (; exp.More(); exp.Next())
{
const TopoDS_Shape& aShell=exp.Current();
try
{
OCC_CATCH_SIGNALS
myMap(aShell)->InContext(S);
}
catch(Standard_Failure)
{
const TopoDS_Shape& aShell=exp.Current();
try
{
OCC_CATCH_SIGNALS
myMap(aShell)->InContext(S);
}
catch(Standard_Failure)
{
#ifdef OCCT_DEBUG
cout<<"BRepCheck_Analyzer : ";
Standard_Failure::Caught()->Print(cout);
cout<<endl;
cout<<"BRepCheck_Analyzer : ";
Standard_Failure::Caught()->Print(cout);
cout<<endl;
#endif
if ( ! myMap(S).IsNull() )
{
myMap(S)->SetFailStatus(S);
}
//
Handle(BRepCheck_Result) aRes = myMap(aShell);
if (!aRes.IsNull() )
{
aRes->SetFailStatus(exp.Current());
aRes->SetFailStatus(S);
}
}//catch(Standard_Failure)
}//for (; exp.More(); exp.Next())
}
if ( ! myMap(S).IsNull() )
{
myMap(S)->SetFailStatus(S);
}
//
Handle(BRepCheck_Result) aRes = myMap(aShell);
if (!aRes.IsNull() )
{
aRes->SetFailStatus(exp.Current());
aRes->SetFailStatus(S);
}
}//catch(Standard_Failure)
}//for (; exp.More(); exp.Next())
}
break;//case TopAbs_SOLID
default:
break;
@@ -503,10 +499,10 @@ Standard_Boolean BRepCheck_Analyzer::ValidSub
// for (TopExp_Explorer exp(S,SubType);exp.More(); exp.Next()) {
const Handle(BRepCheck_Result)& RV = myMap(exp.Current());
for (RV->InitContextIterator();
RV->MoreShapeInContext();
RV->NextShapeInContext()) {
RV->MoreShapeInContext();
RV->NextShapeInContext()) {
if (RV->ContextualShape().IsSame(S)) {
break;
break;
}
}
@@ -514,7 +510,7 @@ Standard_Boolean BRepCheck_Analyzer::ValidSub
for (itl.Initialize(RV->StatusOnShape()); itl.More(); itl.Next()) {
if (itl.Value() != BRepCheck_NoError) {
return Standard_False;
return Standard_False;
}
}
}

View File

@@ -0,0 +1,70 @@
-- Created by: Peter KURNEV
-- Copyright (c) 2014 OPEN CASCADE SAS
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
--
-- Alternatively, this file may be used under the terms of Open CASCADE
-- commercial license or contractual agreement.
class Solid from BRepCheck
inherits Result from BRepCheck
---Purpose: The class is to check a solid.
uses
Shape from TopoDS,
Solid from TopoDS
is
Create(theS: Solid from TopoDS)
returns Solid from BRepCheck;
---Purpose:
-- Constructor
-- <theS> is the solid to check
InContext(me: mutable;
theContextShape: Shape from TopoDS)
is redefined;
---Purpose:
-- Checks the solid in context of
-- the shape <theContextShape>
Minimum(me: mutable)
is redefined;
---Purpose:
-- Checks the solid per se.
--
-- The scan area is:
-- 1. Shells that overlaps each other
-- Status: BRepCheck_InvalidImbricationOfShells
--
-- 2. Detached parts of the solid (vertices, edges)
-- that have non-internal orientation
-- Status: BRepCheck_BadOrientationOfSubshape
--
--
-- 3. For closed, non-internal shells:
-- 3.1 Shells containing entities of the solid that
-- are outside towards the shells
-- Status: BRepCheck_SubshapeNotInShape
--
-- 3.2 Shells that encloses other Shells
-- (for non-holes)
-- Status: BRepCheck_EnclosedRegion
--
Blind(me: mutable)
is redefined;
---Purpose:
-- see the parent class for more details
--fields
end Solid;

View File

@@ -0,0 +1,315 @@
// Created by: Peter KURNEV
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepCheck_Solid.ixx>
//
#include <Standard_DefineHandle.hxx>
#include <MMgt_TShared.hxx>
//
#include <NCollection_Vector.hxx>
#include <NCollection_Map.hxx>
//
#include <gp_Pnt.hxx>
//
#include <Geom_Curve.hxx>
//
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Builder.hxx>
#include <BRep_Tool.hxx>
//
#include <TopExp_Explorer.hxx>
//
#include <TopTools_MapOfShape.hxx>
#include <TopTools_ShapeMapHasher.hxx>
//
#include <BRepClass3d_SolidClassifier.hxx>
//
#include <BRepCheck.hxx>
#include <BRepCheck_ListOfStatus.hxx>
DEFINE_STANDARD_HANDLE(BRepCheck_HSC, MMgt_TShared);
//=======================================================================
//class : BRepCheck_HSC
//purpose :
//=======================================================================
class BRepCheck_HSC : public MMgt_TShared {
public:
//
Standard_EXPORT
BRepCheck_HSC(){
};
//
Standard_EXPORT
virtual ~BRepCheck_HSC(){
};
//
Standard_EXPORT
BRepClass3d_SolidClassifier& SolidClassifier(){
return mySC;
};
//
DEFINE_STANDARD_RTTI(BRepCheck_HSC);
protected:
BRepClass3d_SolidClassifier mySC;
};
IMPLEMENT_STANDARD_HANDLE(BRepCheck_HSC, MMgt_TShared);
IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_HSC, MMgt_TShared);
//
//=======================================================================
//class : BRepCheck_ToolSolid
//purpose :
//=======================================================================
class BRepCheck_ToolSolid {
public:
DEFINE_STANDARD_ALLOC
BRepCheck_ToolSolid() {
myIsHole=Standard_False;
myPnt.SetCoord(-1.,-1.,-1.);
};
virtual ~BRepCheck_ToolSolid() {
};
//
void SetSolid(const TopoDS_Solid& aZ) {
mySolid=aZ;
};
//
const TopoDS_Solid& Solid()const {
return mySolid;
};
//
Standard_Boolean IsHole() const {
return myIsHole;
};
//
const gp_Pnt& InnerPoint() {
return myPnt;
}
//
// IsOut
Standard_Boolean IsOut(BRepCheck_ToolSolid& aOther) {
Standard_Boolean bFlag;
TopAbs_State aState;
//
BRepClass3d_SolidClassifier& aSC=myHSC->SolidClassifier();
//
aSC.Perform(aOther.myPnt, ::RealSmall());
aState=aSC.State();
bFlag=(aState==TopAbs_OUT);
//
return bFlag;
};
//
// Init
void Init() {
Standard_Real aT, aT1, aT2, aPAR_T;
TopExp_Explorer aExp;
//
// 0.myHSC
myHSC=new BRepCheck_HSC();
//
BRepClass3d_SolidClassifier& aSC=myHSC->SolidClassifier();
// 1. Load
aSC.Load(mySolid);
//
// 2. myIsHole
aSC.PerformInfinitePoint(::RealSmall());
myIsHole=(aSC.State()==TopAbs_IN);
//
// 3. myPnt
aPAR_T=0.43213918; // 10*e^(-PI)
aExp.Init(mySolid, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
if (!BRep_Tool::Degenerated(aE)) {
Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aT1, aT2);
aT=(1.-aPAR_T)*aT1 + aPAR_T*aT2;
myPnt=aC3D->Value(aT);
break;
}
}
};
//
protected:
Standard_Boolean myIsHole;
gp_Pnt myPnt;
TopoDS_Solid mySolid;
Handle(BRepCheck_HSC) myHSC;
};
//
typedef NCollection_Vector<BRepCheck_ToolSolid>
BRepCheck_VectorOfToolSolid;
//
//=======================================================================
//function : BRepCheck_Solid
//purpose :
//=======================================================================
BRepCheck_Solid::BRepCheck_Solid (const TopoDS_Solid& S)
{
Init(S);
}
//=======================================================================
//function : Blind
//purpose :
//=======================================================================
void BRepCheck_Solid::Blind()
{
if (!myBlind) {
// nothing more than in the minimum
myBlind = Standard_True;
}
}
//=======================================================================
//function : InContext
//purpose :
//=======================================================================
void BRepCheck_Solid::InContext(const TopoDS_Shape& )
{
}
//=======================================================================
//function : Minimum
//purpose :
//=======================================================================
void BRepCheck_Solid::Minimum()
{
if (myMin) {
return;
}
myMin = Standard_True;
//
Standard_Boolean bFound, bIsHole, bFlag;
Standard_Integer i, j, aNbVTS, aNbVTS1;
TopoDS_Solid aZ;
TopoDS_Iterator aIt, aItF;
TopoDS_Builder aBB;
TopExp_Explorer aExp;
TopTools_MapOfShape aMSS;
TopAbs_Orientation aOr;
BRepCheck_VectorOfToolSolid aVTS;
BRepCheck_ListOfStatus thelist;
//
myMap.Bind(myShape, thelist);
BRepCheck_ListOfStatus& aLST = myMap(myShape);
aLST.Append(BRepCheck_NoError);
//
//-------------------------------------------------
// 1. InvalidImbricationOfShells
bFound=Standard_False;
aExp.Init(myShape, TopAbs_FACE);
for (; !bFound && aExp.More(); aExp.Next()) {
const TopoDS_Shape& aF=aExp.Current();
if (!aMSS.Add(aF)) {
BRepCheck::Add(myMap(myShape),
BRepCheck_InvalidImbricationOfShells);
bFound=!bFound;
}
}
//
//-------------------------------------------------
// 2.
// - Too many growths,
// - There is smt of the solid that is out of solid
aIt.Initialize(myShape);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSx=aIt.Value();
//
if (aSx.ShapeType()!=TopAbs_SHELL) {
aOr=aSx.Orientation();
if (aOr!=TopAbs_INTERNAL) {
BRepCheck::Add(myMap(myShape),
BRepCheck_BadOrientationOfSubshape);
}
continue;
}
//
const TopoDS_Shell& aSh=*((TopoDS_Shell*)&aSx);
//
// Skip internal shells
bFound=Standard_False;
aItF.Initialize(aSh);
for (; !bFound && aItF.More(); aItF.Next()) {
const TopoDS_Shape& aF=aItF.Value();
aOr=aF.Orientation();
if (aOr==TopAbs_INTERNAL) {
bFound=!bFound;
}
}
if (bFound) {
continue;
}
//
// Skip not closed shells
if (!BRep_Tool::IsClosed(aSh)) {
continue;
}
//
aBB.MakeSolid(aZ);
aBB.Add(aZ, aSh);
//
BRepCheck_ToolSolid aTS;
//
aTS.SetSolid(aZ);
aVTS.Append(aTS);
}//for (; aIt.More(); aIt.Next()) {
//
aNbVTS=aVTS.Size();
if (aNbVTS<2) {
return;
}
//
aNbVTS1=0;
for (i=0; i<aNbVTS; ++i) {
BRepCheck_ToolSolid& aTS=aVTS(i);
//
aTS.Init();
bIsHole=aTS.IsHole();
if (!bIsHole) {
++aNbVTS1;
if (aNbVTS1>1) {
// Too many growths
BRepCheck::Add(myMap(myShape),
BRepCheck_EnclosedRegion);
break;
}
}
}
//
bFound=Standard_False;
aNbVTS1=aNbVTS-1;
for (i=0; !bFound && i<aNbVTS1; ++i) {
BRepCheck_ToolSolid& aTSi=aVTS(i);
//
for (j=i+1; !bFound && j<aNbVTS; ++j) {
BRepCheck_ToolSolid& aTSj=aVTS(j);
//
bFlag=aTSi.IsOut(aTSj);
if (bFlag) {
// smt of solid is out of solid
BRepCheck::Add(myMap(myShape),
BRepCheck_SubshapeNotInShape);
bFound=!bFound;
}
}
}
//
//myMin = Standard_True;
}