0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[occt.git] / src / STEPControl / STEPControl_ActorWrite.cxx
old mode 100755 (executable)
new mode 100644 (file)
index fba328a..268c968
+// Copyright (c) 1999-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.
+
 //:k8 abv 6 Jan 99: unique names for PRODUCTs
 //:k9 abv 6 Jan 99: TR10: eliminating duplicated APPLICATION_CONTEXT entities
 //abv,gka 05.04.99: S4136: change parameters and update units
 // PTV    22.08.2002 OCC609 transfer solo vertices into step file.
 // PTV    16.09.2002 OCC725 transfer compound of vertices into one geometrical curve set.
-#include <STEPControl_ActorWrite.ixx>
-#include <STEPControl_StepModelType.hxx>
 
-//  Transfer
-#include <Transfer_SimpleBinderOfTransient.hxx>
-#include <gp_Ax2.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepTools_Modifier.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_Surface.hxx>
 #include <GeomToStep_MakeAxis2Placement3d.hxx>
-#include <StepGeom_Axis2Placement3d.hxx>
-
-#include <STEPConstruct_Part.hxx>
+#include <gp_Ax2.hxx>
+#include <Interface_Macros.hxx>
+#include <Interface_MSG.hxx>
+#include <Interface_Static.hxx>
+#include <MoniTool_DataMapOfShapeTransient.hxx>
+#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 <STEPConstruct_AP203Context.hxx>
 #include <STEPConstruct_Assembly.hxx>
 #include <STEPConstruct_ContextTool.hxx>
+#include <STEPConstruct_Part.hxx>
 #include <STEPConstruct_UnitContext.hxx>
-
-//  TransferShape
+#include <STEPControl_ActorWrite.hxx>
+#include <STEPControl_StepModelType.hxx>
+#include <StepData_StepModel.hxx>
+#include <StepGeom_Axis2Placement3d.hxx>
+#include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
+#include <StepGeom_Point.hxx>
+#include <StepRepr_GlobalUnitAssignedContext.hxx>
+#include <StepRepr_HArray1OfRepresentationItem.hxx>
+#include <StepRepr_PropertyDefinition.hxx>
+#include <StepRepr_ShapeRepresentationRelationship.hxx>
+#include <StepShape_AdvancedBrepShapeRepresentation.hxx>
+#include <StepShape_BrepWithVoids.hxx>
+#include <StepShape_FacetedBrep.hxx>
+#include <StepShape_FacetedBrepAndBrepWithVoids.hxx>
+#include <StepShape_FacetedBrepShapeRepresentation.hxx>
+#include <StepShape_GeometricallyBoundedWireframeShapeRepresentation.hxx>
+#include <StepShape_GeometricCurveSet.hxx>
+#include <StepShape_GeometricSetSelect.hxx>
+#include <StepShape_HArray1OfGeometricSetSelect.hxx>
+#include <StepShape_ManifoldSolidBrep.hxx>
+#include <StepShape_ManifoldSurfaceShapeRepresentation.hxx>
+#include <StepShape_NonManifoldSurfaceShapeRepresentation.hxx>
+#include <StepShape_ShapeDefinitionRepresentation.hxx>
+#include <StepShape_ShapeRepresentation.hxx>
+#include <StepShape_ShellBasedSurfaceModel.hxx>
+#include <StepShape_TopologicalRepresentationItem.hxx>
+#include <StepShape_VertexPoint.hxx>
+#include <TCollection_HAsciiString.hxx>
+#include <TColStd_HSequenceOfTransient.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Solid.hxx>
 #include <TopoDSToStep.hxx>
 #include <TopoDSToStep_Builder.hxx>
 #include <TopoDSToStep_FacetedTool.hxx>
-#include <TopoDSToStep_Tool.hxx>
-#include <TopoDSToStep_MakeManifoldSolidBrep.hxx>
 #include <TopoDSToStep_MakeBrepWithVoids.hxx>
 #include <TopoDSToStep_MakeFacetedBrep.hxx>
 #include <TopoDSToStep_MakeFacetedBrepAndBrepWithVoids.hxx>
 #include <TopoDSToStep_MakeGeometricCurveSet.hxx>
