0030945: JT Import, JtProperty_LateLoaded - expose type of Deferred object IR-2019-12-06
authorkgv <kgv@opencascade.com>
Thu, 5 Dec 2019 13:20:37 +0000 (16:20 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 6 Dec 2019 16:38:01 +0000 (19:38 +0300)
RWMesh_NodeAttributes has been extended with NamedData property for passing Metadata.

RWMesh_CafReader::addShapeIntoDoc() has been corrected to avoid
adding calling XCAFDoc_ShapeTool::AddSubShape() for sub-shape labels.
Attributes for Products and Instances are now set independently to shape labels.
Sharing of Compounds (previously always duplicated) as sub-Components has been fixed.

TDataStd_NamedData has been extended with interface for deferred data loading.
Setters have been corrected to avoid duplicating lookups within map.

src/BinMDataStd/BinMDataStd_NamedDataDriver.cxx
src/DDataStd/DDataStd_BasicCommands.cxx
src/RWMesh/RWMesh_CafReader.cxx
src/RWMesh/RWMesh_CafReader.hxx
src/RWMesh/RWMesh_NodeAttributes.hxx
src/TDataStd/FILES
src/TDataStd/TDataStd_NamedData.cxx
src/TDataStd/TDataStd_NamedData.hxx
src/TDataStd/TDataStd_NamedData.lxx [deleted file]
src/XDEDRAW/XDEDRAW_Shapes.cxx
src/XmlMDataStd/XmlMDataStd_NamedDataDriver.cxx

index 15e64a4..294f785 100644 (file)
@@ -204,6 +204,7 @@ void BinMDataStd_NamedDataDriver::Paste(const Handle(TDF_Attribute)& theSource,
   if(S.IsNull()) return;
 //  Standard_Integer i=0;
 
+  S->LoadDeferredData();
   if(S->HasIntegers() && !S->GetIntegersContainer().IsEmpty()) {
     theTarget.PutInteger(1) << S->GetIntegersContainer().Extent(); //dim
     TColStd_DataMapIteratorOfDataMapOfStringInteger itr(S->GetIntegersContainer());
index 54dd87b..8e22399 100644 (file)
@@ -3202,6 +3202,7 @@ static Standard_Integer DDataStd_SetNDataIntegers2 (Draw_Interpretor& di,
   
     j = 1111;
     TCollection_ExtendedString aKey("Key_");
+    anAtt->LoadDeferredData();
     for(Standard_Integer i = 1; i<=aNumP; i++) {
       TCollection_ExtendedString key = aKey + i;
       Standard_Integer aVal = j+i;
@@ -3247,6 +3248,7 @@ static Standard_Integer DDataStd_SetNDataIntAr2 (Draw_Interpretor& di,
       anArr->SetValue(i, aVal);
       j++;
     }
+    anAtt->LoadDeferredData();
     anAtt->SetArrayOfIntegers(aKey, anArr); 
     return 0; 
   }
@@ -3363,6 +3365,7 @@ static Standard_Integer DDataStd_SetNDataIntegers (Draw_Interpretor& di,
       return 1;}
   
     j = 4;
+    anAtt->LoadDeferredData();
     for(Standard_Integer i = 1; i<=aNumP; i++) {
       TCollection_ExtendedString aKey(arg[j]);
       Standard_Integer aVal = Draw::Atoi(arg[j+1]);
@@ -3397,6 +3400,7 @@ static Standard_Integer DDataStd_GetNDIntegers (Draw_Interpretor& di,
       return 1;}
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;
+    anAtt->LoadDeferredData();
     const TColStd_DataMapOfStringInteger& aMap = anAtt->GetIntegersContainer();
     TColStd_DataMapIteratorOfDataMapOfStringInteger itr(aMap);
     for (; itr.More(); itr.Next()){
@@ -3434,6 +3438,7 @@ static Standard_Integer DDataStd_GetNDInteger (Draw_Interpretor& di,
 
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;    
+    anAtt->LoadDeferredData();
     if(!anAtt->HasInteger(arg[3])) {
       std::cout << "There is no data specified by Key = "<< arg[3]  << std::endl;
       return 1;
@@ -3473,6 +3478,7 @@ static Standard_Integer DDataStd_SetNDataReals (Draw_Interpretor& di,
       return 1;}
   
     j = 4;
+    anAtt->LoadDeferredData();
     for(Standard_Integer i = 1; i<=aNumP; i++) {
       TCollection_ExtendedString aKey(arg[j]);
       Standard_Real aVal = Draw::Atof(arg[j+1]);
@@ -3506,6 +3512,7 @@ static Standard_Integer DDataStd_GetNDReals (Draw_Interpretor& di,
       std::cout << "NamedData attribute is not found or not set"  << std::endl;
       return 1;}
     
+    anAtt->LoadDeferredData();
     const TDataStd_DataMapOfStringReal& aMap = anAtt->GetRealsContainer();
     TDataStd_DataMapIteratorOfDataMapOfStringReal itr(aMap);
     for (; itr.More(); itr.Next()){
@@ -3542,6 +3549,7 @@ static Standard_Integer DDataStd_GetNDReal (Draw_Interpretor& di,
 
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;    
+    anAtt->LoadDeferredData();
     if(!anAtt->HasReal(arg[3])) {
       std::cout << "There is no data specified by Key = "<< arg[3]  << std::endl;
       return 1;
@@ -3581,6 +3589,7 @@ static Standard_Integer DDataStd_SetNDataStrings (Draw_Interpretor& di,
       return 1;}
   
     j = 4;
+    anAtt->LoadDeferredData();
     for(Standard_Integer i = 1; i<=aNumP; i++) {
       TCollection_ExtendedString aKey(arg[j]);
       TCollection_ExtendedString aVal(arg[j+1]);
@@ -3614,6 +3623,7 @@ static Standard_Integer DDataStd_GetNDStrings (Draw_Interpretor& di,
       return 1;}
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;    
+    anAtt->LoadDeferredData();
     const TDataStd_DataMapOfStringString& aMap = anAtt->GetStringsContainer();
     TDataStd_DataMapIteratorOfDataMapOfStringString itr(aMap);
     for (; itr.More(); itr.Next()){
@@ -3651,6 +3661,7 @@ static Standard_Integer DDataStd_GetNDString (Draw_Interpretor& di,
 
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;    
+    anAtt->LoadDeferredData();
     if(!anAtt->HasString(arg[3])) {
       std::cout << "There is no data specified by Key = "<< arg[3]  << std::endl;
       return 1;
@@ -3691,6 +3702,7 @@ static Standard_Integer DDataStd_SetNDataBytes (Draw_Interpretor& di,
       return 1;}
   
     j = 4;
+    anAtt->LoadDeferredData();
     for(Standard_Integer i = 1; i<=aNumP; i++) {
       TCollection_ExtendedString aKey(arg[j]);
       Standard_Byte aVal = (Standard_Byte)Draw::Atoi(arg[j+1]);
@@ -3724,6 +3736,7 @@ static Standard_Integer DDataStd_GetNDBytes (Draw_Interpretor& di,
       return 1;}
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;      
+    anAtt->LoadDeferredData();
     const TDataStd_DataMapOfStringByte& aMap = anAtt->GetBytesContainer();
     TDataStd_DataMapIteratorOfDataMapOfStringByte itr(aMap);
     for (; itr.More(); itr.Next()){
@@ -3760,6 +3773,7 @@ static Standard_Integer DDataStd_GetNDByte (Draw_Interpretor& di,
 
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;      
+    anAtt->LoadDeferredData();
     if(!anAtt->HasByte(arg[3])) {
       std::cout << "There is no data specified by Key = "<< arg[3]  << std::endl;
       return 1;
@@ -3807,6 +3821,7 @@ static Standard_Integer DDataStd_SetNDataIntAr (Draw_Interpretor& di,
       anArr->SetValue(i, aVal);
       j++;
     }
+    anAtt->LoadDeferredData();
     anAtt->SetArrayOfIntegers(aKey, anArr); 
     return 0; 
   }
@@ -3836,6 +3851,7 @@ static Standard_Integer DDataStd_GetNDIntArrays (Draw_Interpretor& di,
       return 1;}
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;      
+    anAtt->LoadDeferredData();
     const TDataStd_DataMapOfStringHArray1OfInteger& aMap = anAtt->GetArraysOfIntegersContainer();
     TDataStd_DataMapIteratorOfDataMapOfStringHArray1OfInteger itr(aMap);
     for (; itr.More(); itr.Next()){
@@ -3881,6 +3897,7 @@ static Standard_Integer DDataStd_GetNDIntArray (Draw_Interpretor& di,
 
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;      
+    anAtt->LoadDeferredData();
     if(!anAtt->HasArrayOfIntegers(arg[3])) {
       std::cout << "There is no data specified by Key = "<< arg[3]  << std::endl;
       return 1;
@@ -3937,6 +3954,7 @@ static Standard_Integer DDataStd_SetNDataRealAr (Draw_Interpretor& di,
       anArr->SetValue(i, aVal);
       j++;
     }
+    anAtt->LoadDeferredData();
     anAtt->SetArrayOfReals(aKey, anArr); 
     return 0; 
   }
@@ -3966,6 +3984,7 @@ static Standard_Integer DDataStd_GetNDRealArrays (Draw_Interpretor& di,
       return 1;}
     std::cout <<std::endl;
     std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;      
+    anAtt->LoadDeferredData();
     const TDataStd_DataMapOfStringHArray1OfReal& aMap = anAtt->GetArraysOfRealsContainer();
     TDataStd_DataMapIteratorOfDataMapOfStringHArray1OfReal itr(aMap);
     for (; itr.More(); itr.Next()){
@@ -4010,7 +4029,8 @@ static Standard_Integer DDataStd_GetNDRealArray (Draw_Interpretor& di,
       return 1;}
 
     std::cout <<std::endl;
-    std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;      
+    std::cout <<"NamedData attribute at Label = " << arg[2] <<std::endl;
+    anAtt->LoadDeferredData();
     if(!anAtt->HasArrayOfReals(arg[3])) {
       std::cout << "There is no data specified by Key = "<< arg[3]  << std::endl;
       return 1;
index ec0fc02..436b8f2 100644 (file)
@@ -163,19 +163,114 @@ void RWMesh_CafReader::fillDocument()
   const Standard_Boolean wasAutoNaming = XCAFDoc_ShapeTool::AutoNaming();
   XCAFDoc_ShapeTool::SetAutoNaming (Standard_False);
   const TCollection_AsciiString aRootName; // = generateRootName (theFile);
+  CafDocumentTools aTools;
+  aTools.ShapeTool = XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main());
+  aTools.ColorTool = XCAFDoc_DocumentTool::ColorTool (myXdeDoc->Main());
+  aTools.VisMaterialTool = XCAFDoc_DocumentTool::VisMaterialTool (myXdeDoc->Main());
   for (TopTools_SequenceOfShape::Iterator aRootIter (myRootShapes); aRootIter.More(); aRootIter.Next())
   {
-    addShapeIntoDoc (aRootIter.Value(), TDF_Label(), aRootName);
+    addShapeIntoDoc (aTools, aRootIter.Value(), TDF_Label(), aRootName);
   }
   XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main())->UpdateAssemblies();
   XCAFDoc_ShapeTool::SetAutoNaming (wasAutoNaming);
 }
 
 // =======================================================================
+// function : setShapeName
+// purpose  :
+// =======================================================================
+void RWMesh_CafReader::setShapeName (const TDF_Label& theLabel,
+                                     const TopAbs_ShapeEnum theShapeType,
+                                     const TCollection_AsciiString& theName,
+                                     const TDF_Label& theParentLabel,
+                                     const TCollection_AsciiString& theParentName)
+{
+  if (!theName.IsEmpty())
+  {
+    TDataStd_Name::Set (theLabel, theName);
+  }
+  else if (!theParentLabel.IsNull())
+  {
+    TDataStd_Name::Set (theLabel, shapeTypeToString (theShapeType));
+  }
+  else if (theParentLabel.IsNull()
+       && !theParentName.IsEmpty())
+  {
+    TDataStd_Name::Set (theLabel, theParentName);
+  }
+}
+
+// =======================================================================
+// function : setShapeStyle
+// purpose  :
+// =======================================================================
+void RWMesh_CafReader::setShapeStyle (const CafDocumentTools& theTools,
+                                      const TDF_Label& theLabel,
+                                      const XCAFPrs_Style& theStyle)
+{
+  if (theStyle.IsSetColorSurf())
+  {
+    theTools.ColorTool->SetColor (theLabel, theStyle.GetColorSurfRGBA(), XCAFDoc_ColorSurf);
+  }
+  if (theStyle.IsSetColorCurv())
+  {
+    theTools.ColorTool->SetColor (theLabel, theStyle.GetColorCurv(), XCAFDoc_ColorCurv);
+  }
+  if (!theStyle.Material().IsNull())
+  {
+    TDF_Label aMaterialLabel = theStyle.Material()->Label();
+    if (aMaterialLabel.IsNull())
+    {
+      const TCollection_AsciiString aMatName = !theStyle.Material()->RawName().IsNull()
+                                             ?  theStyle.Material()->RawName()->String()
+                                             :  "";
+      aMaterialLabel = theTools.VisMaterialTool->AddMaterial (theStyle.Material(), aMatName);
+    }
+    theTools.VisMaterialTool->SetShapeMaterial (theLabel, aMaterialLabel);
+  }
+}
+
+// =======================================================================
+// function : setShapeNamedData
+// purpose  :
+// =======================================================================
+void RWMesh_CafReader::setShapeNamedData (const CafDocumentTools& ,
+                                          const TDF_Label& theLabel,
+                                          const Handle(TDataStd_NamedData)& theNameData)
+{
+  if (theNameData.IsNull())
+  {
+    return;
+  }
+
+  const TDF_Label aNameDataLabel = theNameData->Label();
+  Handle(TDataStd_NamedData) anOtherNamedData;
+  if (theLabel.FindAttribute (theNameData->ID(), anOtherNamedData))
+  {
+    if (anOtherNamedData->Label() != aNameDataLabel)
+    {
+      Message::DefaultMessenger()->Send ("Error! Different NamedData is already set to shape", Message_Alarm);
+    }
+  }
+  else
+  {
+    if (aNameDataLabel.IsNull())
+    {
+      theLabel.AddAttribute (theNameData);
+    }
+    else
+    {
+      Message::DefaultMessenger()->Send ("Error! Skipped NamedData instance shared across shapes", Message_Alarm);
+    }
+  }
+}
+
+// =======================================================================
 // function : addShapeIntoDoc
 // purpose  :
 // =======================================================================
-Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (const TopoDS_Shape& theShape,
+Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (CafDocumentTools& theTools,
+                                                    const TopoDS_Shape& theShape,
                                                     const TDF_Label& theLabel,
                                                     const TCollection_AsciiString& theParentName)
 {
@@ -185,10 +280,9 @@ Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (const TopoDS_Shape& theShape
     return Standard_False;
   }
 
-  Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main());
-
   const TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
   TopoDS_Shape aShapeToAdd = theShape;
+  const TopoDS_Shape aShapeNoLoc = theShape.Located (TopLoc_Location());
   Standard_Boolean toMakeAssembly = Standard_False;
   if (theShape.ShapeType() == TopAbs_COMPOUND)
   {
@@ -206,9 +300,9 @@ Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (const TopoDS_Shape& theShape
                     || (myAttribMap.Find (aFace, aSubFaceAttribs) && !aSubFaceAttribs.Name.IsEmpty());
     }
 
-    // create empty compound to add as assembly
     if (toMakeAssembly)
     {
+      // create an empty Compound to add as assembly, so that we can add children one-by-one via AddComponent()
       TopoDS_Compound aCompound;
       BRep_Builder aBuilder;
       aBuilder.MakeCompound (aCompound);
@@ -217,21 +311,35 @@ Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (const TopoDS_Shape& theShape
     }
   }
 
-  TDF_Label aNewLabel;
+  TDF_Label aNewLabel, anOldLabel;
   if (theLabel.IsNull())
   {
     // add new shape
-    aNewLabel = aShapeTool->AddShape (aShapeToAdd, toMakeAssembly);
+    aNewLabel = theTools.ShapeTool->AddShape (aShapeToAdd, toMakeAssembly);
   }
-  else if (aShapeTool->IsAssembly (theLabel))
+  else if (theTools.ShapeTool->IsAssembly (theLabel))
   {
     // add shape as component
-    aNewLabel = aShapeTool->AddComponent (theLabel, aShapeToAdd, toMakeAssembly);
+    if (theTools.ComponentMap.Find (aShapeNoLoc, anOldLabel))
+    {
+      aNewLabel = theTools.ShapeTool->AddComponent (theLabel, anOldLabel, theShape.Location());
+    }
+    else
+    {
+      aNewLabel = theTools.ShapeTool->AddComponent (theLabel, aShapeToAdd, toMakeAssembly);
+
+      TDF_Label aRefLabel = aNewLabel;
+      theTools.ShapeTool->GetReferredShape (aNewLabel, aRefLabel);
+      if (!aRefLabel.IsNull())
+      {
+        theTools.ComponentMap.Bind (aShapeNoLoc, aRefLabel);
+      }
+    }
   }
   else
   {
     // add shape as sub-shape
-    aNewLabel = aShapeTool->AddSubShape (theLabel, theShape);
+    aNewLabel = theTools.ShapeTool->AddSubShape (theLabel, theShape);
     if (!aNewLabel.IsNull())
     {
       Handle(XCAFDoc_ShapeMapTool) aShapeMapTool = XCAFDoc_ShapeMapTool::Set (aNewLabel);
@@ -245,57 +353,127 @@ Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (const TopoDS_Shape& theShape
 
   // if new label is a reference get referred shape
   TDF_Label aNewRefLabel = aNewLabel;
-  aShapeTool->GetReferredShape (aNewLabel, aNewRefLabel);
+  theTools.ShapeTool->GetReferredShape (aNewLabel, aNewRefLabel);
 
-  // store name
-  RWMesh_NodeAttributes aShapeAttribs;
-  myAttribMap.Find (theShape, aShapeAttribs);
-  if (aShapeAttribs.Name.IsEmpty())
+  RWMesh_NodeAttributes aRefShapeAttribs;
+  myAttribMap.Find (aShapeNoLoc, aRefShapeAttribs);
+
+  bool hasProductName = false;
+  if (aNewLabel != aNewRefLabel)
   {
-    if (theLabel.IsNull())
+    // put attributes to the Instance (overrides Product attributes)
+    RWMesh_NodeAttributes aShapeAttribs;
+    if (!theShape.Location().IsIdentity()
+      && myAttribMap.Find (theShape, aShapeAttribs))
     {
-      aShapeAttribs.Name = theParentName;
+      if (!aShapeAttribs.Style.IsEqual (aRefShapeAttribs.Style))
+      {
+        setShapeStyle (theTools, aNewLabel, aShapeAttribs.Style);
+      }
+      if (aShapeAttribs.NamedData != aRefShapeAttribs.NamedData)
+      {
+        setShapeNamedData (theTools, aNewLabel, aShapeAttribs.NamedData);
+      }
+      setShapeName (aNewLabel, aShapeType, aShapeAttribs.Name, theLabel, theParentName);
+      if (aRefShapeAttribs.Name.IsEmpty()
+      && !aShapeAttribs.Name.IsEmpty())
+      {
+        // it is not nice having unnamed Product, so copy name from first Instance (probably the only one)
+        hasProductName = true;
+        setShapeName (aNewRefLabel, aShapeType, aShapeAttribs.Name, theLabel, theParentName);
+      }
     }
-    if (aShapeAttribs.Name.IsEmpty()
-    && !theLabel.IsNull())
+    else
     {
-      aShapeAttribs.Name = shapeTypeToString (aShapeType);
+      // copy name from Product
+      setShapeName (aNewLabel, aShapeType, aRefShapeAttribs.Name, theLabel, theParentName);
     }
   }
-  if (!aShapeAttribs.Name.IsEmpty())
+
+  if (!anOldLabel.IsNull())
   {
-    TDataStd_Name::Set (aNewRefLabel, aShapeAttribs.Name);
+    // already defined in the document
+    return Standard_True;
   }
 
-  // store color
-  Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (myXdeDoc->Main());
-  if (aShapeAttribs.Style.IsSetColorSurf())
+  // put attributes to the Product (shared across Instances)
+  if (!hasProductName)
   {
-    aColorTool->SetColor (aNewRefLabel, aShapeAttribs.Style.GetColorSurfRGBA(), XCAFDoc_ColorSurf);
+    setShapeName (aNewRefLabel, aShapeType, aRefShapeAttribs.Name, theLabel, theParentName);
   }
-  if (aShapeAttribs.Style.IsSetColorCurv())
+  setShapeStyle (theTools, aNewRefLabel, aRefShapeAttribs.Style);
+  setShapeNamedData (theTools, aNewRefLabel, aRefShapeAttribs.NamedData);
+
+  if (theTools.ShapeTool->IsAssembly (aNewRefLabel))
   {
-    aColorTool->SetColor (aNewRefLabel, aShapeAttribs.Style.GetColorCurv(), XCAFDoc_ColorCurv);
+    // store sub-shapes (iterator is set to not inherit Location of parent object)
+    TCollection_AsciiString aDummyName;
+    for (TopoDS_Iterator aSubShapeIter (theShape, Standard_True, Standard_False); aSubShapeIter.More(); aSubShapeIter.Next())
+    {
+      addShapeIntoDoc (theTools, aSubShapeIter.Value(), aNewRefLabel, aDummyName);
+    }
   }
-  if (!aShapeAttribs.Style.Material().IsNull())
+  else
   {
-    Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (myXdeDoc->Main());
-    TDF_Label aMaterialLabel = aShapeAttribs.Style.Material()->Label();
-    if (aMaterialLabel.IsNull())
+    // store a plain list of sub-shapes in case if they have custom attributes (usually per-face color)
+    RWMesh_NodeAttributes aSubShapeAttribs;
+    for (TopoDS_Iterator aSubShapeIter (theShape, Standard_True, Standard_False); aSubShapeIter.More(); aSubShapeIter.Next())
     {
-      const TCollection_AsciiString aMatName = !aShapeAttribs.Style.Material()->RawName().IsNull()
-                                             ?  aShapeAttribs.Style.Material()->RawName()->String()
-                                             :  "";
-      aMaterialLabel = aMatTool->AddMaterial (aShapeAttribs.Style.Material(), aMatName);
+      const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
+      if (myAttribMap.Find (aSubShape.Located (TopLoc_Location()), aSubShapeAttribs))
+      {
+        addSubShapeIntoDoc (theTools, aSubShape, aNewRefLabel, aSubShapeAttribs);
+      }
     }
-    aMatTool->SetShapeMaterial (aNewRefLabel, aMaterialLabel);
+  }
+  return Standard_True;
+}
+
+// =======================================================================
+// function : addSubShapeIntoDoc
+// purpose  :
+// =======================================================================
+Standard_Boolean RWMesh_CafReader::addSubShapeIntoDoc (CafDocumentTools& theTools,
+                                                       const TopoDS_Shape& theShape,
+                                                       const TDF_Label& theParentLabel,
+                                                       const RWMesh_NodeAttributes& theAttribs)
+{
+  if (theShape.IsNull()
+   || myXdeDoc.IsNull())
+  {
+    return Standard_False;
   }
 
-  // store sub-shapes (iterator is set to ignore Location)
-  TCollection_AsciiString aDummyName;
+  const TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
+  TDF_Label aNewLabel = theTools.ShapeTool->AddSubShape (theParentLabel, theShape);
+  if (aNewLabel.IsNull())
+  {
+    return Standard_False;
+  }
+
+  {
+    Handle(XCAFDoc_ShapeMapTool) aShapeMapTool = XCAFDoc_ShapeMapTool::Set (aNewLabel);
+    aShapeMapTool->SetShape (theShape);
+  }
+
+  // if new label is a reference get referred shape
+  TDF_Label aNewRefLabel = aNewLabel;
+  theTools.ShapeTool->GetReferredShape (aNewLabel, aNewRefLabel);
+
+  // put attributes to the Product (shared across Instances)
+  static const TCollection_AsciiString anEmptyString;
+  setShapeName (aNewRefLabel, aShapeType, theAttribs.Name, TDF_Label(), anEmptyString);
+  setShapeStyle (theTools, aNewRefLabel, theAttribs.Style);
+  setShapeNamedData (theTools, aNewRefLabel, theAttribs.NamedData);
+
+  RWMesh_NodeAttributes aSubShapeAttribs;
   for (TopoDS_Iterator aSubShapeIter (theShape, Standard_True, Standard_False); aSubShapeIter.More(); aSubShapeIter.Next())
   {
-    addShapeIntoDoc (aSubShapeIter.Value(), aNewRefLabel, aDummyName);
+    const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
+    if (myAttribMap.Find (aSubShape.Located (TopLoc_Location()), aSubShapeAttribs))
+    {
+      addSubShapeIntoDoc (theTools, aSubShape, theParentLabel, aSubShapeAttribs);
+    }
   }
   return Standard_True;
 }
index 8658a21..1edc085 100644 (file)
@@ -24,6 +24,9 @@
 
 class Message_ProgressIndicator;
 class TDocStd_Document;
+class XCAFDoc_ShapeTool;
+class XCAFDoc_ColorTool;
+class XCAFDoc_VisMaterialTool;
 
 //! Extended status bits.
 enum RWMesh_CafReaderStatusEx
@@ -47,6 +50,17 @@ class RWMesh_CafReader : public Standard_Transient
   DEFINE_STANDARD_RTTIEXT(RWMesh_CafReader, Standard_Transient)
 public:
 
+  //! Structure holding tools for filling the document.
+  struct CafDocumentTools
+  {
+    Handle(XCAFDoc_ShapeTool)       ShapeTool;
+    Handle(XCAFDoc_ColorTool)       ColorTool;
+    Handle(XCAFDoc_VisMaterialTool) VisMaterialTool;
+    NCollection_DataMap<TopoDS_Shape, TDF_Label, TopTools_ShapeMapHasher> ComponentMap;
+  };
+
+public:
+
   //! Empty constructor.
   Standard_EXPORT RWMesh_CafReader();
 
@@ -189,10 +203,34 @@ protected:
   Standard_EXPORT void fillDocument();
 
   //! Append new shape into the document (recursively).
-  Standard_EXPORT Standard_Boolean addShapeIntoDoc (const TopoDS_Shape& theShape,
+  Standard_EXPORT Standard_Boolean addShapeIntoDoc (CafDocumentTools& theTools,
+                                                    const TopoDS_Shape& theShape,
                                                     const TDF_Label& theLabel,
                                                     const TCollection_AsciiString& theParentName);
 
+  //! Append new sub-shape into the document (recursively).
+  Standard_EXPORT Standard_Boolean addSubShapeIntoDoc (CafDocumentTools& theTools,
+                                                       const TopoDS_Shape& theShape,
+                                                       const TDF_Label& theParentLabel,
+                                                       const RWMesh_NodeAttributes& theAttribs);
+
+  //! Put name attribute onto the label.
+  Standard_EXPORT void setShapeName (const TDF_Label& theLabel,
+                                     const TopAbs_ShapeEnum theShapeType,
+                                     const TCollection_AsciiString& theName,
+                                     const TDF_Label& theParentLabel,
+                                     const TCollection_AsciiString& theParentName);
+
+  //! Put color and material attributes onto the label.
+  Standard_EXPORT void setShapeStyle (const CafDocumentTools& theTools,
+                                      const TDF_Label& theLabel,
+                                      const XCAFPrs_Style& theStyle);
+
+  //! Put name data (metadata) attribute onto the label.
+  Standard_EXPORT void setShapeNamedData (const CafDocumentTools& theTools,
+                                          const TDF_Label& theLabel,
+                                          const Handle(TDataStd_NamedData)& theNameData);
+
   //! Generate names for root labels starting from specified index.
   Standard_EXPORT void generateNames (const TCollection_AsciiString& theFile,
                                       const Standard_Integer theRootLower,
index adc7110..9bdc357 100644 (file)
 #include <TopTools_ShapeMapHasher.hxx>
 #include <XCAFPrs_Style.hxx>
 
+class TDataStd_NamedData;
+
 //! Attributes of the node.
 struct RWMesh_NodeAttributes
 {
-  TCollection_AsciiString Name;    //!< name for the user
-  TCollection_AsciiString RawName; //!< name within low-level format structure
-  XCAFPrs_Style           Style;   //!< presentation style
+  TCollection_AsciiString    Name;      //!< name for the user
+  TCollection_AsciiString    RawName;   //!< name within low-level format structure
+  Handle(TDataStd_NamedData) NamedData; //!< optional metadata
+  XCAFPrs_Style              Style;     //!< presentation style
 };
 typedef NCollection_DataMap<TopoDS_Shape, RWMesh_NodeAttributes, TopTools_ShapeMapHasher> RWMesh_NodeAttributeMap;
 
index 8f9f3ec..e4a26f6 100644 (file)
@@ -72,7 +72,6 @@ TDataStd_Name.cxx
 TDataStd_Name.hxx
 TDataStd_NamedData.cxx
 TDataStd_NamedData.hxx
-TDataStd_NamedData.lxx
 TDataStd_NoteBook.cxx
 TDataStd_NoteBook.hxx
 TDataStd_PtrTreeNode.hxx
index 1b8e92f..6a1de76 100644 (file)
@@ -13,9 +13,9 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <TDataStd_NamedData.hxx>
 
 #include <Standard_GUID.hxx>
-#include <Standard_Type.hxx>
 #include <TCollection_ExtendedString.hxx>
 #include <TColStd_DataMapIteratorOfDataMapOfStringInteger.hxx>
 #include <TDataStd_DataMapIteratorOfDataMapOfStringByte.hxx>
 #include <TDataStd_HDataMapOfStringInteger.hxx>
 #include <TDataStd_HDataMapOfStringReal.hxx>
 #include <TDataStd_HDataMapOfStringString.hxx>
-#include <TDataStd_NamedData.hxx>
-#include <TDF_Attribute.hxx>
+
 #include <TDF_Label.hxx>
 #include <TDF_RelocationTable.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(TDataStd_NamedData,TDF_Attribute)
 
-#ifdef _WIN32
-#define EXCEPTION ...
-#else
-#define EXCEPTION Standard_Failure
-#endif
 //=======================================================================
 //function : GetID
 //purpose  : 
@@ -75,6 +69,19 @@ Handle(TDataStd_NamedData) TDataStd_NamedData::Set(const TDF_Label& label)
   return A;
 }
 
+//=======================================================================
+//function : clear
+//purpose  :
+//=======================================================================
+void TDataStd_NamedData::clear()
+{
+  myIntegers.Nullify();
+  myReals.Nullify();
+  myStrings.Nullify();
+  myBytes.Nullify();
+  myArraysOfIntegers.Nullify();
+  myArraysOfReals.Nullify();
+}
 
 //Category: Integers
 
@@ -103,6 +110,21 @@ Standard_Integer TDataStd_NamedData::GetInteger(const TCollection_ExtendedString
 }
 
 //=======================================================================
+//function : setInteger
+//purpose  :
+//=======================================================================
+void TDataStd_NamedData::setInteger (const TCollection_ExtendedString& theName,
+                                     const Standard_Integer theInteger)
+{
+  if (!HasIntegers())
+  {
+    TColStd_DataMapOfStringInteger aMap;
+    myIntegers = new TDataStd_HDataMapOfStringInteger (aMap);
+  }
+  myIntegers->ChangeMap().Bind (theName, theInteger);
+}
+
+//=======================================================================
 //function : SetInteger
 //purpose  : Defines a named integer. If the integer already exists,
 //         : it changes its value to <theInteger>.
@@ -110,17 +132,23 @@ Standard_Integer TDataStd_NamedData::GetInteger(const TCollection_ExtendedString
 void TDataStd_NamedData::SetInteger(const TCollection_ExtendedString& theName,
                                    const Standard_Integer theInteger)
 {
-  if(!HasIntegers()) {
+  if (!HasIntegers())
+  {
     TColStd_DataMapOfStringInteger aMap;
     myIntegers = new TDataStd_HDataMapOfStringInteger(aMap);
   }
-  if (!myIntegers->Map().IsBound(theName) || myIntegers->Map().Find(theName) != theInteger)
+  if (Standard_Integer* aValuePtr = myIntegers->ChangeMap().ChangeSeek (theName))
+  {
+    if (*aValuePtr != theInteger)
+    {
+      Backup();
+      *aValuePtr = theInteger;
+    }
+  }
+  else
   {
     Backup();
-    if (myIntegers->Map().IsBound(theName))
-      myIntegers->ChangeMap().ChangeFind(theName) = theInteger;
-    else
-      myIntegers->ChangeMap().Bind(theName, theInteger);
+    myIntegers->ChangeMap().Bind (theName, theInteger);
   }
 }
 
@@ -182,6 +210,21 @@ Standard_Real TDataStd_NamedData::GetReal(const TCollection_ExtendedString& theN
 }
 
 //=======================================================================
+//function : setReal
+//purpose  :
+//=======================================================================
+void TDataStd_NamedData::setReal (const TCollection_ExtendedString& theName,
+                                  const Standard_Real theReal)
+{
+  if (!HasReals())
+  {
+    TDataStd_DataMapOfStringReal aMap;
+    myReals = new TDataStd_HDataMapOfStringReal (aMap);
+  }
+  myReals->ChangeMap().Bind (theName, theReal);
+}
+
+//=======================================================================
 //function : SetReal
 //purpose  : Defines a named real. If the real already exists, 
 //         : it changes its value to <theReal>.
@@ -189,17 +232,22 @@ Standard_Real TDataStd_NamedData::GetReal(const TCollection_ExtendedString& theN
 void TDataStd_NamedData::SetReal(const TCollection_ExtendedString& theName,
                                 const Standard_Real theReal)
 {
-  if(!HasReals()) {
+  if (!HasReals())
+  {
     TDataStd_DataMapOfStringReal aMap;
     myReals = new TDataStd_HDataMapOfStringReal(aMap);
- }
-  if (!myReals->Map().IsBound(theName) || myReals->Map().Find(theName) != theReal)
+  }
+  if (Standard_Real* aValuePtr = myReals->ChangeMap().ChangeSeek (theName))
   {
-    Backup();
-    if (myReals->Map().IsBound(theName))
-      myReals->ChangeMap().ChangeFind(theName) = theReal;
-    else
-      myReals->ChangeMap().Bind(theName, theReal);
+    if (*aValuePtr != theReal)
+    {
+      Backup();
+      *aValuePtr = theReal;
+    }
+  }
+  else
+  {
+    myReals->ChangeMap().Bind (theName, theReal);
   }
 }
 
@@ -260,23 +308,46 @@ const TCollection_ExtendedString& TDataStd_NamedData::GetString(const TCollectio
 
 //=======================================================================
 //function : SetString
+//purpose  :
+//=======================================================================
+void TDataStd_NamedData::setString (const TCollection_ExtendedString& theName,
+                                    const TCollection_ExtendedString& theString)
+{
+  if (!HasStrings())
+  {
+    TDataStd_DataMapOfStringString aMap;
+    myStrings = new TDataStd_HDataMapOfStringString (aMap);
+  }
+
+  myStrings->ChangeMap().Bind (theName, theString);
+}
+
+//=======================================================================
+//function : SetString
 //purpose  : Defines a named string. If the string already exists,
 //         : it changes its value to <theString>.
 //=======================================================================
 void TDataStd_NamedData::SetString(const TCollection_ExtendedString& theName,
                                   const TCollection_ExtendedString& theString)
 {
-  if(!HasStrings()) {
+  if (!HasStrings())
+  {
     TDataStd_DataMapOfStringString aMap;
     myStrings = new TDataStd_HDataMapOfStringString(aMap);
   }
-  if (!myStrings->Map().IsBound(theName) || myStrings->Map().Find(theName) != theString)
+
+  if (TCollection_ExtendedString* aValuePtr = myStrings->ChangeMap().ChangeSeek (theName))
+  {
+    if (*aValuePtr != theString)
+    {
+      Backup();
+      *aValuePtr = theString;
+    }
+  }
+  else
   {
     Backup();
-    if (myStrings->Map().IsBound(theName))
-      myStrings->ChangeMap().ChangeFind(theName) = theString;
-    else
-      myStrings->ChangeMap().Bind(theName, theString);
+    myStrings->ChangeMap().Bind(theName, theString);
   }
 }
 
@@ -336,6 +407,21 @@ Standard_Byte TDataStd_NamedData::GetByte(const TCollection_ExtendedString& theN
 }
 
 //=======================================================================
+//function : setByte
+//purpose  :
+//=======================================================================
+void TDataStd_NamedData::setByte (const TCollection_ExtendedString& theName,
+                                  const Standard_Byte theByte)
+{
+  if (!HasBytes())
+  {
+    TDataStd_DataMapOfStringByte aMap;
+    myBytes = new TDataStd_HDataMapOfStringByte (aMap);
+  }
+  myBytes->ChangeMap().Bind (theName, theByte);
+}
+
+//=======================================================================
 //function : SetByte
 //purpose  : Defines a named byte. If the byte already exists,
 //         : it changes its value to <theByte>.
@@ -343,17 +429,24 @@ Standard_Byte TDataStd_NamedData::GetByte(const TCollection_ExtendedString& theN
 void TDataStd_NamedData::SetByte(const TCollection_ExtendedString& theName,
                                 const Standard_Byte theByte)
 {
-  if(!HasBytes()) {
+  if (!HasBytes())
+  {
     TDataStd_DataMapOfStringByte aMap;
-    myBytes = new TDataStd_HDataMapOfStringByte(aMap);
+    myBytes = new TDataStd_HDataMapOfStringByte (aMap);
   }
-  if (!myBytes->Map().IsBound(theName) || myBytes->Map().Find(theName) != theByte)
+
+  if (Standard_Byte* aValuePtr = myBytes->ChangeMap().ChangeSeek (theName))
+  {
+    if (*aValuePtr != theByte)
+    {
+      Backup();
+      *aValuePtr = theByte;
+    }
+  }
+  else
   {
     Backup();
-    if (myBytes->Map().IsBound(theName))
-      myBytes->ChangeMap().ChangeFind(theName) = theByte;
-    else
-      myBytes->ChangeMap().Bind(theName, theByte);
+    myBytes->ChangeMap().Bind (theName, theByte);
   }
 }
 
@@ -416,35 +509,30 @@ const Handle(TColStd_HArray1OfInteger)& TDataStd_NamedData::GetArrayOfIntegers
 }
 
 //=======================================================================
-//function : SetArrayOfIntegers
-//purpose  : Defines a named array of integer values.
-//         : If the array already exists, it changes its value to <theArrayOfIntegers>.
+//function : setArrayOfIntegers
+//purpose  :
 //=======================================================================
-void TDataStd_NamedData::SetArrayOfIntegers(const TCollection_ExtendedString& theName,
-                                           const Handle(TColStd_HArray1OfInteger)& theArrayOfIntegers)
+void TDataStd_NamedData::setArrayOfIntegers (const TCollection_ExtendedString& theName,
+                                             const Handle(TColStd_HArray1OfInteger)& theArrayOfIntegers)
 {
-  if(!HasArraysOfIntegers()) {
+  if (!HasArraysOfIntegers())
+  {
     TDataStd_DataMapOfStringHArray1OfInteger aMap;
-    myArraysOfIntegers = new TDataStd_HDataMapOfStringHArray1OfInteger(aMap);
+    myArraysOfIntegers = new TDataStd_HDataMapOfStringHArray1OfInteger (aMap);
   }
 
-  Backup();
-  // Deep copy of the array
-  Handle(TColStd_HArray1OfInteger) arr;
+  Handle(TColStd_HArray1OfInteger) anArray;
   if (!theArrayOfIntegers.IsNull())
   {
-    Standard_Integer lower = theArrayOfIntegers->Lower(), i = lower, upper = theArrayOfIntegers->Upper();
-    arr = new TColStd_HArray1OfInteger(lower, upper);
-    for (; i <= upper; i++)
+    // deep copy of the array
+    const Standard_Integer aLower = theArrayOfIntegers->Lower(), anUpper = theArrayOfIntegers->Upper();
+    anArray = new TColStd_HArray1OfInteger (aLower, anUpper);
+    for (Standard_Integer anIter = aLower; anIter <= anUpper; ++anIter)
     {
-      arr->SetValue(i, theArrayOfIntegers->Value(i));
+      anArray->SetValue (anIter, theArrayOfIntegers->Value (anIter));
     }
   }
-
-  if (myArraysOfIntegers->Map().IsBound(theName))
-    myArraysOfIntegers->ChangeMap().ChangeFind(theName) = arr;
-  else
-    myArraysOfIntegers->ChangeMap().Bind(theName, arr);
+  myArraysOfIntegers->ChangeMap().Bind (theName, anArray);
 }
 
 //=======================================================================
@@ -508,35 +596,30 @@ const Handle(TColStd_HArray1OfReal)& TDataStd_NamedData::GetArrayOfReals
 }
 
 //=======================================================================
-//function : SetArrayOfReals
-//purpose  : Defines a named array of real values.
-//         : If the array already exists, it changes its value to <theArrayOfReals>.
+//function : setArrayOfReals
+//purpose  :
 //=======================================================================
-void TDataStd_NamedData::SetArrayOfReals(const TCollection_ExtendedString& theName,
-                                        const Handle(TColStd_HArray1OfReal)& theArrayOfReals)
+void TDataStd_NamedData::setArrayOfReals (const TCollection_ExtendedString& theName,
+                                          const Handle(TColStd_HArray1OfReal)& theArrayOfReals)
 {
-  if(!HasArraysOfReals()) {
+  if (!HasArraysOfReals())
+  {
     TDataStd_DataMapOfStringHArray1OfReal aMap;
-    myArraysOfReals = new TDataStd_HDataMapOfStringHArray1OfReal(aMap);
+    myArraysOfReals = new TDataStd_HDataMapOfStringHArray1OfReal (aMap);
   }
-  Backup();
 
-  // Deep copy of the array
-  Handle(TColStd_HArray1OfReal) arr;
+  Handle(TColStd_HArray1OfReal) anArray;
   if (!theArrayOfReals.IsNull())
   {
-    Standard_Integer lower = theArrayOfReals->Lower(), i = lower, upper = theArrayOfReals->Upper();
-    arr = new TColStd_HArray1OfReal(lower, upper);
-    for (; i <= upper; i++)
+    // deep copy of the array
+    const Standard_Integer aLower = theArrayOfReals->Lower(), anUpper = theArrayOfReals->Upper();
+    anArray = new TColStd_HArray1OfReal (aLower, anUpper);
+    for (Standard_Integer anIter = aLower; anIter <= anUpper; ++anIter)
     {
-      arr->SetValue(i, theArrayOfReals->Value(i));
+      anArray->SetValue (anIter, theArrayOfReals->Value (anIter));
     }
   }
-
-  if (myArraysOfReals->Map().IsBound(theName))
-    myArraysOfReals->ChangeMap().ChangeFind(theName) = arr;
-  else
-    myArraysOfReals->ChangeMap().Bind(theName, arr);
+  myArraysOfReals->ChangeMap().Bind (theName, anArray);
 }
 
 //=======================================================================
index 2cd8ae8..eb677c0 100644 (file)
 #ifndef _TDataStd_NamedData_HeaderFile
 #define _TDataStd_NamedData_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-
 #include <TDF_Attribute.hxx>
-#include <Standard_Boolean.hxx>
-#include <Standard_Integer.hxx>
 #include <TColStd_DataMapOfStringInteger.hxx>
-#include <Standard_Real.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
+#include <TColStd_HArray1OfReal.hxx>
 #include <TDataStd_DataMapOfStringReal.hxx>
 #include <TDataStd_DataMapOfStringString.hxx>
-#include <Standard_Byte.hxx>
 #include <TDataStd_DataMapOfStringByte.hxx>
-#include <TColStd_HArray1OfInteger.hxx>
 #include <TDataStd_DataMapOfStringHArray1OfInteger.hxx>
-#include <TColStd_HArray1OfReal.hxx>
 #include <TDataStd_DataMapOfStringHArray1OfReal.hxx>
-#include <Standard_OStream.hxx>
+
 class TDataStd_HDataMapOfStringInteger;
 class TDataStd_HDataMapOfStringReal;
 class TDataStd_HDataMapOfStringString;
 class TDataStd_HDataMapOfStringByte;
 class TDataStd_HDataMapOfStringHArray1OfInteger;
 class TDataStd_HDataMapOfStringHArray1OfReal;
-class Standard_GUID;
-class TDF_Label;
 class TCollection_ExtendedString;
-class TDF_Attribute;
-class TDF_RelocationTable;
-
 
 class TDataStd_NamedData;
 DEFINE_STANDARD_HANDLE(TDataStd_NamedData, TDF_Attribute)
@@ -52,24 +40,22 @@ DEFINE_STANDARD_HANDLE(TDataStd_NamedData, TDF_Attribute)
 //! Contains a named data.
 class TDataStd_NamedData : public TDF_Attribute
 {
-
 public:
 
-  
-  //! Static methods
-  //! ==============
   //! Returns the ID of the named data attribute.
   Standard_EXPORT static const Standard_GUID& GetID();
   
   //! Finds or creates a named data attribute.
   Standard_EXPORT static Handle(TDataStd_NamedData) Set (const TDF_Label& label);
-  
+
+public:
+
+  //! Empty constructor.
   Standard_EXPORT TDataStd_NamedData();
   
-  //! Returns true if at least one named integer value is
-  //! kept in the attribute.
-    Standard_Boolean HasIntegers() const;
-  
+  //! Returns true if at least one named integer value is kept in the attribute.
+  Standard_Boolean HasIntegers() const { return !myIntegers.IsNull(); }
+
   //! Returns true if the attribute contains specified by Name
   //! integer value.
   Standard_EXPORT Standard_Boolean HasInteger (const TCollection_ExtendedString& theName) const;
@@ -88,11 +74,10 @@ public:
   
   //! Replace the container content by new content of the <theIntegers>.
   Standard_EXPORT void ChangeIntegers (const TColStd_DataMapOfStringInteger& theIntegers);
-  
-  //! Returns true if at least one named real value is
-  //! kept in the attribute.
-    Standard_Boolean HasReals() const;
-  
+
+  //! Returns true if at least one named real value is kept in the attribute.
+  Standard_Boolean HasReals() const { return !myReals.IsNull(); }
+
   //! Returns true if the attribute contains a real specified by Name.
   Standard_EXPORT Standard_Boolean HasReal (const TCollection_ExtendedString& theName) const;
   
@@ -112,8 +97,8 @@ public:
   Standard_EXPORT void ChangeReals (const TDataStd_DataMapOfStringReal& theReals);
   
   //! Returns true if there are some named strings in the attribute.
-    Standard_Boolean HasStrings() const;
-  
+  Standard_Boolean HasStrings() const { return !myStrings.IsNull(); }
+
   //! Returns true if the attribute contains this named string.
   Standard_EXPORT Standard_Boolean HasString (const TCollection_ExtendedString& theName) const;
   
@@ -133,8 +118,8 @@ public:
   Standard_EXPORT void ChangeStrings (const TDataStd_DataMapOfStringString& theStrings);
   
   //! Returns true if there are some named bytes in the attribute.
-    Standard_Boolean HasBytes() const;
-  
+  Standard_Boolean HasBytes() const { return !myBytes.IsNull(); }
+
   //! Returns true if the attribute contains this named byte.
   Standard_EXPORT Standard_Boolean HasByte (const TCollection_ExtendedString& theName) const;
   
@@ -154,8 +139,8 @@ public:
   Standard_EXPORT void ChangeBytes (const TDataStd_DataMapOfStringByte& theBytes);
   
   //! Returns true if there are some named arrays of integer values in the attribute.
-    Standard_Boolean HasArraysOfIntegers() const;
-  
+  Standard_Boolean HasArraysOfIntegers() const { return !myArraysOfIntegers.IsNull(); }
+
   //! Returns true if the attribute contains this named array of integer values.
   Standard_EXPORT Standard_Boolean HasArrayOfIntegers (const TCollection_ExtendedString& theName) const;
   
@@ -163,11 +148,17 @@ public:
   //! It returns a NULL Handle if there is no such a named array of integers
   //! (use HasArrayOfIntegers()).
   Standard_EXPORT const Handle(TColStd_HArray1OfInteger)& GetArrayOfIntegers (const TCollection_ExtendedString& theName);
-  
+
   //! Defines a named array of integer values.
-  //! If the array already exists, it changes its value to <theArrayOfIntegers>.
-  Standard_EXPORT void SetArrayOfIntegers (const TCollection_ExtendedString& theName, const Handle(TColStd_HArray1OfInteger)& theArrayOfIntegers);
-  
+  //! @param theName [in] key
+  //! @param theArrayOfIntegers [in] new value, overrides existing (passed array will be copied by value!)
+  void SetArrayOfIntegers (const TCollection_ExtendedString& theName,
+                           const Handle(TColStd_HArray1OfInteger)& theArrayOfIntegers)
+  {
+    Backup();
+    setArrayOfIntegers (theName, theArrayOfIntegers);
+  }
+
   //! Returns the internal container of named arrays of integer values.
   Standard_EXPORT const TDataStd_DataMapOfStringHArray1OfInteger& GetArraysOfIntegersContainer();
   
@@ -175,8 +166,8 @@ public:
   Standard_EXPORT void ChangeArraysOfIntegers (const TDataStd_DataMapOfStringHArray1OfInteger& theArraysOfIntegers);
   
   //! Returns true if there are some named arrays of real values in the attribute.
-    Standard_Boolean HasArraysOfReals() const;
-  
+  Standard_Boolean HasArraysOfReals() const { return !myArraysOfReals.IsNull(); }
+
   //! Returns true if the attribute contains this named array of real values.
   Standard_EXPORT Standard_Boolean HasArrayOfReals (const TCollection_ExtendedString& theName) const;
   
@@ -184,55 +175,126 @@ public:
   //! It returns a NULL Handle if there is no such a named array of reals
   //! (use HasArrayOfReals()).
   Standard_EXPORT const Handle(TColStd_HArray1OfReal)& GetArrayOfReals (const TCollection_ExtendedString& theName);
-  
+
   //! Defines a named array of real values.
-  //! If the array already exists, it changes its value to <theArrayOfReals>.
-  Standard_EXPORT void SetArrayOfReals (const TCollection_ExtendedString& theName, const Handle(TColStd_HArray1OfReal)& theArrayOfReals);
-  
+  //! @param theName [in] key
+  //! @param theArrayOfIntegers [in] new value, overrides existing (passed array will be copied by value!)
+  void SetArrayOfReals (const TCollection_ExtendedString& theName,
+                        const Handle(TColStd_HArray1OfReal)& theArrayOfReals)
+  {
+    Backup();
+    setArrayOfReals (theName, theArrayOfReals);
+  }
+
   //! Returns the internal container of named arrays of real values.
   Standard_EXPORT const TDataStd_DataMapOfStringHArray1OfReal& GetArraysOfRealsContainer();
   
   //! Replace the container content by new content of the <theArraysOfReals>.
   Standard_EXPORT void ChangeArraysOfReals (const TDataStd_DataMapOfStringHArray1OfReal& theArraysOfReals);
-  
-  Standard_EXPORT const Standard_GUID& ID() const Standard_OVERRIDE;
-  
-  Standard_EXPORT void Restore (const Handle(TDF_Attribute)& With) Standard_OVERRIDE;
-  
-  Standard_EXPORT Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE;
-  
-  Standard_EXPORT void Paste (const Handle(TDF_Attribute)& Into, const Handle(TDF_RelocationTable)& RT) const Standard_OVERRIDE;
-  
-  Standard_EXPORT virtual Standard_OStream& Dump (Standard_OStream& anOS) const Standard_OVERRIDE;
 
+  //! Clear data.
+  void Clear()
+  {
+    Backup();
+    clear();
+  }
 
+public: //! @name late-load deferred data interface
 
+  //! Returns TRUE if some data is not loaded from deferred storage and can be loaded using LoadDeferredData().
+  //!
+  //! Late-load interface allows to avoid loading auxiliary data into memory until it is needed by application
+  //! and also speed up reader by skipping data chunks in file.
+  //! This feature requires file format having special structure, and usually implies read-only access,
+  //! therefore default implementation will return FALSE here.
+  //!
+  //! Late-load elements require special attention to ensure data consistency,
+  //! as such elements are created in undefined state (no data) and Undo/Redo mechanism will not work until deferred data being loaded.
+  //!
+  //! Usage scenarios:
+  //! - Application displays model in read-only way.
+  //!   Late-load elements are loaded temporarily on demand and immediatly unloaded.
+  //!     theNamedData->LoadDeferredData (true);
+  //!     TCollection_AsciiString aValue = theNamedData->GetString (theKey);
+  //!     theNamedData->UnloadDeferredData();
+  //! - Application saves the model into another format.
+  //!   All late-load elements should be loaded (at least temporary during operation).
+  //! - Application modifies the model.
+  //!   Late-load element should be loaded with removed link to deferred storage,
+  //!   so that Undo()/Redo() will work as expected since loading.
+  //!     theNamedData->LoadDeferredData (false);
+  //!     theNamedData->SetString (theKey, theNewValue);
+  virtual Standard_Boolean HasDeferredData() const { return false; }
 
-  DEFINE_STANDARD_RTTIEXT(TDataStd_NamedData,TDF_Attribute)
+  //! Load data from deferred storage, without calling Backup().
+  //! As result, the content of the object will be overidden by data from deferred storage (which is normally read-only).
+  //! @param theToKeepDeferred [in] when TRUE, the link to deferred storage will be preserved
+  //!                               so that it will be possible calling UnloadDeferredData() afterwards for releasing memory
+  //! @return FALSE if deferred storage is unavailable or deferred data has been already loaded
+  virtual Standard_Boolean LoadDeferredData (Standard_Boolean theToKeepDeferred = false)
+  {
+    (void )theToKeepDeferred;
+    return false;
+  }
 
-protected:
+  //! Releases data if object has connected deferred storage, without calling Backup().
+  //! WARNING! This operation does not unload modifications to deferred storage (normally it is read-only),
+  //! so that modifications will be discarded (if any).
+  //! @return FALSE if object has no deferred data
+  virtual Standard_Boolean UnloadDeferredData() { return false; }
 
+public:
 
+  //! Clear data without calling Backup().
+  Standard_EXPORT void clear();
 
+  //! Defines a named integer (without calling Backup).
+  Standard_EXPORT void setInteger (const TCollection_ExtendedString& theName,
+                                   const Standard_Integer theInteger);
 
-private:
+  //! Defines a named real (without calling Backup).
+  Standard_EXPORT void setReal (const TCollection_ExtendedString& theName,
+                                const Standard_Real theReal);
 
+  //! Defines a named string (without calling Backup).
+  Standard_EXPORT void setString (const TCollection_ExtendedString& theName,
+                                  const TCollection_ExtendedString& theString);
 
-  Handle(TDataStd_HDataMapOfStringInteger) myIntegers;
-  Handle(TDataStd_HDataMapOfStringReal) myReals;
-  Handle(TDataStd_HDataMapOfStringString) myStrings;
-  Handle(TDataStd_HDataMapOfStringByte) myBytes;
-  Handle(TDataStd_HDataMapOfStringHArray1OfInteger) myArraysOfIntegers;
-  Handle(TDataStd_HDataMapOfStringHArray1OfReal) myArraysOfReals;
+  //! Defines a named byte (without calling Backup).
+  Standard_EXPORT void setByte (const TCollection_ExtendedString& theName,
+                                const Standard_Byte theByte);
 
+  //! Defines a named array of integer values (without calling Backup).
+  Standard_EXPORT void setArrayOfIntegers (const TCollection_ExtendedString& theName,
+                                           const Handle(TColStd_HArray1OfInteger)& theArrayOfIntegers);
 
-};
+  //! Defines a named array of real values (without calling Backup).
+  Standard_EXPORT void setArrayOfReals (const TCollection_ExtendedString& theName,
+                                        const Handle(TColStd_HArray1OfReal)& theArrayOfReals);
+
+public: //! @name TDF_Attribute interface
+
+  Standard_EXPORT virtual const Standard_GUID& ID() const Standard_OVERRIDE;
 
+  Standard_EXPORT virtual void Restore (const Handle(TDF_Attribute)& With) Standard_OVERRIDE;
 
-#include <TDataStd_NamedData.lxx>
+  Standard_EXPORT virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE;
 
+  Standard_EXPORT virtual void Paste (const Handle(TDF_Attribute)& Into, const Handle(TDF_RelocationTable)& RT) const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual Standard_OStream& Dump (Standard_OStream& anOS) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT(TDataStd_NamedData,TDF_Attribute)
 
+protected:
 
+  Handle(TDataStd_HDataMapOfStringInteger) myIntegers;
+  Handle(TDataStd_HDataMapOfStringReal) myReals;
+  Handle(TDataStd_HDataMapOfStringString) myStrings;
+  Handle(TDataStd_HDataMapOfStringByte) myBytes;
+  Handle(TDataStd_HDataMapOfStringHArray1OfInteger) myArraysOfIntegers;
+  Handle(TDataStd_HDataMapOfStringHArray1OfReal) myArraysOfReals;
 
+};
 
 #endif // _TDataStd_NamedData_HeaderFile
diff --git a/src/TDataStd/TDataStd_NamedData.lxx b/src/TDataStd/TDataStd_NamedData.lxx
deleted file mode 100644 (file)
index e4ec80b..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-// Created on: 2007-08-20
-// Created by: Sergey ZARITCHNY
-// Copyright (c) 2007-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//=======================================================================
-//function : HasIntegers
-//purpose  : Returns true if there are some named integers in the attribute.
-//=======================================================================
-
-inline Standard_Boolean TDataStd_NamedData::HasIntegers() const
-{
-  return !myIntegers.IsNull();
-}
-
-//=======================================================================
-//function : HasReals
-//purpose  : Returns true if there are some named reals in the attribute.
-//=======================================================================
-inline Standard_Boolean TDataStd_NamedData::HasReals() const
-{
-  return !myReals.IsNull();
-}
-
-//=======================================================================
-//function : HasStrings
-//purpose  : Returns true if there are some named strings in the attribute.
-//=======================================================================
-inline Standard_Boolean TDataStd_NamedData::HasStrings() const
-{
-  return !myStrings.IsNull();
-}
-
-//=======================================================================
-//function : HasBytes
-//purpose  : Returns true if there are some named bytes in the attribute.
-//=======================================================================
-inline Standard_Boolean TDataStd_NamedData::HasBytes() const
-{
-  return !myBytes.IsNull();
-}
-
-//=======================================================================
-//function : HasArraysOfIntegers
-//purpose  : Returns true if there are at least one array of integer 
-//         : values in the internal container of the attribute.
-//=======================================================================
-inline Standard_Boolean TDataStd_NamedData::HasArraysOfIntegers() const
-{
-  return !myArraysOfIntegers.IsNull();
-}
-//=======================================================================
-//function : HasArraysOfReals
-//purpose  : Returns true if there are some named arrays of real values 
-//         : in the attribute.
-//=======================================================================
-inline Standard_Boolean TDataStd_NamedData::HasArraysOfReals() const
-{
-  return !myArraysOfReals.IsNull();
-}
-
index 9542105..b68dcbf 100644 (file)
@@ -958,6 +958,7 @@ static Standard_Integer XGetProperties(Draw_Interpretor& di, Standard_Integer ar
     return 0;
   }
 
+  aNamedData->LoadDeferredData();
   if (aNamedData->HasIntegers())
   {
     TColStd_DataMapOfStringInteger anIntProperties = aNamedData->GetIntegersContainer();
index 6b83774..efe756a 100644 (file)
@@ -649,6 +649,7 @@ void XmlMDataStd_NamedDataDriver::Paste(const Handle(TDF_Attribute)& theSource,
   Standard_Integer i=0, up;
   XmlObjMgt_Element& anElement = theTarget;
   XmlObjMgt_Document aDoc (anElement.getOwnerDocument());
+  S->LoadDeferredData();
   if(S->HasIntegers() && !S->GetIntegersContainer().IsEmpty()) {
     // store a set of elements with string in each of them
     up = S->GetIntegersContainer().Extent();