From c479c4f6d89ed7c5e33dd35a5e110f13776b7cab Mon Sep 17 00:00:00 2001 From: dorlov Date: Fri, 13 Jan 2023 13:25:17 +0000 Subject: [PATCH] 0023638: Data Exchange - Reading IGES file produced invalid shape Removed double healing of Iges group entities Added ShapeBuild_ReShape member to the IGESData_IGESModel class, shapes which are registered in ShapeBuild_ReShape class does not process to healing --- src/IGESData/IGESData_IGESModel.cxx | 3 + src/IGESData/IGESData_IGESModel.hxx | 9 +- src/IGESToBRep/IGESToBRep_Actor.cxx | 11 +- src/ShapeFix/ShapeFix_Shape.cxx | 8 +- src/XSAlgo/XSAlgo_AlgoContainer.cxx | 158 ++++++++++++++++------------ src/XSAlgo/XSAlgo_AlgoContainer.hxx | 50 +++++++-- tests/bugs/iges/bug23638 | 4 +- 7 files changed, 152 insertions(+), 91 deletions(-) diff --git a/src/IGESData/IGESData_IGESModel.cxx b/src/IGESData/IGESData_IGESModel.cxx index 091495345f..c58873a852 100644 --- a/src/IGESData/IGESData_IGESModel.cxx +++ b/src/IGESData/IGESData_IGESModel.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ void IGESData_VerifyDate IGESData_IGESModel::IGESData_IGESModel () { thestart = new TColStd_HSequenceOfHAsciiString(); + myReShape = new ShapeBuild_ReShape(); // thecheckstx = new Interface_Check; // thechecksem = new Interface_Check; } @@ -62,6 +64,7 @@ void IGESData_IGESModel::ClearHeader () IGESData_GlobalSection newheader; // Un peu brutal, certes theheader = newheader; thestart = new TColStd_HSequenceOfHAsciiString(); + myReShape = new ShapeBuild_ReShape(); } diff --git a/src/IGESData/IGESData_IGESModel.hxx b/src/IGESData/IGESData_IGESModel.hxx index 1e30288963..128b99eb1e 100644 --- a/src/IGESData/IGESData_IGESModel.hxx +++ b/src/IGESData/IGESData_IGESModel.hxx @@ -22,10 +22,10 @@ class IGESData_IGESEntity; class Interface_Check; +class ShapeBuild_ReShape; class Standard_Transient; class TCollection_HAsciiString; - class IGESData_IGESModel; DEFINE_STANDARD_HANDLE(IGESData_IGESModel, Interface_InterfaceModel) @@ -151,8 +151,11 @@ public: //! i.e. a string "Dnn" with nn = directory entry number (2*N-1) Standard_EXPORT Handle(TCollection_HAsciiString) StringLabel (const Handle(Standard_Transient)& ent) const Standard_OVERRIDE; + //! Gets ReShape used to store a model's shapes changes + const Handle(ShapeBuild_ReShape)& ReShape() const { return myReShape; } - + //! Sets ReShape used to store a history of changes of the model's shapes + void SetReShape(const Handle(ShapeBuild_ReShape)& theReShape) { myReShape = theReShape; } DEFINE_STANDARD_RTTIEXT(IGESData_IGESModel,Interface_InterfaceModel) @@ -166,7 +169,7 @@ private: Handle(TColStd_HSequenceOfHAsciiString) thestart; IGESData_GlobalSection theheader; - + Handle(ShapeBuild_ReShape) myReShape; }; diff --git a/src/IGESToBRep/IGESToBRep_Actor.cxx b/src/IGESToBRep/IGESToBRep_Actor.cxx index dc21b09686..0304ddec5b 100644 --- a/src/IGESToBRep/IGESToBRep_Actor.cxx +++ b/src/IGESToBRep/IGESToBRep_Actor.cxx @@ -131,8 +131,6 @@ static void TrimTolerances (const TopoDS_Shape& shape, } } - - //======================================================================= //function : Transfer //purpose : @@ -196,10 +194,11 @@ Handle(Transfer_Binder) IGESToBRep_Actor::Transfer // fixing shape Handle(Standard_Transient) info; - shape = XSAlgo::AlgoContainer()->ProcessShape( shape, theeps, CAS.GetMaxTol(), - "read.iges.resource.name", - "read.iges.sequence", info, - aPS.Next()); + shape = XSAlgo::AlgoContainer()->ProcessShape(shape, theeps, CAS.GetMaxTol(), + "read.iges.resource.name", + "read.iges.sequence", + info, mymodel->ReShape(), + aPS.Next()); XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems); } diff --git a/src/ShapeFix/ShapeFix_Shape.cxx b/src/ShapeFix/ShapeFix_Shape.cxx index fc0c89de99..1e45f0b469 100644 --- a/src/ShapeFix/ShapeFix_Shape.cxx +++ b/src/ShapeFix/ShapeFix_Shape.cxx @@ -112,18 +112,20 @@ Standard_Boolean ShapeFix_Shape::Perform(const Message_ProgressRange& theProgres TopLoc_Location nullLoc,L; L = myShape.Location(); TopoDS_Shape aShapeNullLoc = myShape; + const Standard_Boolean aIsRecorded = Context()->IsNewShape(myShape); aShapeNullLoc.Location(nullLoc); - if(myMapFixingShape.Contains(aShapeNullLoc)) { + if(aIsRecorded || myMapFixingShape.Contains(aShapeNullLoc)) + { myShape.Location(L, Standard_False); myResult = Context()->Apply(myShape); status = Standard_True; return status; } - else myMapFixingShape.Add(aShapeNullLoc); + myMapFixingShape.Add(aShapeNullLoc); //--------------------------------------- myShape.Location(L, Standard_False); TopoDS_Shape S = Context()->Apply(myShape); - if ( NeedFix ( myFixVertexPositionMode ) ) + if (NeedFix(myFixVertexPositionMode)) ShapeFix::FixVertexPosition(S,Precision(),Context()); st = S.ShapeType(); diff --git a/src/XSAlgo/XSAlgo_AlgoContainer.cxx b/src/XSAlgo/XSAlgo_AlgoContainer.cxx index 6f3ccb3bcb..5b9cd8b79c 100644 --- a/src/XSAlgo/XSAlgo_AlgoContainer.cxx +++ b/src/XSAlgo/XSAlgo_AlgoContainer.cxx @@ -82,103 +82,131 @@ void XSAlgo_AlgoContainer::PrepareForTransfer() const //======================================================================= //function : ProcessShape -//purpose : +//purpose : //======================================================================= - -TopoDS_Shape XSAlgo_AlgoContainer::ProcessShape (const TopoDS_Shape& shape, - const Standard_Real Prec, - const Standard_Real maxTol, - const Standard_CString prscfile, - const Standard_CString pseq, - Handle(Standard_Transient)& info, - const Message_ProgressRange& theProgress, - const Standard_Boolean NonManifold) const +TopoDS_Shape XSAlgo_AlgoContainer::ProcessShape(const TopoDS_Shape& theShape, + const Standard_Real thePrec, + const Standard_Real theMaxTol, + const Standard_CString thePrscfile, + const Standard_CString thePseq, + Handle(Standard_Transient)& theInfo, + const Handle(ShapeBuild_ReShape)& theReShape, + const Message_ProgressRange& theProgress, + const Standard_Boolean theNonManifold) const { - if ( shape.IsNull() ) return shape; - - Handle(ShapeProcess_ShapeContext) context = Handle(ShapeProcess_ShapeContext)::DownCast(info); - if ( context.IsNull() ) + if (theShape.IsNull()) { - Standard_CString rscfile = Interface_Static::CVal(prscfile); - if (rscfile != nullptr && strlen (rscfile) == 0) + return theShape; + } + + Handle(ShapeProcess_ShapeContext) aContext = Handle(ShapeProcess_ShapeContext)::DownCast(theInfo); + if (aContext.IsNull()) + { + Standard_CString aRscfile = Interface_Static::CVal(thePrscfile); + if (aRscfile != nullptr && strlen(aRscfile) == 0) { - context = new ShapeProcess_ShapeContext(shape, nullptr); - Interface_Static::FillMap(context->ResourceManager()->GetMap()); + aContext = new ShapeProcess_ShapeContext(theShape, nullptr); + Interface_Static::FillMap(aContext->ResourceManager()->GetMap()); } else { - if (!rscfile) - rscfile = prscfile; - context = new ShapeProcess_ShapeContext(shape, rscfile); + if (!aRscfile) + aRscfile = thePrscfile; + aContext = new ShapeProcess_ShapeContext(theShape, aRscfile); } - context->SetDetalisation(TopAbs_EDGE); + aContext->SetDetalisation(TopAbs_EDGE); } - context->SetNonManifold(NonManifold); - info = context; - - Standard_CString seq = Interface_Static::CVal ( pseq ); - if ( ! seq ) seq = pseq; - + aContext->SetNonManifold(theNonManifold); + theInfo = aContext; + + Standard_CString aSeq = Interface_Static::CVal(thePseq); + if (!aSeq) aSeq = thePseq; + // if resource file is not loaded or does not define .exec.op, // do default fixes - Handle(Resource_Manager) rsc = context->ResourceManager(); - TCollection_AsciiString str ( seq ); - str += ".exec.op"; - if ( ! rsc->Find ( str.ToCString() ) ) { + Handle(Resource_Manager) aRsc = aContext->ResourceManager(); + TCollection_AsciiString aStr(aSeq); + aStr += ".exec.op"; + if (!aRsc->Find(aStr.ToCString())) + { #ifdef OCCT_DEBUG { - static Standard_Integer time = 0; - if ( ! time ) - std::cout << "Warning: XSAlgo_AlgoContainer::ProcessShape(): Sequence " << str.ToCString() << - " is not defined in " << prscfile << " resource; do default processing" << std::endl; - time++; + static Standard_Integer aTime = 0; + if (!aTime) + std::cout << "Warning: XSAlgo_AlgoContainer::ProcessShape(): Sequence " << aStr.ToCString() << + " is not defined in " << thePrscfile << " resource; do default processing" << std::endl; + aTime++; } #endif // if reading, do default ShapeFix - if ( ! strncmp ( pseq, "read.", 5 ) ) { + if (!strncmp(thePseq, "read.", 5)) + { try { OCC_CATCH_SIGNALS - Handle(ShapeExtend_MsgRegistrator) msg = new ShapeExtend_MsgRegistrator; - Handle(ShapeFix_Shape) sfs = ShapeAlgo::AlgoContainer()->ToolContainer()->FixShape(); - sfs->Init ( shape ); - sfs->SetMsgRegistrator ( msg ); - sfs->SetPrecision ( Prec ); - sfs->SetMaxTolerance ( maxTol ); - sfs->FixFaceTool()->FixWireTool()->FixSameParameterMode() = Standard_False; - sfs->FixSolidTool()->CreateOpenSolidMode() = Standard_False; - sfs->Perform(theProgress); + Handle(ShapeExtend_MsgRegistrator) aMsg = new ShapeExtend_MsgRegistrator; + Handle(ShapeFix_Shape) aSfs = ShapeAlgo::AlgoContainer()->ToolContainer()->FixShape(); + aSfs->Init(theShape); + aSfs->SetMsgRegistrator(aMsg); + aSfs->SetPrecision(thePrec); + aSfs->SetMaxTolerance(theMaxTol); + aSfs->FixFaceTool()->FixWireTool()->FixSameParameterMode() = Standard_False; + aSfs->FixSolidTool()->CreateOpenSolidMode() = Standard_False; + aSfs->SetContext(theReShape); + aSfs->Perform(theProgress); - TopoDS_Shape S = sfs->Shape(); - if ( ! S.IsNull() && S != shape ) { - context->RecordModification ( sfs->Context(), msg ); - context->SetResult ( S ); - } + TopoDS_Shape aShape = aSfs->Shape(); + if (!aShape.IsNull() && aShape != theShape) + { + aContext->RecordModification(aSfs->Context(), aMsg); + aContext->SetResult(aShape); + } } - catch (Standard_Failure const& anException) { + catch (Standard_Failure const& anException) + { #ifdef OCCT_DEBUG - std::cout << "Error: XSAlgo_AlgoContainer::ProcessShape(): Exception in ShapeFix::Shape" << std::endl; + std::cout << "Error: XSAlgo_AlgoContainer::ProcessShape(): Exception in ShapeFix::Shape" << std::endl; anException.Print(std::cout); std::cout << std::endl; #endif - (void)anException; + (void)anException; } - return context->Result(); + return aContext->Result(); } // for writing, define default sequence of DirectFaces - else if ( ! strncmp ( pseq, "write.", 6 ) ) { - rsc->SetResource ( str.ToCString(), "DirectFaces" ); + else if (!strncmp(thePseq, "write.", 6)) + { + aRsc->SetResource(aStr.ToCString(), "DirectFaces"); } } - + // Define runtime tolerances and do Shape Processing - rsc->SetResource ( "Runtime.Tolerance", Prec ); - rsc->SetResource ( "Runtime.MaxTolerance", maxTol ); + aRsc->SetResource("Runtime.Tolerance", thePrec); + aRsc->SetResource("Runtime.MaxTolerance", theMaxTol); - if ( !ShapeProcess::Perform(context, seq, theProgress) ) - return shape; // return original shape + if (!ShapeProcess::Perform(aContext, aSeq, theProgress)) + return theShape; // return original shape - return context->Result(); + return aContext->Result(); } - + +//======================================================================= +//function : ProcessShape +//purpose : +//======================================================================= +TopoDS_Shape XSAlgo_AlgoContainer::ProcessShape(const TopoDS_Shape& theShape, + const Standard_Real thePrec, + const Standard_Real theMaxTol, + const Standard_CString thePrscfile, + const Standard_CString thePseq, + Handle(Standard_Transient)& theInfo, + const Message_ProgressRange& theProgress, + const Standard_Boolean theNonManifold) const +{ + Handle(ShapeBuild_ReShape) aReShape = new ShapeBuild_ReShape(); + return ProcessShape(theShape, thePrec, theMaxTol, thePrscfile, + thePseq, theInfo, aReShape, theProgress, + theNonManifold); +} + //======================================================================= //function : PerformFixShape //purpose : diff --git a/src/XSAlgo/XSAlgo_AlgoContainer.hxx b/src/XSAlgo/XSAlgo_AlgoContainer.hxx index 513fe54f91..122051e42b 100644 --- a/src/XSAlgo/XSAlgo_AlgoContainer.hxx +++ b/src/XSAlgo/XSAlgo_AlgoContainer.hxx @@ -23,6 +23,7 @@ #include #include +class ShapeBuild_ReShape; class XSAlgo_ToolContainer; class TopoDS_Shape; class TopoDS_Edge; @@ -30,7 +31,6 @@ class TopoDS_Face; class Transfer_TransientProcess; class Transfer_FinderProcess; - class XSAlgo_AlgoContainer; DEFINE_STANDARD_HANDLE(XSAlgo_AlgoContainer, Standard_Transient) @@ -55,16 +55,44 @@ public: Standard_EXPORT virtual void PrepareForTransfer() const; //! Does shape processing with specified tolerances - //! and returns resulting shape and associated information - //! in the form of Transient. - //! This information should be later transmitted to - //! MergeTransferInfo in order to be recorded in the - //! translation map - Standard_EXPORT virtual TopoDS_Shape ProcessShape ( - const TopoDS_Shape& shape, const Standard_Real Prec, const Standard_Real MaxTol, - const Standard_CString rscfile, const Standard_CString seq, Handle(Standard_Transient)& info, - const Message_ProgressRange& theProgress = Message_ProgressRange(), - const Standard_Boolean NonManifold = Standard_False) const; + //! @param[in] theShape shape to process + //! @param[in] thePrec basic precision and tolerance + //! @param[in] theMaxTol maximum allowed tolerance + //! @param[in] thePrscfile name of the resource file + //! @param[in] thePseq name of the sequence of operators defined in the resource file for Shape Processing + //! @param[out] theInfo information to be recorded in the translation map + //! @param[in] theProgress progress indicator + //! @param[in] theNonManifold flag to proceed with non-manifold topology + //! @return the processed shape + Standard_EXPORT virtual TopoDS_Shape ProcessShape (const TopoDS_Shape& theShape, + const Standard_Real thePrec, + const Standard_Real theMaxTol, + const Standard_CString thePrscfile, + const Standard_CString thePseq, + Handle(Standard_Transient)& theInfo, + const Message_ProgressRange& theProgress = Message_ProgressRange(), + const Standard_Boolean theNonManifold = Standard_False) const; + + //! Does shape processing with specified tolerances + //! @param[in] theShape shape to process + //! @param[in] thePrec basic precision and tolerance + //! @param[in] theMaxTol maximum allowed tolerance + //! @param[in] thePrscfile name of the resource file + //! @param[in] thePseq name of the sequence of operators defined in the resource file for Shape Processing + //! @param[out] theInfo information to be recorded in the translation map + //! @param[in] theReShape tool to record the modifications of input shape + //! @param[in] theProgress progress indicator + //! @param[in] theNonManifold flag to proceed with non-manifold topology + //! @return the processed shape + Standard_EXPORT virtual TopoDS_Shape ProcessShape(const TopoDS_Shape& theShape, + const Standard_Real thePrec, + const Standard_Real theMaxTol, + const Standard_CString thePrscfile, + const Standard_CString thePseq, + Handle(Standard_Transient)& theInfo, + const Handle(ShapeBuild_ReShape)& theReShape, + const Message_ProgressRange& theProgress = Message_ProgressRange(), + const Standard_Boolean theNonManifold = Standard_False) const; //! Checks quality of pcurve of the edge on the given face, //! and corrects it if necessary. diff --git a/tests/bugs/iges/bug23638 b/tests/bugs/iges/bug23638 index b43be2433e..ba614b387c 100755 --- a/tests/bugs/iges/bug23638 +++ b/tests/bugs/iges/bug23638 @@ -1,4 +1,4 @@ -puts "TODO OCC23638 ALL: Faulty shapes in variables faulty_1 to faulty_" +puts "TODO OCC23638 ALL: Faulty shapes in variables faulty_1 to faulty_1" puts "============" puts "CR23638" @@ -8,8 +8,6 @@ puts "" # Reading IGES file produced invalid shape ####################################################################### -param read.surfacecurve.mode -3 - igesread [locate_data_file bug23638_cadbad.igs] result * checkshape result