0031485: Data Exchange - Export STEP in nonmanifold mode looses all faces except one
[occt.git] / src / STEPControl / STEPControl_ActorWrite.cxx
index 7fc7769..a1de838 100644 (file)
@@ -33,6 +33,7 @@
 #include <OSD_Timer.hxx>
 #include <ShapeAnalysis_ShapeTolerance.hxx>
 #include <ShapeExtend_Explorer.hxx>
+#include <ShapeProcess_ShapeContext.hxx>
 #include <Standard_Type.hxx>
 #include <StepBasic_ApplicationProtocolDefinition.hxx>
 #include <StepBasic_HArray1OfProduct.hxx>
 #include <XSAlgo.hxx>
 #include <XSAlgo_AlgoContainer.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(STEPControl_ActorWrite,Transfer_ActorOfFinderProcess)
+
 //  Transfer
 //  TransferShape
 //:d6
@@ -154,14 +157,14 @@ static void DumpWhatIs(const TopoDS_Shape& S) {
     }
   }
 
-  cout << "//What is?// NB SOLIDS: " << nbSolids << endl;
-  cout << "//What is?// NB SHELLS: " << nbShells << endl;
-  cout << "//What is?//    OPEN SHELLS: " << nbOpenShells << endl;
-  cout << "//What is?//    CLOSED SHELLS: " << nbShells - nbOpenShells << endl;
-  cout << "//What is?// NB FACES: " << nbFaces << endl;
-  cout << "//What is?// NB WIRES: " << nbWires << endl;
-  cout << "//What is?// NB EDGES: " << nbEdges << endl;
-  cout << "//What is?// NB VERTEXES: " << nbVertexes << endl;
+  std::cout << "//What is?// NB SOLIDS: " << nbSolids << std::endl;
+  std::cout << "//What is?// NB SHELLS: " << nbShells << std::endl;
+  std::cout << "//What is?//    OPEN SHELLS: " << nbOpenShells << std::endl;
+  std::cout << "//What is?//    CLOSED SHELLS: " << nbShells - nbOpenShells << std::endl;
+  std::cout << "//What is?// NB FACES: " << nbFaces << std::endl;
+  std::cout << "//What is?// NB WIRES: " << nbWires << std::endl;
+  std::cout << "//What is?// NB EDGES: " << nbEdges << std::endl;
+  std::cout << "//What is?// NB VERTEXES: " << nbVertexes << std::endl;
 }
 #endif
 
@@ -196,7 +199,7 @@ static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
 
   Standard_Integer aNbEdges = aMapEdgeFaces.Extent();
   #ifdef OCCT_DEBUG
-  cout << "Checking whether the topology passed is manifold..." << endl;
+  std::cout << "Checking whether the topology passed is manifold..." << std::endl;
   #endif
 
   // Check topology
@@ -212,8 +215,8 @@ static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
   }
 
   #ifdef OCCT_DEBUG
-  cout << "Check result: "
-       << (aResult ? "TRUE" : "FALSE") << endl;
+  std::cout << "Check result: "
+       << (aResult ? "TRUE" : "FALSE") << std::endl;
   #endif
 
   return aResult;
@@ -253,13 +256,13 @@ Handle(StepShape_NonManifoldSurfaceShapeRepresentation) STEPControl_ActorWrite::
 
   if ( aResult.IsNull() ) {
     #ifdef OCCT_DEBUG
-    cout << "\nNew NMSSR created" << endl;
+    std::cout << "\nNew NMSSR created" << std::endl;
     #endif
     aResult = new StepShape_NonManifoldSurfaceShapeRepresentation;
     isNMSSRCreated = Standard_True;
   } else {
     #ifdef OCCT_DEBUG
-    cout << "\nExisting NMSSR is used" << endl;
+    std::cout << "\nExisting NMSSR is used" << std::endl;
     #endif
     isNMSSRCreated = Standard_False;
   }
@@ -267,6 +270,34 @@ Handle(StepShape_NonManifoldSurfaceShapeRepresentation) STEPControl_ActorWrite::
   return aResult;
 }
 
