Salome HOME
0022661: EDF GEOM: [HYDRO] Integration of the polyline editor in GEOM
[modules/geom.git] / src / GEOMImpl / GEOMImpl_PolylineDriver.cxx
index 1eeeaf27763596f0b065a3d9b3bef95f5be62406..1a996c1e514e19efea9155654dabffed4258a108 100644 (file)
 #include "GEOMImpl_PolylineDriver.hxx"
 
 #include "GEOMImpl_ICurveParametric.hxx"
+#include "GEOMImpl_ICurvesOperations.hxx"
 #include "GEOMImpl_IPolyline.hxx"
+#include "GEOMImpl_IPolyline2D.hxx"
 #include "GEOMImpl_Types.hxx"
 #include "GEOM_Function.hxx"
+#include <GEOMUtils.hxx>
+#include <Sketcher_Utils.hxx>
 
 #include <BRepBuilderAPI_MakePolygon.hxx>
 #include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 #include <Precision.hxx>
 #include <TColgp_Array1OfPnt.hxx>
@@ -38,6 +43,7 @@
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
+#include <gp_Ax3.hxx>
 #include <gp_Pnt.hxx>
 
 //=======================================================================
@@ -59,6 +65,125 @@ GEOMImpl_PolylineDriver::GEOMImpl_PolylineDriver()
 {
 }
 
+//=======================================================================
+//function : MakePolyline2D
+//purpose  :
+//======================================================================= 
+Standard_Integer GEOMImpl_PolylineDriver::MakePolyline2D
+                      (TFunction_Logbook& log) const
+{
+  if (Label().IsNull()) {
+    return 0;
+  }
+
+  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
+  GEOMImpl_IPolyline2D  aCI(aFunction);
+  Standard_Integer      aType = aFunction->GetType();
+  TopoDS_Shape          aShape;
+
+  // Get data.
+  Handle(TColStd_HArray1OfExtendedString) aNames       = aCI.GetNames();
+  Handle(TColStd_HArray1OfByte)           aTypes       = aCI.GetTypes();
+  Handle(TColStd_HArray1OfByte)           aClosedFlags = aCI.GetClosedFlags();
+  std::list <std::list <double> >         aCoords;
+  gp_Ax3                                  aWPlane;
+
+  aCI.GetCoords(aCoords);
+
+  // Check the data validity
+  if (aNames.IsNull()) {
+    return 0;
+  }
+
+  Standard_Integer aNbSections = aNames->Length();
+
+  if (aTypes.IsNull() || aNbSections != aTypes->Length()) {
+    return 0;
+  }
+
+  if (aClosedFlags.IsNull() || aNbSections != aClosedFlags->Length()) {
+    return 0;
+  }
+
+  if (aNbSections != aCoords.size()) {
+    return 0;
+  }
+
+  if (aType == POLYLINE2D_PLN_COORDS) {
+    Handle(TColStd_HArray1OfReal) aPlaneCoords = aCI.GetWorkingPlaneDbls();
+
+    if (aPlaneCoords.IsNull()) {
+      return 0;
+    }
+
+    if (aPlaneCoords->Length() != 9) {
+      return 0;
+    }
+
+    Standard_Integer i = aPlaneCoords->Lower();
+    gp_Pnt aOrigin(aPlaneCoords->Value(i), aPlaneCoords->Value(i + 1),
+                 aPlaneCoords->Value(i + 2));
+    gp_Dir aDirZ(aPlaneCoords->Value(i + 3), aPlaneCoords->Value(i + 4),
+                 aPlaneCoords->Value(i + 5));
+    gp_Dir aDirX(aPlaneCoords->Value(i + 6), aPlaneCoords->Value(i + 7),
+                 aPlaneCoords->Value(i + 8));
+    aWPlane = gp_Ax3(aOrigin, aDirZ, aDirX);
+  } else if (aType == POLYLINE2D_PLN_OBJECT) {
+    Handle(GEOM_Function) aRefFace = aCI.GetWorkingPlane();
+    TopoDS_Shape aShape = aRefFace->GetValue();
+
+    aWPlane = GEOMUtils::GetPosition(aShape);
+  } else {
+    return 0;
+  }
+
+  // Construct a shape.
+  Standard_Integer iN = aNames->Lower();
+  Standard_Integer iT = aTypes->Lower();
+  Standard_Integer iC = aClosedFlags->Lower();
+  std::list <std::list <double> >::const_iterator anIter = aCoords.begin();
+  BRep_Builder aBuilder;
+  Standard_Boolean isEmpty = Standard_True;
+
+  if (aNbSections > 1) {
+    aBuilder.MakeCompound(TopoDS::Compound(aShape));
+  }
+
+  for (; anIter != aCoords.end(); ++anIter, ++iN, ++iT, ++iC) {
+    Standard_Integer aType = aTypes->Value(iT);
+    TopoDS_Shape     aSection;
+
+    if (aType == GEOMImpl_ICurvesOperations::Polyline) {
+      aSection = Sketcher_Utils::MakePolyline
+          (*anIter, aClosedFlags->Value(iC), aWPlane);
+    } else if (aType == GEOMImpl_ICurvesOperations::Interpolation) {
+      aSection = Sketcher_Utils::MakeInterpolation
+        (*anIter, aClosedFlags->Value(iC), aWPlane);
+    }
+
+    if (aNbSections > 1) {
+      // There are multiple sections.
+      if (aSection.IsNull() == Standard_False) {
+        aBuilder.Add(aShape, aSection);
+        isEmpty = Standard_False;
+      }
+    } else {
+      // There is only one section.
+      isEmpty = aSection.IsNull();
+      aShape  = aSection;
+    }
+  }
+
+  if (isEmpty) {
+    return 0;
+  }
+
+  aFunction->SetValue(aShape);
+  log.SetTouched(Label()); 
+
+  return 1;
+}
+
 //=======================================================================
 //function : Execute
 //purpose  :
