From: kgv Date: Sat, 3 Sep 2016 16:21:58 +0000 (+0300) Subject: 0027835: Application Framework, BinXCAF - handle correctly faces with NULL surface... X-Git-Tag: V7_1_0_beta~162 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=f1fb0901d60539ba96f6914f0f56f8e71f11eeb3 0027835: Application Framework, BinXCAF - handle correctly faces with NULL surface within BinTools_ShapeSet BinTools_ShapeSet::AddGeometry() now writes NULL surface with 0 index. myWithTriangles is ignored for TopoDS_Face with NULL surface so that triangulation-only faces are not lost with defaults. Added Draw Harness command StoreTriangulation defining WithTriangulation flag for BinXCAF/BinOcaf storage drivers. --- diff --git a/src/BinDrivers/BinDrivers_DocumentStorageDriver.cxx b/src/BinDrivers/BinDrivers_DocumentStorageDriver.cxx index 730f7f15f2..f1179c1e51 100644 --- a/src/BinDrivers/BinDrivers_DocumentStorageDriver.cxx +++ b/src/BinDrivers/BinDrivers_DocumentStorageDriver.cxx @@ -13,15 +13,16 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include #include -#include #include #include #include #include #include #include +#include #include #include #include @@ -47,6 +48,51 @@ Handle(BinMDF_ADriverTable) BinDrivers_DocumentStorageDriver::AttributeDrivers return BinDrivers::AttributeDrivers (theMessageDriver); } +//======================================================================= +//function : IsWithTriangles +//purpose : +//======================================================================= +Standard_Boolean BinDrivers_DocumentStorageDriver::IsWithTriangles() const +{ + if (myDrivers.IsNull()) + { + return Standard_False; + } + + Handle(BinMDF_ADriver) aDriver; + myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver); + Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver); + return !aShapesDriver.IsNull() + && aShapesDriver->IsWithTriangles(); +} + +//======================================================================= +//function : SetWithTriangles +//purpose : +//======================================================================= +void BinDrivers_DocumentStorageDriver::SetWithTriangles (const Handle(CDM_MessageDriver)& theMessageDriver, + const Standard_Boolean theWithTriangulation) +{ + if (myDrivers.IsNull()) + { + myDrivers = AttributeDrivers (theMessageDriver); + } + if (myDrivers.IsNull()) + { + return; + } + + Handle(BinMDF_ADriver) aDriver; + myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver); + Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver); + if (aShapesDriver.IsNull()) + { + Standard_NotImplemented::Raise("Internal Error - TNaming_NamedShape is not found!"); + } + + aShapesDriver->SetWithTriangles (theWithTriangulation); +} + //======================================================================= //function : WriteShapeSection //purpose : Implements WriteShapeSection diff --git a/src/BinDrivers/BinDrivers_DocumentStorageDriver.hxx b/src/BinDrivers/BinDrivers_DocumentStorageDriver.hxx index ad0cba1229..4c1d843702 100644 --- a/src/BinDrivers/BinDrivers_DocumentStorageDriver.hxx +++ b/src/BinDrivers/BinDrivers_DocumentStorageDriver.hxx @@ -44,8 +44,12 @@ public: //! implements the procedure of writing a shape section to file Standard_EXPORT virtual void WriteShapeSection (BinLDrivers_DocumentSection& theDocSection, Standard_OStream& theOS) Standard_OVERRIDE; + //! Return true if shape should be stored with triangles. + Standard_EXPORT Standard_Boolean IsWithTriangles() const; - + //! Set if triangulation should be stored or not. + Standard_EXPORT void SetWithTriangles (const Handle(CDM_MessageDriver)& theMessageDriver, + const Standard_Boolean theWithTriangulation); DEFINE_STANDARD_RTTIEXT(BinDrivers_DocumentStorageDriver,BinLDrivers_DocumentStorageDriver) diff --git a/src/BinMNaming/BinMNaming_NamedShapeDriver.hxx b/src/BinMNaming/BinMNaming_NamedShapeDriver.hxx index a0f7884223..057199d71b 100644 --- a/src/BinMNaming/BinMNaming_NamedShapeDriver.hxx +++ b/src/BinMNaming/BinMNaming_NamedShapeDriver.hxx @@ -59,9 +59,12 @@ public: //! Clear myShapeSet Standard_EXPORT void Clear(); - + + //! Return true if shape should be stored with triangles. + Standard_Boolean IsWithTriangles() const { return myShapeSet.IsWithTriangles(); } + //! set whether to store triangulation - void SetWithTriangles (const Standard_Boolean isWithTriangles); + void SetWithTriangles (const Standard_Boolean isWithTriangles); //! set the format of topology //! First : does not write CurveOnSurface UV Points into the file diff --git a/src/BinTools/BinTools_ShapeSet.cxx b/src/BinTools/BinTools_ShapeSet.cxx index 5ab0c6b2ba..3f0d45bf1b 100644 --- a/src/BinTools/BinTools_ShapeSet.cxx +++ b/src/BinTools/BinTools_ShapeSet.cxx @@ -86,15 +86,6 @@ BinTools_ShapeSet::BinTools_ShapeSet(const Standard_Boolean isWithTriangles) BinTools_ShapeSet::~BinTools_ShapeSet() {} -//======================================================================= -//function : SetWithTriangles -//purpose : -//======================================================================= -void BinTools_ShapeSet::SetWithTriangles(const Standard_Boolean isWithTriangles) -{ - myWithTriangles = isWithTriangles; -} - //======================================================================= //function : SetFormatNb //purpose : @@ -287,7 +278,9 @@ void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S) Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape()); if (!TF->Surface().IsNull()) mySurfaces.Add(TF->Surface()); - if (myWithTriangles) { + if (myWithTriangles + || TF->Surface().IsNull()) + { Handle(Poly_Triangulation) Tr = TF->Triangulation(); if (!Tr.IsNull()) myTriangulations.Add(Tr); } @@ -730,17 +723,19 @@ void BinTools_ShapeSet::WriteGeometry(const TopoDS_Shape& S, Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape()); const TopoDS_Face& F = TopoDS::Face(S); - - if (!(TF->Surface()).IsNull()) { - Standard_Boolean aNatRes = (BRep_Tool::NaturalRestriction(F)) ? Standard_True : Standard_False; - BinTools::PutBool(OS, aNatRes); // Write the surface geometry - BinTools::PutReal(OS, TF->Tolerance()); - BinTools::PutInteger(OS, mySurfaces.Index(TF->Surface())); - BinTools::PutInteger(OS, Locations().Index(TF->Location())); - } - if (myWithTriangles) { + Standard_Boolean aNatRes = (BRep_Tool::NaturalRestriction(F)) ? Standard_True : Standard_False; + BinTools::PutBool (OS, aNatRes); + BinTools::PutReal (OS, TF->Tolerance()); + BinTools::PutInteger (OS, !TF->Surface().IsNull() + ? mySurfaces.Index (TF->Surface()) + : 0); + BinTools::PutInteger (OS, Locations().Index (TF->Location())); + + if (myWithTriangles + || TF->Surface().IsNull()) + { if (!(TF->Triangulation()).IsNull()) { OS << (Standard_Byte) 2; // Write the triangulation @@ -1103,12 +1098,11 @@ void BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T, BinTools::GetReal(IS, tol); BinTools::GetInteger(IS, s); //surface indx BinTools::GetInteger(IS, l); //location indx - if (!mySurfaces.Surface(s).IsNull()) { - myBuilder.UpdateFace(TopoDS::Face(S), - mySurfaces.Surface(s), - Locations().Location(l),tol); - myBuilder.NaturalRestriction(TopoDS::Face(S),bval ); - } + myBuilder.UpdateFace (F, + s > 0 ? mySurfaces.Surface(s) : Handle(Geom_Surface)(), + Locations().Location(l), + tol); + myBuilder.NaturalRestriction (F, bval); Standard_Byte aByte = (Standard_Byte)IS.get(); // cas triangulation diff --git a/src/BinTools/BinTools_ShapeSet.hxx b/src/BinTools/BinTools_ShapeSet.hxx index 61eea483d2..8cfa5d5538 100644 --- a/src/BinTools/BinTools_ShapeSet.hxx +++ b/src/BinTools/BinTools_ShapeSet.hxx @@ -49,10 +49,14 @@ public: Standard_EXPORT BinTools_ShapeSet(const Standard_Boolean isWithTriangles = Standard_False); Standard_EXPORT virtual ~BinTools_ShapeSet(); - - //! Define if shape will be stored with triangles - Standard_EXPORT void SetWithTriangles (const Standard_Boolean isWithTriangles); - + + //! Return true if shape should be stored with triangles. + Standard_Boolean IsWithTriangles() const { return myWithTriangles; } + + //! Define if shape will be stored with triangles. + //! Ignored (always written) if face defines only triangulation (no surface). + void SetWithTriangles (const Standard_Boolean isWithTriangles) { myWithTriangles = isWithTriangles; } + Standard_EXPORT void SetFormatNb (const Standard_Integer theFormatNb); //! two formats available for the moment: diff --git a/src/DDocStd/DDocStd_DocumentCommands.cxx b/src/DDocStd/DDocStd_DocumentCommands.cxx index 6a6ca12b78..6a68984e56 100644 --- a/src/DDocStd/DDocStd_DocumentCommands.cxx +++ b/src/DDocStd/DDocStd_DocumentCommands.cxx @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -404,6 +405,42 @@ static Standard_Integer DDocStd_Propagate (Draw_Interpretor& di,Standard_Integer return 1; } +//======================================================================= +//function : DDocStd_StoreTriangulation +//purpose : +//======================================================================= + +static Standard_Integer DDocStd_StoreTriangulation (Draw_Interpretor& theDi, + Standard_Integer theNbArgs, + const char** theArgVec) +{ + const Handle(TDocStd_Application)& anApp = DDocStd::GetApplication(); + Handle(BinDrivers_DocumentStorageDriver) aDriverXCaf = Handle(BinDrivers_DocumentStorageDriver)::DownCast(anApp->WriterFromFormat ("BinXCAF")); + Handle(BinDrivers_DocumentStorageDriver) aDriverOcaf = Handle(BinDrivers_DocumentStorageDriver)::DownCast(anApp->WriterFromFormat ("BinOcaf")); + if (aDriverXCaf.IsNull() + || aDriverOcaf.IsNull()) + { + std::cout << "Error: BinXCAF or BinOcaf storage formats are not registered\n"; + return 1; + } + + if (theNbArgs == 1) + { + theDi << (aDriverXCaf->IsWithTriangles() ? "1" : "0"); + return 0; + } + else if (theNbArgs != 2) + { + std::cout << "Syntax error: wrong number of arguments\n"; + return 1; + } + + const Standard_Boolean toEnable = (Draw::Atoi (theArgVec[1]) != 0); + aDriverXCaf->SetWithTriangles (anApp->MessageDriver(), toEnable); + aDriverOcaf->SetWithTriangles (anApp->MessageDriver(), toEnable); + return 0; +} + //======================================================================= //function : DocumentCommands //purpose : @@ -435,6 +472,11 @@ void DDocStd::DocumentCommands(Draw_Interpretor& theCommands) "DumpDocument (DOC)", __FILE__, DDocStd_DumpDocument, g); + theCommands.Add ("StoreTriangulation", + "StoreTriangulation [toStore={0|1}]" + "\nSetup BinXCAF/BinOcaf storage drivers to write triangulation", + __FILE__, DDocStd_StoreTriangulation, g); + // XREF theCommands.Add("Copy","Copy DOC entry XDOC xentry", diff --git a/tests/bugs/caf/bug27835 b/tests/bugs/caf/bug27835 new file mode 100644 index 0000000000..c336fed384 --- /dev/null +++ b/tests/bugs/caf/bug27835 @@ -0,0 +1,41 @@ +puts "========" +puts "OCC27835" +puts "BinXCAF - handle correctly faces with NULL surface within BinTools_ShapeSet" +puts "========" +puts "" + +set anImgDoc1 $imagedir/${casename}_doc1.png +set anImgDoc2 $imagedir/${casename}_doc2.png +set anImgDiff $imagedir/${casename}_diff.png + +pload XDE OCAF MODELING VISUALIZATION + +restore [locate_data_file bug27821_nullsurf.brep] s +explode s F + +NewDocument D BinXCAF +XAddShape D s +XSetColor D s_1 1 0 0 +XShow D +vaxo +vfit +vrotate 3 0 0 +vsetdispmode 1 +vdump $anImgDoc1 + +StoreTriangulation 1 +SaveAs D test.xbf +Close D + +XOpen test.xbf D +XShow D +vsetdispmode 1 +vaxo +vfit +vrotate 3 0 0 +vdump $anImgDoc2 + +set aDiffRes [diffimage $anImgDoc2 $anImgDoc1 0.0 0 0 $anImgDiff] +if {$aDiffRes != 0} { + puts "Error: document has changed after Save/Read" +}