From 63cdf48ec1e3e55fdebf40292ecca39e4ff9c07f Mon Sep 17 00:00:00 2001 From: msv Date: Fri, 1 Jun 2018 14:38:39 +0300 Subject: [PATCH] 0029830: STEPCAFControl_Reader poor performance - quadratic dependence Various performance improvements in STEP read/write algorithms: - Search for the label of a shape or component shape is improved using map mechanism instead of brute force iteration. - Invariant FindEntities() is moved out of the loop in the method getStyledItem in STEPCAFControl/STEPCAFControl_Writer.cxx. - A pointer to the end of binders chain is added in Transfer_Binder class to speed up adding a binder to the chain. - Small fixes are added to eliminate excess copying of handles, calls of handle DownCasts and so on. Stack overflow is removed during destruction of STEP model with long chains of Transfer_Binder. It is possible to use the Draw commands ReadStep and WriteStep to read/write from the session without accessing the disk file (use '.' for the file name). Performance test cases for STEP reading/writing have been added. --- src/STEPCAFControl/STEPCAFControl_Reader.cxx | 159 +++++++----------- src/STEPCAFControl/STEPCAFControl_Reader.hxx | 11 +- src/STEPCAFControl/STEPCAFControl_Writer.cxx | 17 +- src/STEPControl/STEPControl_ActorRead.cxx | 23 +-- src/StepVisual/StepVisual_StyledItem.cxx | 26 +-- src/StepVisual/StepVisual_StyledItem.hxx | 34 +++- src/Transfer/Transfer_Binder.cxx | 37 +++- src/Transfer/Transfer_Binder.hxx | 5 +- .../Transfer_SimpleBinderOfTransient.cxx | 2 +- src/XCAFDoc/XCAFDoc_ShapeTool.cxx | 10 +- src/XCAFDoc/XCAFDoc_ShapeTool.hxx | 2 +- src/XDEDRAW/XDEDRAW_Common.cxx | 73 +++++--- tests/perf/de/begin | 2 +- tests/perf/de/bug29830_1 | 2 + tests/perf/de/bug29830_2 | 2 + tests/perf/de/bug29830_3 | 24 +++ tests/perf/de/bug29830_dir/script | 105 ++++++++++++ 17 files changed, 349 insertions(+), 185 deletions(-) create mode 100644 tests/perf/de/bug29830_1 create mode 100644 tests/perf/de/bug29830_2 create mode 100644 tests/perf/de/bug29830_3 create mode 100644 tests/perf/de/bug29830_dir/script diff --git a/src/STEPCAFControl/STEPCAFControl_Reader.cxx b/src/STEPCAFControl/STEPCAFControl_Reader.cxx index e3b8c9997b..ed6444d425 100644 --- a/src/STEPCAFControl/STEPCAFControl_Reader.cxx +++ b/src/STEPCAFControl/STEPCAFControl_Reader.cxx @@ -658,7 +658,7 @@ Standard_Boolean STEPCAFControl_Reader::Transfer (STEPControl_Reader &reader, // read colors if ( GetColorMode() ) - ReadColors ( reader.WS(), doc, PDFileMap, map ); + ReadColors ( reader.WS(), doc, map ); // read names if ( GetNameMode() ) @@ -737,7 +737,7 @@ TDF_Label STEPCAFControl_Reader::AddShape (const TopoDS_Shape &S, Standard_Boolean isAssembly = Standard_False; Standard_Integer nbComponents = 0; TopoDS_Iterator it; - for ( it.Initialize(S); it.More(); it.Next(), nbComponents++ ) { + for ( it.Initialize(S); it.More() && !isAssembly; it.Next(), nbComponents++ ) { TopoDS_Shape Sub0 = it.Value(); TopLoc_Location loc; Sub0.Location ( loc ); @@ -781,13 +781,15 @@ TDF_Label STEPCAFControl_Reader::AddShape (const TopoDS_Shape &S, // or as assembly, component-by-component TDF_Label L = STool->NewShape(); + nbComponents = 0; for ( it.Initialize(S); it.More(); it.Next(), nbComponents++ ) { TopoDS_Shape Sub0 = it.Value(); TopLoc_Location loc; Sub0.Location ( loc ); TDF_Label subL = AddShape ( Sub0, STool, NewShapesMap, ShapePDMap, PDFileMap, ShapeLabelMap ); if ( ! subL.IsNull() ) { - STool->AddComponent ( L, subL, it.Value().Location() ); + TDF_Label instL = STool->AddComponent ( L, subL, it.Value().Location() ); + ShapeLabelMap.Bind(it.Value(), instL); } } if ( SHAS.Length() >0 ) STool->SetExternRefs(L,SHAS); @@ -841,21 +843,6 @@ Handle(STEPCAFControl_ExternFile) STEPCAFControl_Reader::ReadExternFile (const S return EF; } - -//======================================================================= -//function : SetColorToSubshape -//purpose : auxilary -//======================================================================= -static void SetColorToSubshape(const Handle(XCAFDoc_ColorTool) & CTool, - const TopoDS_Shape & S, - const Quantity_Color& col, - const XCAFDoc_ColorType type) -{ - for (TopoDS_Iterator it(S); it.More(); it.Next()) - if (! CTool->SetColor( it.Value(), col, type)) break; -} - - //======================================================================= //function : findStyledSR //purpose : auxilary @@ -886,8 +873,7 @@ static void findStyledSR (const Handle(StepVisual_StyledItem) &style, //======================================================================= Standard_Boolean STEPCAFControl_Reader::ReadColors (const Handle(XSControl_WorkSession) &WS, - Handle(TDocStd_Document)& Doc, - const STEPCAFControl_DataMapOfPDExternFile &PDFileMap, + Handle(TDocStd_Document)& Doc, const XCAFDoc_DataMapOfShapeLabel &ShapeLabelMap) const { STEPConstruct_Styles Styles ( WS ); @@ -903,6 +889,8 @@ Standard_Boolean STEPCAFControl_Reader::ReadColors (const Handle(XSControl_WorkS Handle(XCAFDoc_ColorTool) CTool = XCAFDoc_DocumentTool::ColorTool( Doc->Main() ); if ( CTool.IsNull() ) return Standard_False; + Handle(XCAFDoc_ShapeTool) STool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); + if (STool.IsNull()) return Standard_False; // parse and search for color attributes Standard_Integer nb = Styles.NbStyles(); @@ -979,7 +967,7 @@ Standard_Boolean STEPCAFControl_Reader::ReadColors (const Handle(XSControl_WorkS TopoDS_Shape aSh; // PTV 10.02.2003 to find component of assembly CORRECTLY STEPConstruct_Tool Tool( WS ); - TDF_Label aShLab = FindInstance ( NAUO, CTool->ShapeTool(), Tool, PDFileMap, ShapeLabelMap ); + TDF_Label aShLab = FindInstance ( NAUO, CTool->ShapeTool(), Tool, ShapeLabelMap ); aSh = CTool->ShapeTool()->GetShape(aShLab); if (!aSh.IsNull()) { S = aSh; @@ -994,29 +982,51 @@ Standard_Boolean STEPCAFControl_Reader::ReadColors (const Handle(XSControl_WorkS if ( S.IsNull() ) continue; - if ( ! SurfCol.IsNull() ) { - Quantity_Color col; - Styles.DecodeColor ( SurfCol, col ); - if ( ! CTool->SetColor ( S, col, XCAFDoc_ColorSurf )) - SetColorToSubshape( CTool, S, col, XCAFDoc_ColorSurf ); - } - if ( ! BoundCol.IsNull() ) { - Quantity_Color col; - Styles.DecodeColor ( BoundCol, col ); - if ( ! CTool->SetColor ( S, col, XCAFDoc_ColorCurv )) - SetColorToSubshape( CTool, S, col, XCAFDoc_ColorCurv ); - } - if ( ! CurveCol.IsNull() ) { - Quantity_Color col; - Styles.DecodeColor ( CurveCol, col ); - if ( ! CTool->SetColor ( S, col, XCAFDoc_ColorCurv )) - SetColorToSubshape( CTool, S, col, XCAFDoc_ColorCurv ); - } - if ( !IsVisible ) { - // sets the invisibility for shape. - TDF_Label aInvL; - if ( CTool->ShapeTool()->Search( S, aInvL ) ) - CTool->SetVisibility( aInvL, Standard_False ); + if (!SurfCol.IsNull() || !BoundCol.IsNull() || !CurveCol.IsNull() || !IsVisible) + { + TDF_Label aL; + Standard_Boolean isFound = STool->SearchUsingMap(S, aL, Standard_False, Standard_True); + if (!SurfCol.IsNull() || !BoundCol.IsNull() || !CurveCol.IsNull()) + { + Quantity_Color aSCol, aBCol, aCCol; + if (!SurfCol.IsNull()) + Styles.DecodeColor(SurfCol, aSCol); + if (!BoundCol.IsNull()) + Styles.DecodeColor(BoundCol, aBCol); + if (!CurveCol.IsNull()) + Styles.DecodeColor(CurveCol, aCCol); + if (isFound) + { + if (!SurfCol.IsNull()) + CTool->SetColor(aL, aSCol, XCAFDoc_ColorSurf); + if (!BoundCol.IsNull()) + CTool->SetColor(aL, aBCol, XCAFDoc_ColorCurv); + if (!CurveCol.IsNull()) + CTool->SetColor(aL, aCCol, XCAFDoc_ColorCurv); + } + else + { + for (TopoDS_Iterator it(S); it.More(); it.Next()) + { + TDF_Label aL1; + if (STool->SearchUsingMap(it.Value(), aL1, Standard_False, Standard_True)) + { + if (!SurfCol.IsNull()) + CTool->SetColor(aL1, aSCol, XCAFDoc_ColorSurf); + if (!BoundCol.IsNull()) + CTool->SetColor(aL1, aBCol, XCAFDoc_ColorCurv); + if (!CurveCol.IsNull()) + CTool->SetColor(aL1, aCCol, XCAFDoc_ColorCurv); + } + } + } + } + if (!IsVisible) + { + // sets the invisibility for shape. + if (isFound) + CTool->SetVisibility(aL, Standard_False); + } } } } @@ -1050,7 +1060,6 @@ static TDF_Label GetLabelFromPD (const Handle(StepBasic_ProductDefinition) &PD, S = TransferBRep::ShapeResult ( TP, binder ); if ( S.IsNull() ) return L; - if ( S.IsNull() ) return L; if ( ShapeLabelMap.IsBound ( S ) ) L = ShapeLabelMap.Find ( S ); if ( L.IsNull() ) @@ -1066,7 +1075,6 @@ static TDF_Label GetLabelFromPD (const Handle(StepBasic_ProductDefinition) &PD, TDF_Label STEPCAFControl_Reader::FindInstance (const Handle(StepRepr_NextAssemblyUsageOccurrence) &NAUO, const Handle(XCAFDoc_ShapeTool) &STool, const STEPConstruct_Tool &Tool, - const STEPCAFControl_DataMapOfPDExternFile &PDFileMap, const XCAFDoc_DataMapOfShapeLabel &ShapeLabelMap) { TDF_Label L; @@ -1089,50 +1097,11 @@ TDF_Label STEPCAFControl_Reader::FindInstance (const Handle(StepRepr_NextAssembl return L; } - // find component`s original label - Handle(StepBasic_ProductDefinition) PD = NAUO->RelatedProductDefinition(); - if ( PD.IsNull() ) return L; - TDF_Label Lref = GetLabelFromPD ( PD, STool, TP, PDFileMap, ShapeLabelMap ); - if ( Lref.IsNull() ) return L; - - // find main shape (assembly) label - PD.Nullify(); - PD = NAUO->RelatingProductDefinition(); - if ( PD.IsNull() ) return L; - TDF_Label L0 = GetLabelFromPD ( PD, STool, TP, PDFileMap, ShapeLabelMap ); - if ( L0.IsNull() ) return L; - - // if CDSR and NAUO are reversed, swap labels - Handle(StepShape_ContextDependentShapeRepresentation) CDSR; - Interface_EntityIterator subs1 = Tool.Graph().Sharings(NAUO); - for (subs1.Start(); subs1.More(); subs1.Next()) { - Handle(StepRepr_ProductDefinitionShape) PDS = - Handle(StepRepr_ProductDefinitionShape)::DownCast(subs1.Value()); - if(PDS.IsNull()) continue; - Interface_EntityIterator subs2 = Tool.Graph().Sharings(PDS); - for (subs2.Start(); subs2.More(); subs2.Next()) { - Handle(StepShape_ContextDependentShapeRepresentation) CDSRtmp = - Handle(StepShape_ContextDependentShapeRepresentation)::DownCast(subs2.Value()); - if (CDSRtmp.IsNull()) continue; - CDSR = CDSRtmp; - } - } - if (CDSR.IsNull()) return L; -// if ( STEPConstruct_Assembly::CheckSRRReversesNAUO ( Tool.Model(), CDSR ) ) { -// TDF_Label Lsw = L0; L0 = Lref; Lref = Lsw; -// } - - // iterate on components to find proper one - TDF_LabelSequence seq; - XCAFDoc_ShapeTool::GetComponents ( L0, seq ); - for ( Standard_Integer k=1; L.IsNull() && k <= seq.Length(); k++ ) { - TDF_Label Lcomp = seq(k), Lref2; - if ( XCAFDoc_ShapeTool::GetReferredShape ( Lcomp, Lref2 ) && - Lref2 == Lref && - S.Location() == XCAFDoc_ShapeTool::GetLocation ( Lcomp ) ) - L = Lcomp; - } - + if (ShapeLabelMap.IsBound(S)) + L = ShapeLabelMap(S); + else + STool->Search(S, L, Standard_True, Standard_True, Standard_False); + return L; } @@ -1183,7 +1152,7 @@ Standard_Boolean STEPCAFControl_Reader::ReadNames (const Handle(XSControl_WorkSe else name = new TCollection_HAsciiString; } // find proper label - L = FindInstance ( NAUO, STool, Tool, PDFileMap, ShapeLabelMap ); + L = FindInstance ( NAUO, STool, Tool, ShapeLabelMap ); if ( L.IsNull() ) continue; TCollection_ExtendedString str ( name->String() ); TDataStd_Name::Set ( L, str ); @@ -1293,7 +1262,7 @@ Standard_Boolean STEPCAFControl_Reader::ReadValProps (const Handle(XSControl_Wor NAUO = Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(subs1.Value()); } if ( !NAUO.IsNull() ) { - L = FindInstance ( NAUO, STool, WS, PDFileMap, ShapeLabelMap ); + L = FindInstance ( NAUO, STool, WS, ShapeLabelMap ); if ( L.IsNull() ) continue; } else { @@ -1476,7 +1445,7 @@ static Standard_Boolean findNextSHUOlevel (const Handle(XSControl_WorkSession) & // get label of NAUO next level TDF_Label NULab; STEPConstruct_Tool Tool( WS ); - NULab = STEPCAFControl_Reader::FindInstance ( NUNAUO, STool, Tool, PDFileMap, ShapeLabelMap ); + NULab = STEPCAFControl_Reader::FindInstance ( NUNAUO, STool, Tool, ShapeLabelMap ); // STool->Search(NUSh, NUlab); if (NULab.IsNull()) return Standard_False; @@ -1524,8 +1493,8 @@ static TDF_Label setSHUOintoDoc (const Handle(XSControl_WorkSession) &WS, // get first labels for first SHUO attribute TDF_Label UULab, NULab; STEPConstruct_Tool Tool( WS ); - UULab = STEPCAFControl_Reader::FindInstance ( UUNAUO, STool, Tool, PDFileMap, ShapeLabelMap ); - NULab = STEPCAFControl_Reader::FindInstance ( NUNAUO, STool, Tool, PDFileMap, ShapeLabelMap ); + UULab = STEPCAFControl_Reader::FindInstance ( UUNAUO, STool, Tool, ShapeLabelMap ); + NULab = STEPCAFControl_Reader::FindInstance ( NUNAUO, STool, Tool, ShapeLabelMap ); // STool->Search(UUSh, UULab); // STool->Search(NUSh, NULab); diff --git a/src/STEPCAFControl/STEPCAFControl_Reader.hxx b/src/STEPCAFControl/STEPCAFControl_Reader.hxx index 8902c8d43e..6281506d88 100644 --- a/src/STEPCAFControl/STEPCAFControl_Reader.hxx +++ b/src/STEPCAFControl/STEPCAFControl_Reader.hxx @@ -120,7 +120,11 @@ public: //! Returns label of instance of an assembly component //! corresponding to a given NAUO - Standard_EXPORT static TDF_Label FindInstance (const Handle(StepRepr_NextAssemblyUsageOccurrence)& NAUO, const Handle(XCAFDoc_ShapeTool)& STool, const STEPConstruct_Tool& Tool, const STEPCAFControl_DataMapOfPDExternFile& PDRFileMap, const XCAFDoc_DataMapOfShapeLabel& ShapeLabelMap); + Standard_EXPORT static TDF_Label FindInstance + (const Handle(StepRepr_NextAssemblyUsageOccurrence)& NAUO, + const Handle(XCAFDoc_ShapeTool)& STool, + const STEPConstruct_Tool& Tool, + const XCAFDoc_DataMapOfShapeLabel& ShapeLabelMap); //! Set ColorMode for indicate read Colors or not. Standard_EXPORT void SetColorMode (const Standard_Boolean colormode); @@ -189,7 +193,10 @@ protected: //! Reads style assignments from STEP model and sets //! corresponding color assignments in the DECAF document - Standard_EXPORT Standard_Boolean ReadColors (const Handle(XSControl_WorkSession)& WS, Handle(TDocStd_Document)& doc, const STEPCAFControl_DataMapOfPDExternFile& PDFileMap, const XCAFDoc_DataMapOfShapeLabel& ShapeLabelMap) const; + Standard_EXPORT Standard_Boolean ReadColors + (const Handle(XSControl_WorkSession)& WS, + Handle(TDocStd_Document)& doc, + const XCAFDoc_DataMapOfShapeLabel& ShapeLabelMap) const; //! Reads names of parts defined in the STEP model and //! assigns them to corresponding labels in the DECAF document diff --git a/src/STEPCAFControl/STEPCAFControl_Writer.cxx b/src/STEPCAFControl/STEPCAFControl_Writer.cxx index 32ea6b0533..f0580416e6 100644 --- a/src/STEPCAFControl/STEPCAFControl_Writer.cxx +++ b/src/STEPCAFControl/STEPCAFControl_Writer.cxx @@ -937,7 +937,9 @@ static Standard_Boolean getStyledItem(const TopoDS_Shape& S, // search for PSA of Monifold solid if ( !anSelItmHArr.IsNull() ) { - for (Standard_Integer si = 1; si <= anSelItmHArr->Length(); si++) { + TColStd_SequenceOfTransient aNewseqRI; + Standard_Boolean isFilled = Standard_False; + for (Standard_Integer si = 1; si <= anSelItmHArr->Length() && !found; si++) { Handle(StepVisual_StyledItem) aSelItm = Handle(StepVisual_StyledItem)::DownCast(anSelItmHArr->Value(si)); @@ -945,13 +947,16 @@ static Standard_Boolean getStyledItem(const TopoDS_Shape& S, continue; // check that it is a stiled item for monifold solid brep - TopLoc_Location Loc; - TColStd_SequenceOfTransient aNewseqRI; - FindEntities ( Styles.FinderProcess(), aTopLevSh, Loc, aNewseqRI ); + if (!isFilled) + { + TopLoc_Location Loc; + FindEntities(Styles.FinderProcess(), aTopLevSh, Loc, aNewseqRI); + isFilled = Standard_True; + } if ( aNewseqRI.Length() > 0 ) { - Handle(StepRepr_RepresentationItem) anItem = aSelItm->Item(); + const Handle(StepRepr_RepresentationItem)& anItem = aSelItm->Item(); Standard_Boolean isSameMonSolBR = Standard_False; for (Standard_Integer mi = 1; mi <= aNewseqRI.Length(); mi++) { if ( !anItem.IsNull() && anItem == aNewseqRI.Value( mi ) ) { @@ -965,7 +970,7 @@ static Standard_Boolean getStyledItem(const TopoDS_Shape& S, for (Standard_Integer jsi = 1; jsi <= aSelItm->NbStyles() && !found; jsi++) { - Handle(StepVisual_PresentationStyleAssignment) aFatherPSA = aSelItm->StylesValue(jsi); + const Handle(StepVisual_PresentationStyleAssignment)& aFatherPSA = aSelItm->StylesValue(jsi); // check for PSA for top-level (not Presentation style by contex for NAUO) if (aFatherPSA.IsNull() || aFatherPSA->IsKind(STANDARD_TYPE(StepVisual_PresentationStyleByContext))) continue; diff --git a/src/STEPControl/STEPControl_ActorRead.cxx b/src/STEPControl/STEPControl_ActorRead.cxx index 1dbbc2c226..3ea8eb46c7 100644 --- a/src/STEPControl/STEPControl_ActorRead.cxx +++ b/src/STEPControl/STEPControl_ActorRead.cxx @@ -658,7 +658,7 @@ static void getSDR(const Handle(StepRepr_ProductDefinitionShape)& PDS, Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Handle(StepRepr_NextAssemblyUsageOccurrence)& NAUO , const Handle(Transfer_TransientProcess)& TP) { - Handle(TransferBRep_ShapeBinder) shbinder; + Handle(TransferBRep_ShapeBinder) shbinder; Handle(StepBasic_ProductDefinition) PD; const Interface_Graph& graph = TP->Graph(); gp_Trsf Trsf; @@ -685,21 +685,24 @@ Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Han // find real ProductDefinition used rep Interface_EntityIterator subs3 = TP->Graph().Sharings(rep); for (subs3.Start(); subs3.More(); subs3.Next()) { - if ( subs3.Value()->IsKind(STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation))) { - DeclareAndCast(StepShape_ShapeDefinitionRepresentation,SDR,subs3.Value()); + const Handle(Standard_Transient)& aSubs3Val = subs3.Value(); + if (Handle(StepShape_ShapeDefinitionRepresentation) SDR = + Handle(StepShape_ShapeDefinitionRepresentation)::DownCast (aSubs3Val)) + { Handle(StepRepr_ProductDefinitionShape) PDS1 = Handle(StepRepr_ProductDefinitionShape)::DownCast(SDR->Definition().PropertyDefinition()); if(PDS1.IsNull()) continue; Interface_EntityIterator subs4 = graph.Shareds(PDS1); - for (subs4.Start(); subs4.More(); subs4.Next()) { - Handle(StepBasic_ProductDefinition) PD1 = - Handle(StepBasic_ProductDefinition)::DownCast(subs4.Value()); - if(PD1.IsNull()) continue; - PD=PD1; + for (subs4.Start(); PD.IsNull() && subs4.More(); subs4.Next()) + { + PD = Handle(StepBasic_ProductDefinition)::DownCast(subs4.Value()); } } - else if(subs3.Value()->IsKind(STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship))) { - SRR = Handle(StepRepr_ShapeRepresentationRelationship)::DownCast(subs3.Value()); + else if (aSubs3Val->IsKind (STANDARD_TYPE(StepRepr_ShapeRepresentationRelationship))) + { + // NB: C cast is used instead of DownCast() to improve performance on some cases. + // This saves ~10% of elapsed time on "testgrid perf de bug29* -parallel 0". + SRR = (StepRepr_ShapeRepresentationRelationship*)(aSubs3Val.get()); } } } diff --git a/src/StepVisual/StepVisual_StyledItem.cxx b/src/StepVisual/StepVisual_StyledItem.cxx index 7e897d37b7..781cb180ab 100644 --- a/src/StepVisual/StepVisual_StyledItem.cxx +++ b/src/StepVisual/StepVisual_StyledItem.cxx @@ -20,8 +20,6 @@ IMPLEMENT_STANDARD_RTTIEXT(StepVisual_StyledItem,StepRepr_RepresentationItem) -StepVisual_StyledItem::StepVisual_StyledItem () {} - void StepVisual_StyledItem::Init( const Handle(TCollection_HAsciiString)& aName, const Handle(StepVisual_HArray1OfPresentationStyleAssignment)& aStyles, @@ -30,6 +28,7 @@ void StepVisual_StyledItem::Init( // --- classe own fields --- myStyles = aStyles; myItem = aItem; + myReprItem = Handle(StepRepr_RepresentationItem)::DownCast(aItem); // --- classe inherited fields --- StepRepr_RepresentationItem::Init(aName); } @@ -39,35 +38,16 @@ void StepVisual_StyledItem::SetStyles(const Handle(StepVisual_HArray1OfPresentat myStyles = aStyles; } -Handle(StepVisual_HArray1OfPresentationStyleAssignment) StepVisual_StyledItem::Styles() const -{ - return myStyles; -} - -Handle(StepVisual_PresentationStyleAssignment) StepVisual_StyledItem::StylesValue(const Standard_Integer num) const -{ - return myStyles->Value(num); -} - -Standard_Integer StepVisual_StyledItem::NbStyles () const -{ - if (myStyles.IsNull()) return 0; - return myStyles->Length(); -} - void StepVisual_StyledItem::SetItem(const Handle(StepRepr_RepresentationItem)& aItem) { myItem = aItem; + myReprItem = aItem; } void StepVisual_StyledItem::SetItem(const StepVisual_StyledItemTarget& theItem) { myItem = theItem.Value(); -} - -Handle(StepRepr_RepresentationItem) StepVisual_StyledItem::Item() const -{ - return Handle(StepRepr_RepresentationItem)::DownCast(myItem); + myReprItem = Handle(StepRepr_RepresentationItem)::DownCast(myItem); } StepVisual_StyledItemTarget StepVisual_StyledItem::ItemAP242() const diff --git a/src/StepVisual/StepVisual_StyledItem.hxx b/src/StepVisual/StepVisual_StyledItem.hxx index b244f38dcb..94d0f9fd34 100644 --- a/src/StepVisual/StepVisual_StyledItem.hxx +++ b/src/StepVisual/StepVisual_StyledItem.hxx @@ -40,21 +40,35 @@ public: //! Returns a StyledItem - Standard_EXPORT StepVisual_StyledItem(); - + StepVisual_StyledItem() + {} + Standard_EXPORT void Init (const Handle(TCollection_HAsciiString)& aName, const Handle(StepVisual_HArray1OfPresentationStyleAssignment)& aStyles, const Handle(Standard_Transient)& aItem); Standard_EXPORT void SetStyles (const Handle(StepVisual_HArray1OfPresentationStyleAssignment)& aStyles); - Standard_EXPORT Handle(StepVisual_HArray1OfPresentationStyleAssignment) Styles() const; - - Standard_EXPORT Handle(StepVisual_PresentationStyleAssignment) StylesValue (const Standard_Integer num) const; - - Standard_EXPORT Standard_Integer NbStyles() const; + const Handle(StepVisual_HArray1OfPresentationStyleAssignment)& Styles() const + { + return myStyles; + } + const Handle(StepVisual_PresentationStyleAssignment)& StylesValue + (const Standard_Integer num) const + { + return myStyles->Value(num); + } + + Standard_Integer NbStyles() const + { + return myStyles.IsNull() ? 0 : myStyles->Length(); + } + Standard_EXPORT void SetItem (const Handle(StepRepr_RepresentationItem)& aItem); - Standard_EXPORT Handle(StepRepr_RepresentationItem) Item() const; + const Handle(StepRepr_RepresentationItem)& Item() const + { + return myReprItem; + } Standard_EXPORT void SetItem (const StepVisual_StyledItemTarget& aItem); @@ -73,8 +87,10 @@ private: Handle(StepVisual_HArray1OfPresentationStyleAssignment) myStyles; - // May be StepRepr_RepresentationItem for AP214(203) and StepVisual_StyledItemTarget for AP242 + //! May be StepRepr_RepresentationItem for AP214(203) and StepVisual_StyledItemTarget for AP242 Handle(Standard_Transient) myItem; + //! This is downcasted from myItem + Handle(StepRepr_RepresentationItem) myReprItem; }; diff --git a/src/Transfer/Transfer_Binder.cxx b/src/Transfer/Transfer_Binder.cxx index 7a83566f56..bf99ca12bb 100644 --- a/src/Transfer/Transfer_Binder.cxx +++ b/src/Transfer/Transfer_Binder.cxx @@ -77,20 +77,17 @@ void Transfer_Binder::AddResult (const Handle(Transfer_Binder)& next) thenextr = next; else { //Modification of recursive to cycle - Handle(Transfer_Binder) theBinder = thenextr; + Handle(Transfer_Binder) theBinder = theendr.IsNull() ? thenextr : theendr; while( theBinder != next ) { if( theBinder->NextResult().IsNull() ) { theBinder->AddResult(next); + theendr = next; return; } else theBinder = theBinder->NextResult(); } } - //former recursive - // if (thenextr.IsNull()) thenextr = next; - // else if (thenextr == next) return; - // else thenextr->AddResult (next); } //======================================================================= @@ -101,7 +98,11 @@ void Transfer_Binder::AddResult (const Handle(Transfer_Binder)& next) void Transfer_Binder::CutResult (const Handle(Transfer_Binder)& next) { if (thenextr.IsNull()) return; - if (thenextr == next) thenextr.Nullify(); + if (thenextr == next) + { + thenextr.Nullify(); + theendr.Nullify(); + } //else thenextr->CutResult (next); else { Handle(Transfer_Binder) currBinder = thenextr, currNext; @@ -223,3 +224,27 @@ Handle(Interface_Check) Transfer_Binder::CCheck () return thecheck; } +//======================================================================= +//function : Destructor +//purpose : +//======================================================================= + +Transfer_Binder::~Transfer_Binder() +{ + // To prevent stack overflow on long chains it is needed + // to avoid recursive destruction of the field thenextr + if (!thenextr.IsNull()) + { + Handle(Transfer_Binder) aCurr = thenextr; + theendr.Nullify(); + thenextr.Nullify(); + // we check GetRefCount in order to not destroy a chain if it belongs also + // to another upper level chain (two chains continue at the same binder) + while (!aCurr->thenextr.IsNull() && aCurr->thenextr->GetRefCount() == 1) + { + Handle(Transfer_Binder) aPrev = aCurr; + aCurr = aCurr->thenextr; + aPrev->thenextr.Nullify(); + } + } +} diff --git a/src/Transfer/Transfer_Binder.hxx b/src/Transfer/Transfer_Binder.hxx index 13fb853333..52e7b2d0cc 100644 --- a/src/Transfer/Transfer_Binder.hxx +++ b/src/Transfer/Transfer_Binder.hxx @@ -134,8 +134,8 @@ public: //! it (adding messages, or replacing it) Standard_EXPORT Handle(Interface_Check) CCheck(); - - + //! Destructor + Standard_EXPORT ~Transfer_Binder(); DEFINE_STANDARD_RTTIEXT(Transfer_Binder,Standard_Transient) @@ -165,6 +165,7 @@ private: Transfer_StatusExec theexecst; Handle(Interface_Check) thecheck; Handle(Transfer_Binder) thenextr; + Handle(Transfer_Binder) theendr; }; diff --git a/src/Transfer/Transfer_SimpleBinderOfTransient.cxx b/src/Transfer/Transfer_SimpleBinderOfTransient.cxx index 44a7d14a8c..c3ec56531d 100644 --- a/src/Transfer/Transfer_SimpleBinderOfTransient.cxx +++ b/src/Transfer/Transfer_SimpleBinderOfTransient.cxx @@ -63,7 +63,7 @@ Transfer_SimpleBinderOfTransient::Transfer_SimpleBinderOfTransient () { } Handle(Transfer_SimpleBinderOfTransient)::DownCast(bn); bn = bn->NextResult(); if (trb.IsNull()) continue; - Handle(Standard_Transient) rs = trb->Result(); + const Handle(Standard_Transient)& rs = trb->Result(); if (rs.IsNull()) continue; if (!rs->IsKind(atype)) continue; res = rs; diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx index 553b15d69f..a900b749c0 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx @@ -932,7 +932,7 @@ Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L, TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, const TDF_Label& compL, - const TopLoc_Location &Loc) const + const TopLoc_Location &Loc) { TDF_Label L; @@ -949,6 +949,14 @@ TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, L = aTag.NewChild(assembly); MakeReference ( L, compL, Loc ); + // map shape to label + TopoDS_Shape aShape; + if (GetShape(L, aShape)) + { + if (!myShapeLabels.IsBound(aShape)) + myShapeLabels.Bind(aShape, L); + } + return L; } diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx index 2df242a5dc..a8adf831dc 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx @@ -273,7 +273,7 @@ public: //! Adds a component given by its label and location to the assembly //! Note: assembly must be IsAssembly() or IsSimpleShape() - Standard_EXPORT TDF_Label AddComponent (const TDF_Label& assembly, const TDF_Label& comp, const TopLoc_Location& Loc) const; + Standard_EXPORT TDF_Label AddComponent (const TDF_Label& assembly, const TDF_Label& comp, const TopLoc_Location& Loc); //! Adds a shape (located) as a component to the assembly //! If necessary, creates an additional top-level shape for diff --git a/src/XDEDRAW/XDEDRAW_Common.cxx b/src/XDEDRAW/XDEDRAW_Common.cxx index 8c43066b1b..5fabb0eb25 100644 --- a/src/XDEDRAW/XDEDRAW_Common.cxx +++ b/src/XDEDRAW/XDEDRAW_Common.cxx @@ -193,8 +193,13 @@ static Standard_Integer ReadIges (Draw_Interpretor& di, Standard_Integer argc, c DeclareAndCast(IGESControl_Controller,ctl,XSDRAW::Controller()); if (ctl.IsNull()) XSDRAW::SetNorm("IGES"); + TCollection_AsciiString fnom, rnom; + Standard_Boolean modfic = XSDRAW::FileAndVar(argv[2], argv[1], "IGES", fnom, rnom); + if (modfic) di << " File IGES to read : " << fnom.ToCString() << "\n"; + else di << " Model taken from the session : " << fnom.ToCString() << "\n"; + // di<<" -- Names of variables BREP-DRAW prefixed by : "<NbStartingEntities() > 0) readstat = IFSelect_RetDone; @@ -282,10 +282,18 @@ static Standard_Integer WriteIges (Draw_Interpretor& di, Standard_Integer argc, } writer.Transfer ( Doc ); - di << "Writig IGES model to file " << argv[2] << "\n"; - if ( writer.Write ( argv[2] ) ) di<<" Write OK\n"; - else di<<" Write failed\n"; - + TCollection_AsciiString fnom, rnom; + Standard_Boolean modfic = XSDRAW::FileAndVar(argv[2], argv[1], "IGES", fnom, rnom); + if (modfic) + { + di << "Writig IGES model to file " << argv[2] << "\n"; + if ( writer.Write ( argv[2] ) ) di<<" Write OK\n"; + else di<<" Write failed\n"; + } + else + { + di << "Document has been translated into the session"; + } return 0; } @@ -304,7 +312,13 @@ static Standard_Integer ReadStep (Draw_Interpretor& di, Standard_Integer argc, c DeclareAndCast(STEPControl_Controller,ctl,XSDRAW::Controller()); if (ctl.IsNull()) XSDRAW::SetNorm("STEP"); - STEPCAFControl_Reader reader ( XSDRAW::Session(),Standard_True); + TCollection_AsciiString fnom, rnom; + Standard_Boolean modfic = XSDRAW::FileAndVar(argv[2], argv[1], "STEP", fnom, rnom); + if (modfic) di << " File STEP to read : " << fnom.ToCString() << "\n"; + else di << " Model taken from the session : " << fnom.ToCString() << "\n"; + // di<<" -- Names of variables BREP-DRAW prefixed by : "<NbStartingEntities() > 0) readstat = IFSelect_RetDone; @@ -452,20 +461,28 @@ static Standard_Integer WriteStep (Draw_Interpretor& di, Standard_Integer argc, } } + TCollection_AsciiString fnom, rnom; + Standard_Boolean modfic = XSDRAW::FileAndVar(argv[2], argv[1], "STEP", fnom, rnom); + if (modfic) + { + di << "Writing STEP file " << argv[2] << "\n"; + IFSelect_ReturnStatus stat = writer.Write(argv[2]); + switch (stat) { + case IFSelect_RetVoid : di<<"No file written\n"; break; + case IFSelect_RetDone : { + di<<"File "< DicFile = writer.ExternFiles(); - FillDicWS( DicFile ); - AddWS( argv[2], XSDRAW::Session() ); - break; + NCollection_DataMap DicFile = writer.ExternFiles(); + FillDicWS( DicFile ); + AddWS( argv[2], XSDRAW::Session() ); + break; + } + default : di<<"Error on writing file\n"; break; } - default : di<<"Error on writing file\n"; break; + } + else + { + di << "Document has been translated into the session"; } return 0; } diff --git a/tests/perf/de/begin b/tests/perf/de/begin index 3d2248a44e..25b25de6cf 100644 --- a/tests/perf/de/begin +++ b/tests/perf/de/begin @@ -1 +1 @@ -pload XDE +pload XDE OCAF diff --git a/tests/perf/de/bug29830_1 b/tests/perf/de/bug29830_1 new file mode 100644 index 0000000000..10b9a0162b --- /dev/null +++ b/tests/perf/de/bug29830_1 @@ -0,0 +1,2 @@ +set use_sharing 1 +source "$dirname/$groupname/$gridname/bug29830_dir/script" diff --git a/tests/perf/de/bug29830_2 b/tests/perf/de/bug29830_2 new file mode 100644 index 0000000000..37f55c26a3 --- /dev/null +++ b/tests/perf/de/bug29830_2 @@ -0,0 +1,2 @@ +set use_sharing 0 +source "$dirname/$groupname/$gridname/bug29830_dir/script" diff --git a/tests/perf/de/bug29830_3 b/tests/perf/de/bug29830_3 new file mode 100644 index 0000000000..99d721b3de --- /dev/null +++ b/tests/perf/de/bug29830_3 @@ -0,0 +1,24 @@ +puts "========" +puts "0029830: Data Exchange, STEPCAFControl_Reader poor performance - quadratic dependence" +puts "========" +puts "Test on stack overflow during destructing the STEP model" + +set ncomp 1000 + +box a 1 1 1 +shape co C +for {set i 0} {$i < $ncomp} {incr i} { + tcopy a a1 + add a1 co +} +if [info exists D] {Close D} +XNewDoc D +XAddShape D co + +puts "Writing STEP model" +WriteStep D . +Close D + +puts "Destructing model" +#crash +newmodel diff --git a/tests/perf/de/bug29830_dir/script b/tests/perf/de/bug29830_dir/script new file mode 100644 index 0000000000..c98714f758 --- /dev/null +++ b/tests/perf/de/bug29830_dir/script @@ -0,0 +1,105 @@ +puts "========" +puts "0029830: Data Exchange, STEPCAFControl_Reader poor performance - quadratic dependence" +puts "========" +puts "" + +set copy_cmd tcopy + +if $use_sharing { + set copy_cmd copy +} + +set dx 2 +set dy 4 +set dz 6 +set nx0 20 +set ny 10 +set nz 10 + +if [info exists D] {Close D} +if [info exists D1] {Close D1} + +for {set npass 1} {$npass <= 2} {incr npass} { + + set nx [expr $nx0 * $npass] + puts "Creating assembly of $nx*$ny*$nz boxes" + plane a 0 0 0 1 0 0 + mkface a a 0 3 0 2 + shape co C + + for {set i 0} {$i < $nx} {incr i} { + for {set j 0} {$j < $ny} {incr j} { + for {set k 0} {$k < $nz} {incr k} { + eval $copy_cmd a a1 + ttranslate a1 $dx*$i $dy*$j $dz*$k + add a1 co + } + } + } + XNewDoc D + XAddShape D co + + puts "Assigning colors to components" + set i 0 + set j 0 + set k 0 + set shlist [explode co] + set lab [lindex [XFindComponent D co_1] 0] + set taglist [split $lab :] + foreach c $shlist { + set r [expr ($i%3)/3.] + set g [expr ($j%3)/3.] + set b [expr ($k%3)/3.] + set lab [join $taglist :] + XSetColor D $lab $r $g $b + incr k + if {$k%3 == 0} { + incr j + if {$j%3 == 0} { + incr i + } + } + set taglist "[lrange $taglist 0 end-1] [expr [lindex $taglist end] + 1]" + } + + puts "Writing STEP model" + chrono cr1 restart + WriteStep D . + chrono cr1 stop + Close D + + puts "Reading STEP model" + chrono cr2 restart + ReadStep D1 . + chrono cr2 stop + + # check one solid with different locations + XGetOneShape result D1 + if $use_sharing { + checknbshapes result -face 1 + checknbshapes result -face [expr $nx*$ny*$nz] -t + } else { + checknbshapes result -face [expr $nx*$ny*$nz] + checknbshapes result -face [expr $nx*$ny*$nz] -t + } + + if {$npass == 2} { + XShow D1 + vfit + vsetdispmode 1 + checkview -screenshot -3d -path ${imagedir}/${test_image}.png + } + Close D1 + + set time_write_$npass [lindex [dchrono cr1 counter "WriteStep_$npass"] end] + set time_read_$npass [lindex [dchrono cr2 counter "ReadStep_$npass"] end] +} + +puts "time_write_1=$time_write_1" +puts "time_write_2=$time_write_2" +puts "time_read_1=$time_read_1" +puts "time_read_2=$time_read_2" +set time_raise_write [expr $time_write_2 / $time_write_1] +set time_raise_read [expr $time_read_2 / $time_read_1] +puts "time_raise_write=$time_raise_write" +puts "time_raise_read=$time_raise_read"