0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / BinMNaming / BinMNaming_NamedShapeDriver.cxx
index b0eb742..a694a83 100644 (file)
 #include <BinObjMgt_Persistent.hxx>
 #include <BinTools_LocationSet.hxx>
 #include <BinTools_ShapeSet.hxx>
-#include <CDM_MessageDriver.hxx>
+#include <BinTools_ShapeWriter.hxx>
+#include <BinTools_ShapeReader.hxx>
+#include <Message_Messenger.hxx>
 #include <Standard_DomainError.hxx>
 #include <Standard_Type.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TDF_Attribute.hxx>
 #include <TDF_Label.hxx>
+#include <TDocStd_FormatVersion.hxx>
 #include <TNaming_Builder.hxx>
-#include <TNaming_Evolution.hxx>
 #include <TNaming_Iterator.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TopAbs_Orientation.hxx>
 #include <TopoDS_Shape.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(BinMNaming_NamedShapeDriver,BinMDF_ADriver)
+
 #define SHAPESET "SHAPE_SECTION"
-#define FORMAT_NUMBER 3
 //=======================================================================
-static Standard_Character EvolutionToChar(const TNaming_Evolution theEvol)
+static Standard_Character EvolutionToChar (const TNaming_Evolution theEvol)
 {
   switch(theEvol) {
     case TNaming_PRIMITIVE    : return 'P';
@@ -44,13 +47,12 @@ static Standard_Character EvolutionToChar(const TNaming_Evolution theEvol)
     case TNaming_SELECTED     : return 'S';
     case TNaming_REPLACE      : return 'M'; // for compatibility case TNaming_REPLACE      : return 'R';
   default:
-    Standard_DomainError::Raise("TNaming_Evolution:: Evolution Unknown");
+    throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
   }
-  return 'P'; // To avoid compilation error message.
 }
 
 //=======================================================================
-static TNaming_Evolution EvolutionToEnum(const Standard_Character theEvol)
+static TNaming_Evolution EvolutionToEnum (const Standard_Character theEvol)
 {
   switch(theEvol) {
     case 'P': return TNaming_PRIMITIVE;
@@ -60,12 +62,11 @@ static TNaming_Evolution EvolutionToEnum(const Standard_Character theEvol)
     case 'S': return TNaming_SELECTED;
     case 'R': return TNaming_MODIFY; //for compatibility //TNaming_REPLACE;
   default:
-    Standard_DomainError::Raise("TNaming_Evolution:: Evolution Unknown");
+    throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
   }
-  return TNaming_PRIMITIVE; // To avoid compilation error message.
 }
 //=======================================================================
-static Standard_Character OrientationToChar(const TopAbs_Orientation theOrient)
+static Standard_Character OrientationToChar (const TopAbs_Orientation theOrient)
 {
   switch(theOrient) {
     case TopAbs_FORWARD    : return 'F';
@@ -73,12 +74,11 @@ static Standard_Character OrientationToChar(const TopAbs_Orientation theOrient)
     case TopAbs_INTERNAL   : return 'I';
     case TopAbs_EXTERNAL   : return 'E';
   default:
-    Standard_DomainError::Raise("TopAbs_Orientation:: Orientation Unknown");
+    throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown");
   }
-  return 'F'; // To avoid compilation error message.
 }
 //=======================================================================