+#include <TopoDSToStep_MakeManifoldSolidBrep.hxx>
 #include <TopoDSToStep_MakeShellBasedSurfaceModel.hxx>
-
-#include <TopoDS.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Solid.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_Line.hxx>
-
-#include <StepShape_ShapeDefinitionRepresentation.hxx>
-#include <StepShape_FacetedBrepAndBrepWithVoids.hxx>
-#include <StepShape_FacetedBrep.hxx>
-#include <StepShape_GeometricCurveSet.hxx>
-#include <StepShape_ShellBasedSurfaceModel.hxx>
-#include <StepShape_ManifoldSolidBrep.hxx>
-#include <StepShape_BrepWithVoids.hxx>
-#include <StepRepr_HArray1OfRepresentationItem.hxx>
-#include <StepBasic_HArray1OfProduct.hxx>
-#include <StepRepr_GlobalUnitAssignedContext.hxx>
-#include <StepShape_AdvancedBrepShapeRepresentation.hxx>
-#include <StepShape_FacetedBrepShapeRepresentation.hxx>
-#include <StepShape_TopologicalRepresentationItem.hxx>
-#include <StepShape_ManifoldSurfaceShapeRepresentation.hxx>
-#include <StepShape_GeometricallyBoundedWireframeShapeRepresentation.hxx>
-#include <StepBasic_ApplicationProtocolDefinition.hxx>
-#include <StepRepr_PropertyDefinition.hxx>
-
-#include <TopExp_Explorer.hxx>
-#include <TColStd_HSequenceOfTransient.hxx>
-#include <TCollection_HAsciiString.hxx>
-
-#include <Transfer_TransientProcess.hxx>
+#include <TopoDSToStep_MakeStepVertex.hxx>
+#include <TopoDSToStep_Tool.hxx>
+#include <TopTools_HSequenceOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <Transfer_Binder.hxx>
 #include <Transfer_Finder.hxx>
 #include <Transfer_FinderProcess.hxx>
-#include <TransferBRep_ShapeMapper.hxx>
+#include <Transfer_SequenceOfBinder.hxx>
+#include <Transfer_SimpleBinderOfTransient.hxx>
+#include <Transfer_TransientProcess.hxx>
 #include <TransferBRep.hxx>
-#include <OSD_Timer.hxx>
-
-#include <ShapeExtend_Explorer.hxx>  
-#include <ShapeAnalysis_ShapeTolerance.hxx>
-#include <Interface_MSG.hxx>
-#include <Interface_Static.hxx>
-
-#include <Interface_Macros.hxx>
-#include <TopTools_HSequenceOfShape.hxx>
-
-#include <BRep_Tool.hxx>
-#include <TopoDS_Iterator.hxx> //:d6
+#include <TransferBRep_ShapeMapper.hxx>
 #include <UnitsMethods.hxx>
-#include <STEPConstruct_AP203Context.hxx>
-#include <BRepTools_Modifier.hxx>
-
 #include <XSAlgo.hxx>
 #include <XSAlgo_AlgoContainer.hxx>
-#include <StepRepr_ShapeRepresentationRelationship.hxx>
-#include <Transfer_SequenceOfBinder.hxx>
 
-#include <TopoDSToStep_MakeStepVertex.hxx>
-#include <StepShape_VertexPoint.hxx>
-#include <MoniTool_DataMapOfShapeTransient.hxx>
-#include <StepShape_HArray1OfGeometricSetSelect.hxx>
-#include <StepShape_GeometricSetSelect.hxx>
-#include <TopoDS_Compound.hxx>
-#include <BRep_Builder.hxx>
+IMPLEMENT_STANDARD_RTTIEXT(STEPControl_ActorWrite,Transfer_ActorOfFinderProcess)
 
+//  Transfer
+//  TransferShape
+//:d6
 // Non-manifold topology processing (ssv; 10.11.2010)
-#include <StepShape_NonManifoldSurfaceShapeRepresentation.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopExp.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-
 // ============================================================================
 // Function: DumpWhatIs   
-// Purpose: Use it in DEB mode to dump your shapes
+// Purpose: Use it in debug mode to dump your shapes
 // ============================================================================