@@ -67,9 +192,13 @@ Standard_Integer GEOMImpl_PolylineDriver::Execute(TFunction_Logbook& log) const
 {
   if (Label().IsNull()) return 0;    
   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
+  Standard_Integer aType = aFunction->GetType();
+
+  if (aType == POLYLINE2D_PLN_COORDS || aType == POLYLINE2D_PLN_OBJECT) {
+    return MakePolyline2D(log);
+  }
 
   GEOMImpl_IPolyline aCI (aFunction);
-  Standard_Integer aType = aFunction->GetType();
   
   TopoDS_Shape aShape;
 
@@ -166,10 +295,9 @@ GetCreationInformation(std::string&             theOperationName,
   GEOMImpl_ICurveParametric aIP( function );
   Standard_Integer aType = function->GetType();
 
-  theOperationName = "CURVE";
-
   switch ( aType ) {
   case POLYLINE_POINTS:
+    theOperationName = "CURVE";
     AddParam( theParams, "Type", "Polyline");
     if ( aIP.HasData() )
     {
@@ -206,6 +334,103 @@ GetCreationInformation(std::string&             theOperationName,
       AddParam( theParams, "Is closed", aCI.GetIsClosed() );
     }
     break;
+  case POLYLINE2D_PLN_COORDS:
+  case POLYLINE2D_PLN_OBJECT:
+    {
+      theOperationName = "SKETCH";
+
+      GEOMImpl_IPolyline2D                    aP2d(function);
+      Handle(TColStd_HArray1OfExtendedString) aNames = aP2d.GetNames();
+
+      if (aNames.IsNull() == Standard_False) {
+        if (aNames->Length() == 1) {
+          // This is the single curve. Make its full dump.
+          AddParam(theParams, "Name", aNames->Value(aNames->Lower()));
+
+          Handle(TColStd_HArray1OfByte) aTypes = aP2d.GetTypes();
+
+          if (aTypes.IsNull() == Standard_False && aTypes->Length() == 1) {
+            Standard_Integer aType = aTypes->Value(aTypes->Lower());
+
+            if (aType == GEOMImpl_ICurvesOperations::Polyline) {
+              AddParam(theParams, "Type") << "Polyline";
+            } else if (aType == GEOMImpl_ICurvesOperations::Interpolation) {
+              AddParam(theParams, "Type") << "Interpolation";
+            }
+          }
+
+          Handle(TColStd_HArray1OfByte) aCloseds = aP2d.GetClosedFlags();
+
+          if (aCloseds.IsNull() == Standard_False && aCloseds->Length() == 1) {
+            const char *aYesNo =
+              aCloseds->Value(aCloseds->Lower()) ? "Yes" : "No";
+
+            AddParam(theParams, "Is closed", aYesNo);
+          }
+
+          std::list <std::list <double> > aCoords;
+
+          aP2d.GetCoords(aCoords);
+
+          if (aCoords.size() == 1) {
+            AddParam(theParams, "Number of points", aCoords.front().size()/2);
+          }
+        } else {
+          // There are more than 1 curve.
+          Standard_Integer                aNbCurves = aNames->Length();
+          Standard_Integer                i;
+          std::list <std::list <double> > aCoords;
+
+          AddParam(theParams, "Number of curves", aNbCurves);
+          aP2d.GetCoords(aCoords);
+
+          Standard_Integer aNbCoords = aCoords.size();
+          std::list <std::list <double> >::const_iterator
+                           anIt      = aCoords.begin();
+
+          for (i = 0; i < aNbCurves; i++) {
+            TCollection_AsciiString aName("Curve ");
+            TCollection_ExtendedString
+              aValue(aNames->Value(aNames->Lower() + i));
+
+            aName.AssignCat(i + 1);
+
+            if (anIt != aCoords.end()) {
+              aValue.AssignCat(" (");
+              aValue.AssignCat(Standard_Integer(anIt->size()));
+              aValue.AssignCat(" points)");
+              anIt++;
+            }
+
+            AddParam(theParams, aName.ToCString(), aValue);
+          }
+        }
+      }
+
+      if (aType == POLYLINE2D_PLN_COORDS) {
+        Handle(TColStd_HArray1OfReal) aPln = aP2d.GetWorkingPlaneDbls();
+
+        if (aPln.IsNull() == Standard_False && aPln->Length() == 9) {
+          Standard_Integer i = aPln->Lower();
+
+          AddParam( theParams, "Origin")
+            << aPln->Value(i)     << " "
+            << aPln->Value(i + 1) << " "
+            << aPln->Value(i + 2);
+          AddParam( theParams, "OZ")
+            << aPln->Value(i + 3) << " "
+            << aPln->Value(i + 4) << " "
+            << aPln->Value(i + 5);
+          AddParam( theParams, "OX")
+            << aPln->Value(i + 6) << " "
+            << aPln->Value(i + 7) << " "
+            << aPln->Value(i + 8);
+        }
+      } else {
+        AddParam(theParams, "Working plane", aP2d.GetWorkingPlane(), "XOY");
+      }
+    }
+    break;
   default:
     return false;
   }