-static TopAbs_Orientation CharToOrientation(const Standard_Character  theCharOrient)
+static TopAbs_Orientation CharToOrientation (const Standard_Character  theCharOrient)
 {
   switch(theCharOrient) {
     case 'F':  return TopAbs_FORWARD;
@@ -86,53 +86,52 @@ static TopAbs_Orientation CharToOrientation(const Standard_Character  theCharOri
     case 'I':  return TopAbs_INTERNAL;
     case 'E':  return TopAbs_EXTERNAL;
   default:
-    Standard_DomainError::Raise("TopAbs_Orientation:: Orientation Unknown");
+    throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown");
   }
-  return TopAbs_FORWARD; // To avoid compilation error message.
 }
 
 //=======================================================================
 static void TranslateTo (const TopoDS_Shape&            theShape,
                          BinObjMgt_Persistent&          theResult,
-                         BinTools_ShapeSet&            theShapeSet)
+                         BinTools_ShapeSet            theShapeSet)
 {
   // Check for empty shape
   if (theShape.IsNull()) {
-    theResult.PutInteger(-1);
-    theResult.PutInteger(-1);
-    theResult.PutInteger(-1);
+    theResult.PutInteger (-1);
+    theResult.PutInteger (-1);
+    theResult.PutInteger (-1);
     return;
   }
   // Add to shape set both TShape and Location contained in <theShape>
-  const Standard_Integer aTShapeID = theShapeSet.Add (theShape);
+  const Standard_Integer aTShapeID = theShapeSet->Add (theShape);
   const Standard_Integer aLocID =
-    theShapeSet.Locations().Index (theShape.Location());
+    theShapeSet->Locations().Index (theShape.Location());
 
   // Fill theResult with shape parameters: TShape ID, Location, Orientation
   theResult << aTShapeID;
   theResult << aLocID;
-  theResult << OrientationToChar(theShape.Orientation());
+  theResult << OrientationToChar (theShape.Orientation());
 }
 //=======================================================================
 static int TranslateFrom  (const BinObjMgt_Persistent&  theSource,
                          TopoDS_Shape&                  theResult,
-                         BinTools_ShapeSet&            theShapeSet)
+                         BinTools_ShapeSet*            theShapeSet)
 {
   Standard_Integer aShapeID, aLocID;
   Standard_Character aCharOrient;
   Standard_Boolean Ok = theSource >> aShapeID; //TShapeID;
   if(!Ok) return 1;
   // Read TShape and Orientation
-  if (aShapeID <= 0 || aShapeID > theShapeSet.NbShapes())
+  if (aShapeID <= 0 || aShapeID > theShapeSet->NbShapes())
     return 1;
   Ok = theSource >> aLocID;
   if(!Ok) return 1;
   Ok = theSource >> aCharOrient;
   if(!Ok) return 1;
-  TopAbs_Orientation anOrient = CharToOrientation(aCharOrient);
+  TopAbs_Orientation anOrient = CharToOrientation (aCharOrient);
 
-  theResult.TShape      (theShapeSet.Shape(aShapeID).TShape());//TShape
-  theResult.Location    (theShapeSet.Locations().Location (aLocID)); //Location
+  theResult.TShape      (theShapeSet->Shape (aShapeID).TShape());//TShape
+  theResult.Location    (theShapeSet->Locations().Location (aLocID), Standard_False); //Location
   theResult.Orientation (anOrient);//Orientation
   return 0;
 }
@@ -143,8 +142,12 @@ static int TranslateFrom  (const BinObjMgt_Persistent&  theSource,
 //=======================================================================
 
 BinMNaming_NamedShapeDriver::BinMNaming_NamedShapeDriver
-                        (const Handle(CDM_MessageDriver)& theMsgDriver)
-     : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()), myShapeSet(Standard_False),myFormatNb(FORMAT_NUMBER)
+                        (const Handle(Message_Messenger)& theMsgDriver)
+     : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()),
+       myShapeSet (NULL),
+       myWithTriangles (Standard_False),
+       myWithNormals  (Standard_False),
+       myIsQuickPart (Standard_False)
 {
 }
 