-
+#ifdef OCCT_DEBUG
 static void DumpWhatIs(const TopoDS_Shape& S) {
 
   TopTools_MapOfShape aMapOfShape;
@@ -146,7 +156,7 @@ static void DumpWhatIs(const TopoDS_Shape& S) {
         nbVertexes++;
     }
   }
-  #ifdef DEB
+
   cout << "//What is?// NB SOLIDS: " << nbSolids << endl;
   cout << "//What is?// NB SHELLS: " << nbShells << endl;
   cout << "//What is?//    OPEN SHELLS: " << nbOpenShells << endl;
@@ -155,8 +165,8 @@ static void DumpWhatIs(const TopoDS_Shape& S) {
   cout << "//What is?// NB WIRES: " << nbWires << endl;
   cout << "//What is?// NB EDGES: " << nbEdges << endl;
   cout << "//What is?// NB VERTEXES: " << nbVertexes << endl;
-  #endif
 }
+#endif
 
 //=======================================================================
 // Function : IsManifoldShape
@@ -180,7 +190,7 @@ static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
       aBrepBuilder.Add(aDirectShapes, aDirectChild);
   }  
 
-  #ifdef DEB
+  #ifdef OCCT_DEBUG
   DumpWhatIs(aDirectShapes);
   #endif
 
@@ -188,7 +198,7 @@ static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
   TopExp::MapShapesAndAncestors(aDirectShapes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
 
   Standard_Integer aNbEdges = aMapEdgeFaces.Extent();
-  #ifdef DEB
+  #ifdef OCCT_DEBUG
   cout << "Checking whether the topology passed is manifold..." << endl;
   #endif
 
@@ -204,33 +214,13 @@ static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
     }
   }
 
-  #ifdef DEB
+  #ifdef OCCT_DEBUG
   cout << "Check result: "
        << (aResult ? "TRUE" : "FALSE") << endl;
   #endif
 
   return aResult;
 }
-
-/* this is a start of a comment! */ 
-#ifdef DEB
-void DumpBinder (const Handle(Transfer_Binder) &binder)
-{
-  Handle(Transfer_Binder) bbb = binder;
-  while ( ! bbb.IsNull() ) {
-    Handle(Transfer_SimpleBinderOfTransient) bx = 
-      Handle(Transfer_SimpleBinderOfTransient)::DownCast ( bbb );
-    cout << (void*)&bx;
-    if ( ! bx.IsNull() ) {
-      cout << "--> " << bx->ResultTypeName() << " " << *(void**)&bx->Result() << endl;
-    }
-    else cout << "--> ???" << endl;
-    bbb = bbb->NextResult();
-  }
-  cout << endl;
-}
-#endif
-/* this is a end of a comment */
   
 //=======================================================================
 //function : STEPControl_ActorWrite