+//=======================================================================
+//function : mergeInfoForNM
+//purpose  : bind already written shared faces to STEP entity for non-manifold
+//=======================================================================
+void STEPControl_ActorWrite::mergeInfoForNM(const Handle(Transfer_FinderProcess)& theFP,
+                                            const Handle(Standard_Transient) &theInfo) const
+{
+  Handle(ShapeProcess_ShapeContext) aContext = Handle(ShapeProcess_ShapeContext)::DownCast ( theInfo );
+  if ( aContext.IsNull() ) return;
+
+  const TopTools_DataMapOfShapeShape &aMap = aContext->Map();
+  TopTools_DataMapIteratorOfDataMapOfShapeShape aShapeShapeIt(aMap);
+
+  for ( ; aShapeShapeIt.More(); aShapeShapeIt.Next() ) {
+    TopoDS_Shape anOrig = aShapeShapeIt.Key(), aRes = aShapeShapeIt.Value();
+    if (anOrig.ShapeType() != TopAbs_FACE)
+      continue;
+
+    Handle(TransferBRep_ShapeMapper) anOrigMapper= TransferBRep::ShapeMapper ( theFP, anOrig);
+    Handle(Transfer_Binder) anOrigBinder = theFP->Find ( anOrigMapper );
+    if (anOrigBinder.IsNull())
+      continue;
+
+    Handle(TransferBRep_ShapeMapper) aResMapper = TransferBRep::ShapeMapper ( theFP, aRes );
+    theFP->Bind(aResMapper, anOrigBinder);
+  }
+}
+
 
 //=======================================================================
 //function : SetMode
@@ -281,8 +312,8 @@ void STEPControl_ActorWrite::SetMode (const STEPControl_StepModelType M)
   case STEPControl_BrepWithVoids :     ModeTrans() = 5; break;
   case STEPControl_FacetedBrep :       ModeTrans() = 1; break;
   case STEPControl_FacetedBrepAndBrepWithVoids : ModeTrans() = 6; break;
-  case STEPControl_ShellBasedSurfaceModel :      ModeTrans() = 2;
-  case STEPControl_GeometricCurveSet :           ModeTrans() = 4;
+  case STEPControl_ShellBasedSurfaceModel :      ModeTrans() = 2; break;
+  case STEPControl_GeometricCurveSet :           ModeTrans() = 4; break;
   case STEPControl_Hybrid : ModeTrans() = 0; break;  // PAS IMPLEMENTE !!
     default: break;
   }
@@ -602,7 +633,7 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
     // as assembly - while face already translated, it should be 
     // re-translated to break sharing
 #ifdef OCCT_DEBUG
-    cout << "Warning: STEPControl_ActorWrite::TransferShape(): shape already translated" << endl;
+    std::cout << "Warning: STEPControl_ActorWrite::TransferShape(): shape already translated" << std::endl;
 #endif
 //    return binder;
   }
@@ -612,7 +643,7 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
     return TransferCompound(start, SDR0, FP);
 
   // [BEGIN] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
-  Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
+  Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold") != 0;
   Handle(Transfer_Binder) aNMBinder;
   if (isNMMode && !GroupMode() && theShape.ShapeType() == TopAbs_COMPOUND) {
     TopoDS_Compound aNMCompound;
@@ -865,16 +896,15 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
     Handle(Standard_Transient) info;
     Standard_Real maxTol = Interface_Static::RVal("read.maxprecision.val");
 
-    // Fix only manifold shapes, do nothing with non-manifold topology as it is processed separately (ssv; 13.11.2010)
     TopoDS_Shape aShape;
-    if (isManifold)
-      aShape = XSAlgo::AlgoContainer()->ProcessShape(xShape, Tol, maxTol
-                                                    "write.step.resource.name", 
-                                                    "write.step.sequence", info,
-                                                    FP->GetProgress() );
-    else
-      aShape = xShape;
-    
+    aShape = XSAlgo::AlgoContainer()->ProcessShape(xShape, Tol, maxTol, 
+                                                  "write.step.resource.name"
+                                                  "write.step.sequence", info,
+                                                  FP->GetProgress() );
+    if (!isManifold) {
+      mergeInfoForNM(FP, info);
+    }
+
     // create a STEP entity corresponding to shape
     Handle(StepGeom_GeometricRepresentationItem) item;
     switch (trmode)
@@ -1248,7 +1278,7 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(T
   TopoDS_Shape theShape = mapper->Value();
 
   // Inspect non-manifold topology case (ssv; 10.11.2010)
-  Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
+  Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold") != 0;
   Standard_Boolean isManifold;
   if (isNMMode)
     isManifold = IsManifoldShape(theShape);
@@ -1269,7 +1299,7 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(T
  
   #ifdef OCCT_DEBUG
   if (!isManifold)
-    cout << "Exploding Solids to Shells if any..." << endl;
+    std::cout << "Exploding Solids to Shells if any..." << std::endl;
   #endif
 
   for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
@@ -1285,7 +1315,9 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(T
           NonManifoldGroup->Append(aSubShell);
         }
       } 
-      else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
+      else if (!isManifold &&
+               (aSubShape.ShapeType() == TopAbs_SHELL || aSubShape.ShapeType() == TopAbs_FACE))
+      {
         RepItemSeq->Append(aSubShape);
         NonManifoldGroup->Append(aSubShape);
       }