@@ -168,12 +171,11 @@ Standard_Boolean BinMNaming_NamedShapeDriver::Paste
                                  const Handle(TDF_Attribute)& theTarget,
                                  BinObjMgt_RRelocationTable&  ) const
 {
-  Handle(TNaming_NamedShape) aTAtt= Handle(TNaming_NamedShape)::DownCast(theTarget);
+  Handle(TNaming_NamedShape) aTAtt= Handle(TNaming_NamedShape)::DownCast (theTarget);
   Standard_Integer aNbShapes;
   theSource >> aNbShapes;
   TDF_Label aLabel = theTarget->Label ();
-  TNaming_Builder   aBuilder   (aLabel);
-  if (aNbShapes == 0) return Standard_False;
+  TNaming_Builder aBuilder (aLabel);
   Standard_Integer aVer;
   Standard_Boolean ok = theSource >> aVer;
   if(!ok) return Standard_False;
@@ -181,44 +183,67 @@ Standard_Boolean BinMNaming_NamedShapeDriver::Paste
   Standard_Character aCharEvol;
   ok = theSource >> aCharEvol;
   if(!ok) return Standard_False;
-  TNaming_Evolution anEvol  = EvolutionToEnum(aCharEvol); //Evolution
-  aTAtt->SetVersion(anEvol);
+  TNaming_Evolution anEvol  = EvolutionToEnum (aCharEvol); //Evolution
+  aTAtt->SetVersion (anEvol);
 
-  BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
+  BinTools_ShapeSetBase* aShapeSet = const_cast<BinMNaming_NamedShapeDriver*>(this)->ShapeSet (Standard_True);
+  Standard_IStream* aDirectStream = NULL;
+  if (myIsQuickPart) // enables direct reading of shapes from the stream
+    aDirectStream = const_cast<BinObjMgt_Persistent*>(&theSource)->GetIStream();
 
-  for (Standard_Integer i = 1; i <= aNbShapes; i++) {
+  NCollection_List<TopoDS_Shape> anOldShapes, aNewShapes;
+  for (Standard_Integer i = 1; i <= aNbShapes; i++)
+  {
     TopoDS_Shape anOldShape, aNewShape;
-    
-    if ( anEvol != TNaming_PRIMITIVE ) 
-      if(TranslateFrom(theSource, anOldShape, aShapeSet)) return Standard_False;
-
-    if (anEvol != TNaming_DELETE) 
-      if(TranslateFrom(theSource, aNewShape, aShapeSet)) return Standard_False;
-
-    switch (anEvol) {
-    case TNaming_PRIMITIVE    : 
-      aBuilder.Generated(aNewShape); 
-      break;
-    case TNaming_GENERATED    : 
-      aBuilder.Generated(anOldShape, aNewShape); 
-      break;
-    case TNaming_MODIFY       : 
-      aBuilder.Modify(anOldShape, aNewShape); 
-      break;
-    case TNaming_DELETE       : 
-      aBuilder.Delete (anOldShape); 
-      break;
-    case TNaming_SELECTED     : 
-      aBuilder.Select(aNewShape, anOldShape); 
-      break;
-    case TNaming_REPLACE      :
-      aBuilder.Modify(anOldShape, aNewShape); // for compatibility aBuilder.Replace(anOldShape, aNewShape);
-      break;
-      default :
-        Standard_DomainError::Raise("TNaming_Evolution:: Evolution Unknown");
+
+    if (anEvol != TNaming_PRIMITIVE)
+    {
+      if (myIsQuickPart)
+        aShapeSet->Read (*aDirectStream, anOldShape);
+      else
+        if (TranslateFrom (theSource, anOldShape, static_cast<BinTools_ShapeSet*>(aShapeSet))) return Standard_False;
+    }
+
+    if (anEvol != TNaming_DELETE)
+    {
+      if (myIsQuickPart)
+        aShapeSet->Read (*aDirectStream, aNewShape);
+      else
+        if (TranslateFrom (theSource, aNewShape, static_cast<BinTools_ShapeSet*>(aShapeSet))) return Standard_False;
+    }
+
+    // Here we add shapes in reverse order because TNaming_Builder also adds them in reverse order.
+    anOldShapes.Prepend (anOldShape);
+    aNewShapes.Prepend (aNewShape);
+  }
+
+  for (NCollection_List<TopoDS_Shape>::Iterator anOldIt (anOldShapes), aNewIt (aNewShapes);
+      anOldIt.More() && aNewIt.More();
+      anOldIt.Next(), aNewIt.Next())
+  {
+    switch (anEvol)
+    {
+      case TNaming_PRIMITIVE:
+        aBuilder.Generated (aNewIt.Value ());
+        break;
+      case TNaming_GENERATED:
+        aBuilder.Generated (anOldIt.Value(), aNewIt.Value());
+        break;
+      case TNaming_MODIFY:
+        aBuilder.Modify (anOldIt.Value(), aNewIt.Value());
+        break;
+      case TNaming_DELETE:
+        aBuilder.Delete (anOldIt.Value());
+        break;
+      case TNaming_SELECTED:
+        aBuilder.Select (aNewIt.Value(), anOldIt.Value());
+        break;
+      case TNaming_REPLACE:
+        aBuilder.Modify (anOldIt.Value(), aNewIt.Value()); // for compatibility aBuilder.Replace(anOldShape, aNewShape);
+        break;
+      default:
+          throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
     }
-    anOldShape.Nullify();
-    aNewShape.Nullify();
   }
   return Standard_True;
 }
@@ -239,28 +264,37 @@ void BinMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource,
   for (TNaming_Iterator SItr (aSAtt); SItr.More (); SItr.Next ()) NbShapes++;
   //--------------------------------------------------------------
 
-  if (NbShapes == 0) return;
-
-  BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
+  BinTools_ShapeSetBase* aShapeSet = const_cast<BinMNaming_NamedShapeDriver*>(this)->ShapeSet (Standard_False);
   TNaming_Evolution anEvol = aSAtt->Evolution();
   
   theTarget << NbShapes;
   theTarget << aSAtt->Version();
-  theTarget << EvolutionToChar(anEvol);
+  theTarget << EvolutionToChar (anEvol);
 
-  Standard_Integer i = 1;  
-  for (TNaming_Iterator SIterator(aSAtt) ;SIterator.More(); SIterator.Next()) {
-    const TopoDS_Shape& OldShape = SIterator.OldShape();
-    const TopoDS_Shape& NewShape = SIterator.NewShape();
-    
-    if ( anEvol != TNaming_PRIMITIVE ) 
-      TranslateTo (OldShape, theTarget, aShapeSet); 
 
-    if (anEvol != TNaming_DELETE) 
-      TranslateTo (NewShape, theTarget, aShapeSet);
+  Standard_OStream* aDirectStream = NULL;
+  if (myIsQuickPart) // enables direct writing of shapes to the stream
+    aDirectStream = theTarget.GetOStream();
+
+  for (TNaming_Iterator SIterator(aSAtt); SIterator.More(); SIterator.Next()) {
+    const TopoDS_Shape& anOldShape = SIterator.OldShape();
+    const TopoDS_Shape& aNewShape = SIterator.NewShape();
     
-    i++;
+    if (anEvol != TNaming_PRIMITIVE)
+    {
+      if (myIsQuickPart)
+        aShapeSet->Write (anOldShape, *aDirectStream);
+      else
+        TranslateTo (anOldShape, theTarget, static_cast<BinTools_ShapeSet*>(aShapeSet));
+    }
+
+    if (anEvol != TNaming_DELETE)
+    {
+      if (myIsQuickPart)
+        aShapeSet->Write (aNewShape, *aDirectStream);
+      else
+        TranslateTo (aNewShape, theTarget, static_cast<BinTools_ShapeSet*>(aShapeSet));
+    }
   }
 
 }
@@ -271,12 +305,22 @@ void BinMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource,
 //purpose  : 
 //=======================================================================
 
-void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS)
+void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS,
+                                                     const Standard_Integer theDocVer,
+                                                     const Message_ProgressRange& theRange)
 {
-  theOS << SHAPESET; 
-  myShapeSet.SetFormatNb(myFormatNb);
-  myShapeSet.Write (theOS);
-  myShapeSet.Clear();
+  myIsQuickPart = Standard_False;
+  theOS << SHAPESET;
+  if (theDocVer >= TDocStd_FormatVersion_VERSION_11)
+  {
+    ShapeSet (Standard_False)->SetFormatNb (BinTools_FormatVersion_VERSION_4);
+  }
+  else
+  {
+    ShapeSet (Standard_False)->SetFormatNb (BinTools_FormatVersion_VERSION_1);
+  }
+  ShapeSet (Standard_False)->Write (theOS, theRange);
+  ShapeSet (Standard_False)->Clear();
 }
 
 //=======================================================================