@@ -265,13 +255,13 @@ Handle(StepShape_NonManifoldSurfaceShapeRepresentation) STEPControl_ActorWrite::
   }
 
   if ( aResult.IsNull() ) {
-    #ifdef DEB
+    #ifdef OCCT_DEBUG
     cout << "\nNew NMSSR created" << endl;
     #endif
     aResult = new StepShape_NonManifoldSurfaceShapeRepresentation;
     isNMSSRCreated = Standard_True;
   } else {
-    #ifdef DEB
+    #ifdef OCCT_DEBUG
     cout << "\nExisting NMSSR is used" << endl;
     #endif
     isNMSSRCreated = Standard_False;
@@ -280,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
@@ -447,7 +465,7 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::Transfer (const Handle(Transfer_
   Standard_Real lFactor = UnitsMethods::GetLengthFactorValue ( Interface_Static::IVal ( "write.step.unit" ) );
   lFactor /= UnitsMethods::GetCasCadeLengthUnit();
   Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
-  UnitsMethods::InitializeFactors ( lFactor, ( anglemode <= 1 ? 1. : PI/180. ), 1. );
+  UnitsMethods::InitializeFactors ( lFactor, ( anglemode <= 1 ? 1. : M_PI/180. ), 1. );
 
   // create SDR
   STEPConstruct_Part SDRTool;
@@ -510,17 +528,19 @@ Standard_Boolean STEPControl_ActorWrite::IsAssembly (TopoDS_Shape &S) const
 {
   if ( ! GroupMode() || S.ShapeType() != TopAbs_COMPOUND ) return Standard_False;
   // PTV 16.09.2002  OCC725 for storing compound of vertices
-  if (S.ShapeType() == TopAbs_COMPOUND ) {
-    Standard_Boolean IsOnlyVertices = Standard_True;
-    TopoDS_Iterator anItr( S );
-    for ( ; anItr.More(); anItr.Next() ) {
-      if ( anItr.Value().ShapeType() != TopAbs_VERTEX ) {
-        IsOnlyVertices = Standard_False;
-        break;
+  if (Interface_Static::IVal("write.step.vertex.mode") == 0) {//bug 23950
+    if (S.ShapeType() == TopAbs_COMPOUND ) {
+      Standard_Boolean IsOnlyVertices = Standard_True;
+      TopoDS_Iterator anItr( S );
+      for ( ; anItr.More(); anItr.Next() ) {
+        if ( anItr.Value().ShapeType() != TopAbs_VERTEX ) {
+          IsOnlyVertices = Standard_False;
+          break;
+        }
       }
+      if ( IsOnlyVertices )
+        return Standard_False;
     }
-    if ( IsOnlyVertices )
-      return Standard_False;
   }
   if ( GroupMode() ==1 ) return Standard_True;
   TopoDS_Iterator it ( S );
@@ -612,7 +632,7 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
     //:abv 20.05.02: writing box & face from it (shared) in one compound 
     // as assembly - while face already translated, it should be 
     // re-translated to break sharing
-#ifdef DEB
+#ifdef OCCT_DEBUG
     cout << "Warning: STEPControl_ActorWrite::TransferShape(): shape already translated" << endl;
 #endif
 //    return binder;
@@ -623,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;
@@ -726,8 +746,8 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
       // NOTE: aNMBinder is connected now with this SDR. It will be added to the resulting
       //       binder in the end of this invocation of TransferShape
       for (Standard_Integer i = 1; i <= aNMItemsNb; i++) {
-        Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper( FP, RepItemSeq->Value(i) );
-        TransferShape(mapper, sdr, FP, NonManifoldGroup, Standard_False);
+        Handle(TransferBRep_ShapeMapper) aMapper = TransferBRep::ShapeMapper( FP, RepItemSeq->Value(i) );
+        TransferShape(aMapper, sdr, FP, NonManifoldGroup, Standard_False);
       }
 
       // Nothing else needed for pure non-manifold topology, return
@@ -742,7 +762,10 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
   // create a list of items to translate
   Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
   
+  Standard_Boolean isSeparateVertices = 
+    Interface_Static::IVal("write.step.vertex.mode") == 0;//bug 23950
   // PTV 16.09.2002 OCC725 separate shape from solo vertices.
+  Standard_Boolean isOnlyVertices = Standard_False;
   if (theShape.ShapeType() == TopAbs_COMPOUND) {
     Standard_Integer countVrtx = 0;
     Standard_Integer countSh = 0;
@@ -751,27 +774,28 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
     aB.MakeCompound(aNewShape);
     aB.MakeCompound(aCompOfVrtx);
     TopoDS_Iterator anCompIt(theShape);
-    for (; anCompIt.More(); anCompIt.Next()) {
-      TopoDS_Shape aCurSh = anCompIt.Value();
-      if (aCurSh.ShapeType() != TopAbs_VERTEX) {
-        aB.Add(aNewShape, aCurSh);
-        countSh++;
-      }
-      else {
-        aB.Add(aCompOfVrtx, aCurSh);
-        countVrtx++;
+    if (isSeparateVertices) {
+      for (; anCompIt.More(); anCompIt.Next()) {
+        TopoDS_Shape aCurSh = anCompIt.Value();
+        if (aCurSh.ShapeType() != TopAbs_VERTEX) {
+          aB.Add(aNewShape, aCurSh);
+          countSh++;
+        }
+        else {
+          aB.Add(aCompOfVrtx, aCurSh);
+          countVrtx++;
+        }
       }
+      // replace the shapes
+      if (countSh)
+        theShape = aNewShape;
+      if (countVrtx)
+        RepItemSeq->Append(aCompOfVrtx);
+      if (countSh == 0) 
+        isOnlyVertices = Standard_True;
     }
-    // replace the shapes
-    if (countSh)
-      theShape = aNewShape;
-    if (countVrtx)
-      RepItemSeq->Append(aCompOfVrtx);
   } 
-  else if (theShape.ShapeType() == TopAbs_VERTEX)
-    RepItemSeq->Append(theShape); // to translate one vertex
   
-
   if (theShape.ShapeType() == TopAbs_COMPOUND) {
     TopExp_Explorer SolidExp, ShellExp, FaceExp;
     if (mymode != STEPControl_GeometricCurveSet) {
@@ -790,7 +814,8 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
       }
     }
     else {
-      RepItemSeq->Append(theShape); //:j1
+      if (!isOnlyVertices) 
+        RepItemSeq->Append(theShape); //:j1
     }
     if(mymode == STEPControl_AsIs) {
       TopExp_Explorer WireExp, EdgeExp;
@@ -812,6 +837,19 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
   else if (theShape.ShapeType() == TopAbs_FACE) {
     RepItemSeq->Append(TopoDS::Face(theShape));
   }
+  else if (theShape.ShapeType() == TopAbs_COMPSOLID) {
+    FP->AddWarning(start,"NonManifold COMPSOLID was translated like a set of SOLIDs");
+    if ( GroupMode() > 0)
+      return TransferCompound(start, SDR0, FP);
+    else {
+      TopExp_Explorer SolidExp;
+      for (SolidExp.Init(theShape, TopAbs_SOLID);
+           SolidExp.More();SolidExp.Next()) {
+        RepItemSeq->Append(TopoDS::Solid(SolidExp.Current()));
+      }
+    }
+  }
+
   else if (mymode != STEPControl_GeometricCurveSet && mymode != STEPControl_AsIs) {
     FP->AddFail(start,"The Shape is not a SOLID, nor a SHELL, nor a FACE");
     return binder;
@@ -858,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)
@@ -1241,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);
@@ -1252,20 +1289,22 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(T
   Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
   // Prepare a collection for non-manifold group of shapes
   Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
+  Standard_Boolean isSeparateVertices = 
+    (Interface_Static::IVal("write.step.vertex.mode") == 0);//bug 23950
   // PTV OCC725 17.09.2002 -- begin --
   Standard_Integer nbFreeVrtx = 0;
   TopoDS_Compound aCompOfVrtx;
   BRep_Builder aB;
   aB.MakeCompound(aCompOfVrtx);
  
-  #ifdef DEB
+  #ifdef OCCT_DEBUG
   if (!isManifold)
     cout << "Exploding Solids to Shells if any..." << endl;
   #endif
 
   for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
     TopoDS_Shape aSubShape = iter.Value();
-    if (aSubShape.ShapeType() != TopAbs_VERTEX) {
+    if (aSubShape.ShapeType() != TopAbs_VERTEX || !isSeparateVertices) {
 
       // Store non-manifold topology as shells (ssv; 10.11.2010)
       if (!isManifold && aSubShape.ShapeType() == TopAbs_SOLID) {
@@ -1320,12 +1359,13 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(T
     while ( !bnd.IsNull() ) {
       Handle(Transfer_SimpleBinderOfTransient) bx = 
         Handle(Transfer_SimpleBinderOfTransient)::DownCast(bnd);
-      if ( !bx.IsNull() )
+      if ( !bx.IsNull() ) {
         // Single SDR is created for a non-manifold group (ssv: 12.11.2010)
         if (!isManifold && i > 1)
           break;
         else
           binder->AddResult( TransientResult( bx->Result() ) );
+      }
       bnd = bnd->NextResult();
     }
   }
@@ -1408,6 +1448,8 @@ Handle(Transfer_Binder)  STEPControl_ActorWrite::TransferSubShape (const Handle(
     FP->Bind (mapper,resbind);
     resprod=resbind; //KA - OCC7141(skl 10.11.2004)
   }
+  if (resprod.IsNull())
+    return resprod;
 
   // A new resbind may have been produced
 //  DeclareAndCast(Transfer_SimpleBinderOfTransient,restrans,resbind);