]> OCCT Git - occt.git/commitdiff
0029830: STEPCAFControl_Reader poor performance - quadratic dependence
authormsv <msv@opencascade.com>
Fri, 1 Jun 2018 11:38:39 +0000 (14:38 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 20 Jul 2018 14:15:53 +0000 (17:15 +0300)
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.

17 files changed:
src/STEPCAFControl/STEPCAFControl_Reader.cxx
src/STEPCAFControl/STEPCAFControl_Reader.hxx
src/STEPCAFControl/STEPCAFControl_Writer.cxx
src/STEPControl/STEPControl_ActorRead.cxx
src/StepVisual/StepVisual_StyledItem.cxx
src/StepVisual/StepVisual_StyledItem.hxx
src/Transfer/Transfer_Binder.cxx
src/Transfer/Transfer_Binder.hxx
src/Transfer/Transfer_SimpleBinderOfTransient.cxx
src/XCAFDoc/XCAFDoc_ShapeTool.cxx
src/XCAFDoc/XCAFDoc_ShapeTool.hxx
src/XDEDRAW/XDEDRAW_Common.cxx
tests/perf/de/begin
tests/perf/de/bug29830_1 [new file with mode: 0644]
tests/perf/de/bug29830_2 [new file with mode: 0644]
tests/perf/de/bug29830_3 [new file with mode: 0644]
tests/perf/de/bug29830_dir/script [new file with mode: 0644]

index e3b8c9997b09cfecf4dc29e29746f5f3d304a5b0..ed6444d42528fb7748f0f4b67f18a1e8c10a5cc5 100644 (file)
@@ -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);
index 8902c8d43e116ea62f825ee74d2b727b21863a12..6281506d886d0f5e9f7de0ff7633615c3d3e5779 100644 (file)
@@ -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
index 32ea6b05339505322a2a1d032c281b7ac14dab36..f0580416e605d9d781db80313a4c5cf999d8c924 100644 (file)
@@ -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;
index 1dbbc2c2261ed1d5006aed632e1effbcbb30d343..3ea8eb46c7dcb8891b9c0725ae98c3adf73aa163 100644 (file)
@@ -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());
         }
       }
     }
index 7e897d37b78fc716668989373af7d2b7637dfaa7..781cb180ab45d6e6edcd5a9b9699fc7ffc4beb35 100644 (file)
@@ -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
index b244f38dcb61bd6b338507a87527f839de0c098d..94d0f9fd3477bed9eb0c72c333824ac0c5bf9377 100644 (file)
@@ -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;
 
 };
 
index 7a83566f5622f5421f92522ec12add1712fbd616..bf99ca12bb1dca79ce9813b1815631fcc76f3f3a 100644 (file)
@@ -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();
+    }
+  }
+}
index 13fb8533336a46f2c3e89426a82487e7ba5d042d..52e7b2d0ccc76a3ef63e47712b1289963eb48cdc 100644 (file)
@@ -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;
 
 
 };
index 44a7d14a8ce894e8fcc9cb5b2a8a4c262030b7b5..c3ec56531d7af7c902a972d89e0614adf5a88693 100644 (file)
@@ -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;
index 553b15d69f07261ae12fdbd0d4b6d9f1e00a51d5..a900b749c0b4fee9b88db333d3e6fdf8b0b3fb78 100644 (file)
@@ -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;
 }
 
index 2df242a5dc86749d33182717e72071c68e90d937..a8adf831dc3f9fe190e23ce5d44636fe25c4b84b 100644 (file)
@@ -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
index 8c43066b1b893a0714e8eac352b4536a584aafcc..5fabb0eb259455b6d75bc7127a178ed56542569b 100644 (file)
@@ -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 : "<<rnom<<"\n";
 
-  IGESCAFControl_Reader reader ( XSDRAW::Session(),Standard_True);
+  IGESCAFControl_Reader reader ( XSDRAW::Session(),modfic);
   Standard_Integer onlyvisible = Interface_Static::IVal("read.iges.onlyvisible");
   reader.SetReadVisible(onlyvisible == 1);
   
@@ -209,11 +214,6 @@ static Standard_Integer ReadIges (Draw_Interpretor& di, Standard_Integer argc, c
       case 'l' : reader.SetLayerMode (mode); break;
       }
   }
-  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 : "<<rnom<<"\n";
   IFSelect_ReturnStatus readstat = IFSelect_RetVoid;
   if (modfic) readstat = reader.ReadFile (fnom.ToCString());
   else  if (XSDRAW::Session()->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 : "<<rnom<<"\n";
+
+  STEPCAFControl_Reader reader ( XSDRAW::Session(),modfic);
   
   if (argc == 4) {
     Standard_Boolean mode = Standard_True;
@@ -319,11 +333,6 @@ static Standard_Integer ReadStep (Draw_Interpretor& di, Standard_Integer argc, c
       }
   }
   
-  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 : "<<rnom<<"\n";
   IFSelect_ReturnStatus readstat = IFSelect_RetVoid;
   if (modfic) readstat = reader.ReadFile (fnom.ToCString());
   else  if (XSDRAW::Session()->NbStartingEntities() > 0) readstat = IFSelect_RetDone;
@@ -452,20 +461,28 @@ static Standard_Integer WriteStep (Draw_Interpretor& di, Standard_Integer argc,
     }
   }
   
-
-  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 "<<argv[2]<<" written\n";
-
-      NCollection_DataMap<TCollection_AsciiString, Handle(STEPCAFControl_ExternFile)> DicFile = writer.ExternFiles();
-      FillDicWS( DicFile );
-      AddWS( argv[2], XSDRAW::Session() );
-      break;
+  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 "<<argv[2]<<" written\n";
+
+        NCollection_DataMap<TCollection_AsciiString, Handle(STEPCAFControl_ExternFile)> 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;
 }
index 3d2248a44ee30e8e9dce024804be383b4e48dd76..25b25de6cf000b8e99f2ec4c176ec9d0413c99fc 100644 (file)
@@ -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 (file)
index 0000000..10b9a01
--- /dev/null
@@ -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 (file)
index 0000000..37f55c2
--- /dev/null
@@ -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 (file)
index 0000000..99d721b
--- /dev/null
@@ -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 (file)
index 0000000..c98714f
--- /dev/null
@@ -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"