@@ -286,7 +330,12 @@ void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS)
 
 void BinMNaming_NamedShapeDriver::Clear()
 {
-  myShapeSet.Clear();
+  if (myShapeSet)
+  {
+    myShapeSet->Clear();
+    delete myShapeSet;
+    myShapeSet = NULL;
+  }
 }
 
 //=======================================================================
@@ -294,19 +343,54 @@ void BinMNaming_NamedShapeDriver::Clear()
 //purpose  : 
 //=======================================================================
 
-void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS)
+void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS,
+                                                    const Message_ProgressRange& theRange)
 {
+  myIsQuickPart = Standard_False;
   // check section title string; note that some versions of OCCT (up to 6.3.1) 
   // might avoid writing shape section if it is empty
   std::streamoff aPos = theIS.tellg();
   TCollection_AsciiString aSectionTitle;
   theIS >> aSectionTitle;
   if(aSectionTitle.Length() > 0 && aSectionTitle == SHAPESET) {
-    myShapeSet.Clear();
-    myShapeSet.Read (theIS);
-    SetFormatNb(myShapeSet.FormatNb());
+    BinTools_ShapeSetBase* aShapeSet = ShapeSet (Standard_True);
+    aShapeSet->Clear();
+    aShapeSet->Read (theIS, theRange);
   }
   else
-    theIS.seekg(aPos); // no shape section is present, try to return to initial point
+    theIS.seekg (aPos); // no shape section is present, try to return to initial point
+}
+
+//=======================================================================
+//function : ShapeSet
+//purpose  : 
+//=======================================================================
+
+BinTools_ShapeSetBase* BinMNaming_NamedShapeDriver::ShapeSet (const Standard_Boolean theReading)
+{
+  if (!myShapeSet)
+  {
+    if (myIsQuickPart)
+    {
+      if (theReading)
+        myShapeSet = new BinTools_ShapeReader();
+      else
+        myShapeSet = new BinTools_ShapeWriter();
+    }
+    else
+      myShapeSet = new BinTools_ShapeSet();
+    myShapeSet->SetWithTriangles(myWithTriangles);
+    myShapeSet->SetWithNormals(myWithNormals);
+  }
+  return myShapeSet;
 }
 
+//=======================================================================
+//function : GetShapesLocations
+//purpose  : 
+//=======================================================================
+BinTools_LocationSet& BinMNaming_NamedShapeDriver::GetShapesLocations() const
+{
+  BinTools_ShapeSetBase* aShapeSet = const_cast<BinMNaming_NamedShapeDriver*>(this)->ShapeSet (Standard_False);
+  return static_cast<BinTools_ShapeSet*>(aShapeSet)->ChangeLocations();
+}