Salome HOME
PAL7508: Development of GetInPlace() functionality
[modules/geom.git] / src / GEOMImpl / GEOMImpl_GlueDriver.cxx
index cd65a79fc71ac10499e666716f3ee531286dd314..f2af73996ccbd8eb19b67bb5c35da707f1d56058 100644 (file)
@@ -4,14 +4,23 @@ using namespace std;
 #include "GEOMImpl_IGlue.hxx"
 #include "GEOMImpl_Types.hxx"
 
+#include "GEOM_Object.hxx"
 #include "GEOM_Function.hxx"
 
 #include "GEOMAlgo_Gluer.hxx"
 
 #include "utilities.h"
 
+#include <TDataStd_IntegerArray.hxx>
+
+#include <TopExp.hxx>
 #include <TopoDS_Shape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+
 #include <Standard_NullObject.hxx>
+#include <Standard_Failure.hxx>
 
 //=======================================================================
 //function : GEOMImpl_GlueDriver
@@ -31,6 +40,119 @@ const Standard_GUID& GEOMImpl_GlueDriver::GetID()
   return aGlueDriver;
 }
 
+//=======================================================================
+//function : GlueFacesWithWarnings
+//purpose  :
+//=======================================================================
+TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesWithWarnings (const TopoDS_Shape& theShape,
+                                                         const Standard_Real theTolerance,
+                                                         TCollection_AsciiString& theWarning) const
+{
+  Standard_Integer iErr, iWrn;
+  TopoDS_Shape aRes;
+  GEOMAlgo_Gluer aGluer;
+
+  aGluer.SetShape(theShape);
+  aGluer.SetTolerance(theTolerance);
+  aGluer.SetCheckGeometry(Standard_True);
+
+  aGluer.Perform();
+
+  iErr = aGluer.ErrorStatus();
+  if (iErr) {
+    switch (iErr) {
+    case 2:
+      Standard_Failure::Raise("No vertices found in source shape");
+      break;
+    case 5:
+      Standard_Failure::Raise("Source shape is Null");
+      break;
+    case 6:
+      Standard_Failure::Raise("Result shape is Null");
+      break;
+    case 200:
+      Standard_Failure::Raise("Error occured during check of geometric coincidence");
+      break;
+    default:
+      {
+        // description of all errors see in GEOMAlgo_Gluer.cxx
+        TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer with code ");
+        aMsg += TCollection_AsciiString(iErr);
+        Standard_Failure::Raise(aMsg.ToCString());
+        break;
+      }
+    }
+    return aRes;
+  }
+
+  iWrn = aGluer.WarningStatus();
+  if (iWrn) {
+    switch (iWrn) {
+    case 1:
+      {
+        Standard_Integer nbAlone = aGluer.AloneShapes();
+        theWarning = TCollection_AsciiString(nbAlone);
+        theWarning += " solid(s) can not be glued by faces";
+      }
+      break;
+    default:
+      // description of all warnings see in GEOMAlgo_Gluer.cxx
+      theWarning = "Warning in GEOMAlgo_Gluer with code ";
+      theWarning += TCollection_AsciiString(iWrn);
+      break;
+    }
+  }
+
+  aRes = aGluer.Result();
+
+  // Fill history to be used by GetInPlace functionality
+  TopTools_IndexedMapOfShape aResIndices;
+  TopExp::MapShapes(aRes, aResIndices);
+
+  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
+
+  // history for all argument shapes
+  TDF_LabelSequence aLabelSeq;
+  aFunction->GetDependency(aLabelSeq);
+  Standard_Integer nbArg = aLabelSeq.Length();
+
+  for (Standard_Integer iarg = 1; iarg <= nbArg; iarg++) {
+
+    TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
+
+    Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
+    TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
+
+    TopTools_IndexedMapOfShape anArgumentIndices;
+    TopExp::MapShapes(anArgumentShape, anArgumentIndices);
+    Standard_Integer nbArgumentEntities = anArgumentIndices.Extent();
+
+    // Find corresponding label in history
+    TDF_Label anArgumentHistoryLabel =
+      aFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_True);
+
+    for (Standard_Integer ie = 1; ie <= nbArgumentEntities; ie++) {
+      TopoDS_Shape anEntity = anArgumentIndices.FindKey(ie);
+      const TopTools_ListOfShape& aModified = aGluer.Modified(anEntity);
+      Standard_Integer nbModified = aModified.Extent();
+
+      if (nbModified > 0) {
+        TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(ie, Standard_True);
+        Handle(TDataStd_IntegerArray) anAttr =
+          TDataStd_IntegerArray::Set(aWhatHistoryLabel, 1, nbModified);
+
+        TopTools_ListIteratorOfListOfShape itM (aModified);
+        for (int im = 1; itM.More(); itM.Next(), ++im) {
+          int id = aResIndices.FindIndex(itM.Value());
+          anAttr->SetValue(im, id);
+        }
+      }
+    }
+  }
+
+  return aRes;
+}
+
 //=======================================================================
 //function : GlueFaces
 //purpose  :
@@ -106,6 +228,7 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
   Standard_Integer aType = aFunction->GetType();
 
   TopoDS_Shape aShape;
+  TCollection_AsciiString aWrn;
 
   if (aType == GLUE_FACES) {
     Handle(GEOM_Function) aRefBase = aCI.GetBase();
@@ -115,7 +238,7 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
     }
 
     Standard_Real tol3d = aCI.GetTolerance();
-    aShape = GlueFaces(aShapeBase, tol3d);
+    aShape = GlueFacesWithWarnings(aShapeBase, tol3d, aWrn);
   } else {
   }
 
@@ -125,6 +248,10 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
 
   log.SetTouched(Label());
 
+  if (!aWrn.IsEmpty()) {
+    Standard_Failure::Raise(aWrn.ToCString());
+  }
+
   return 1;
 }