]> SALOME platform Git repositories - modules/shaper.git/blobdiff - src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp
Salome HOME
updated copyright message
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_Tools.cpp
index c1b83d3f85865e04de66ee6297fe9b888df37627..1645e73f897c244016d425a6b91d1bc989f2b2ac 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,9 @@
 
 #include <PlaneGCSSolver_Tools.h>
 #include <PlaneGCSSolver_EdgeWrapper.h>
+#include <PlaneGCSSolver_PointArrayWrapper.h>
 #include <PlaneGCSSolver_PointWrapper.h>
+#include <PlaneGCSSolver_ScalarArrayWrapper.h>
 #include <PlaneGCSSolver_ScalarWrapper.h>
 #include <PlaneGCSSolver_ConstraintWrapper.h>
 
 #include <SketchSolver_ConstraintTangent.h>
 #include <SketchSolver_ConstraintMultiRotation.h>
 #include <SketchSolver_ConstraintMultiTranslation.h>
+#include <SketchSolver_ConstraintOffset.h>
 
+#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_BSpline.h>
+#include <SketchPlugin_BSplinePeriodic.h>
+#include <SketchPlugin_Circle.h>
 #include <SketchPlugin_ConstraintAngle.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintCollinear.h>
 #include <SketchPlugin_ConstraintRigid.h>
 #include <SketchPlugin_ConstraintPerpendicular.h>
 #include <SketchPlugin_ConstraintTangent.h>
+#include <SketchPlugin_Ellipse.h>
+#include <SketchPlugin_EllipticArc.h>
 #include <SketchPlugin_Line.h>
 #include <SketchPlugin_MultiRotation.h>
 #include <SketchPlugin_MultiTranslation.h>
+#include <SketchPlugin_Offset.h>
+#include <SketchPlugin_Point.h>
 
+#include <GeomAPI_BSpline2d.h>
 #include <GeomAPI_Circ2d.h>
 #include <GeomAPI_Dir2d.h>
 #include <GeomAPI_Ellipse2d.h>
 #include <GeomAPI_Lin2d.h>
 #include <GeomAPI_Pnt2d.h>
 
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelAPI_AttributeIntArray.h>
+
 #include <cmath>
 
 
@@ -77,7 +92,8 @@ static ConstraintWrapperPtr
 static ConstraintWrapperPtr
   createConstraintPointOnEntity(const SketchSolver_ConstraintType& theType,
                                 std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
-                                std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity);
+                                std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity,
+                                std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue);
 static ConstraintWrapperPtr
   createConstraintPointsCollinear(std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint1,
                                   std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint2,
@@ -128,15 +144,15 @@ static ConstraintWrapperPtr
                                      std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2);
 
 static GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar);
+static GCS::SET_pD scalarArrayParameters(const EntityWrapperPtr& theArray);
 static GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint);
+static GCS::SET_pD pointArrayParameters(const EntityWrapperPtr& theArray);
 static GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine);
 static GCS::SET_pD circleParameters(const EdgeWrapperPtr& theCircle);
 static GCS::SET_pD arcParameters(const EdgeWrapperPtr& theArc);
 static GCS::SET_pD ellipseParameters(const EdgeWrapperPtr& theEllipse);
 static GCS::SET_pD ellipticArcParameters(const EdgeWrapperPtr& theEllipticArc);
-
-static double distance(const GCS::Point& thePnt1, const GCS::Point& thePnt2);
-
+static GCS::SET_pD bsplineParameters(const EdgeWrapperPtr& theEdge);
 
 
 
@@ -172,6 +188,8 @@ SolverConstraintPtr PlaneGCSSolver_Tools::createConstraint(ConstraintPtr theCons
     return SolverConstraintPtr(new SketchSolver_ConstraintAngle(theConstraint));
   } else if (theConstraint->getKind() == SketchPlugin_ConstraintPerpendicular::ID()) {
     return SolverConstraintPtr(new SketchSolver_ConstraintPerpendicular(theConstraint));
+  } else if (theConstraint->getKind() == SketchPlugin_Offset::ID()) {
+    return SolverConstraintPtr(new SketchSolver_ConstraintOffset(theConstraint));
   }
   // All other types of constraints
   return SolverConstraintPtr(new SketchSolver_Constraint(theConstraint));
@@ -221,8 +239,9 @@ ConstraintWrapperPtr PlaneGCSSolver_Tools::createConstraint(
     aResult = createConstraintCoincidence(aPoint1, aPoint2);
     break;
   case CONSTRAINT_PT_ON_CURVE:
-    aResult = anEntity1 ? createConstraintPointOnEntity(theType, aPoint1, anEntity1):
-              createConstraintPointsCollinear(aPoint1, aPoint2, GCS_POINT_WRAPPER(theEntity1));
+    aResult = anEntity1 ?
+        createConstraintPointOnEntity(theType, aPoint1, anEntity1, GCS_SCALAR_WRAPPER(theValue)) :
+        createConstraintPointsCollinear(aPoint1, aPoint2, GCS_POINT_WRAPPER(theEntity1));
     break;
   case CONSTRAINT_MIDDLE_POINT:
     aResult = createConstraintMiddlePoint(aPoint1, GCS_EDGE_WRAPPER(theEntity1), aPoint2);
@@ -348,6 +367,37 @@ std::shared_ptr<GeomAPI_Ellipse2d> PlaneGCSSolver_Tools::ellipse(EntityWrapperPt
       new GeomAPI_Ellipse2d(aCenter, anAxis, anEllipse->getRadMaj(), *anEllipse->radmin));
 }
 
+std::shared_ptr<GeomAPI_BSpline2d> PlaneGCSSolver_Tools::bspline(EntityWrapperPtr theEntity)
+{
+  if (theEntity->type() != ENTITY_BSPLINE)
+    return std::shared_ptr<GeomAPI_BSpline2d>();
+
+  std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
+      std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
+  std::shared_ptr<GCS::BSpline> aSpline =
+      std::dynamic_pointer_cast<GCS::BSpline>(anEntity->entity());
+
+  std::list<GeomPnt2dPtr> aPoles;
+  for (GCS::VEC_P::iterator anIt = aSpline->poles.begin(); anIt != aSpline->poles.end(); ++anIt)
+    aPoles.push_back(GeomPnt2dPtr(new GeomAPI_Pnt2d(*anIt->x, *anIt->y)));
+
+  std::list<double> aWeights;
+  for (GCS::VEC_pD::iterator anIt = aSpline->weights.begin();
+       anIt != aSpline->weights.end(); ++anIt)
+    aWeights.push_back(**anIt);
+
+  std::list<double> aKnots;
+  for (GCS::VEC_pD::iterator anIt = aSpline->knots.begin(); anIt != aSpline->knots.end(); ++anIt)
+    aKnots.push_back(**anIt);
+
+  std::list<int> aMultiplicities;
+  aMultiplicities.assign(aSpline->mult.begin(), aSpline->mult.end());
+
+  return std::shared_ptr<GeomAPI_BSpline2d>(
+         new GeomAPI_BSpline2d(aSpline->degree, aPoles, aWeights,
+                               aKnots, aMultiplicities, aSpline->periodic));
+}
+
 void PlaneGCSSolver_Tools::recalculateArcParameters(EntityWrapperPtr theArc)
 {
   std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEdge =
@@ -396,8 +446,12 @@ GCS::SET_pD PlaneGCSSolver_Tools::parameters(const EntityWrapperPtr& theEntity)
   case ENTITY_SCALAR:
   case ENTITY_ANGLE:
     return scalarParameters(GCS_SCALAR_WRAPPER(theEntity));
+  case ENTITY_SCALAR_ARRAY:
+    return scalarArrayParameters(theEntity);
   case ENTITY_POINT:
     return pointParameters(GCS_POINT_WRAPPER(theEntity));
+  case ENTITY_POINT_ARRAY:
+    return pointArrayParameters(theEntity);
   case ENTITY_LINE:
     return lineParameters(GCS_EDGE_WRAPPER(theEntity));
   case ENTITY_CIRCLE:
@@ -408,11 +462,119 @@ GCS::SET_pD PlaneGCSSolver_Tools::parameters(const EntityWrapperPtr& theEntity)
     return ellipseParameters(GCS_EDGE_WRAPPER(theEntity));
   case ENTITY_ELLIPTIC_ARC:
     return ellipticArcParameters(GCS_EDGE_WRAPPER(theEntity));
+  case ENTITY_BSPLINE:
+    return bsplineParameters(GCS_EDGE_WRAPPER(theEntity));
   default: break;
   }
   return GCS::SET_pD();
 }
 
+bool PlaneGCSSolver_Tools::isAttributeApplicable(const std::string& theAttrName,
+                                                 const std::string& theOwnerName)
+{
+  if (theOwnerName == SketchPlugin_Arc::ID()) {
+    return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
+           theAttrName == SketchPlugin_Arc::START_ID() ||
+           theAttrName == SketchPlugin_Arc::END_ID() ||
+           theAttrName == SketchPlugin_Arc::REVERSED_ID();
+  }
+  else if (theOwnerName == SketchPlugin_Circle::ID()) {
+    return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
+           theAttrName == SketchPlugin_Circle::RADIUS_ID();
+  }
+  else if (theOwnerName == SketchPlugin_Line::ID()) {
+    return theAttrName == SketchPlugin_Line::START_ID() ||
+           theAttrName == SketchPlugin_Line::END_ID();
+  }
+  else if (theOwnerName == SketchPlugin_Ellipse::ID()) {
+    return theAttrName == SketchPlugin_Ellipse::CENTER_ID() ||
+           theAttrName == SketchPlugin_Ellipse::FIRST_FOCUS_ID() ||
+           theAttrName == SketchPlugin_Ellipse::SECOND_FOCUS_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_END_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_START_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_END_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MAJOR_RADIUS_ID() ||
+           theAttrName == SketchPlugin_Ellipse::MINOR_RADIUS_ID();
+  }
+  else if (theOwnerName == SketchPlugin_EllipticArc::ID()) {
+    return theAttrName == SketchPlugin_EllipticArc::CENTER_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::FIRST_FOCUS_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::SECOND_FOCUS_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_START_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_END_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MAJOR_RADIUS_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::MINOR_RADIUS_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::START_POINT_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::END_POINT_ID() ||
+           theAttrName == SketchPlugin_EllipticArc::REVERSED_ID();
+  }
+  else if (theOwnerName == SketchPlugin_BSpline::ID()) {
+    return theAttrName == SketchPlugin_BSpline::POLES_ID() ||
+           theAttrName == SketchPlugin_BSpline::WEIGHTS_ID() ||
+           theAttrName == SketchPlugin_BSpline::KNOTS_ID() ||
+           theAttrName == SketchPlugin_BSpline::MULTS_ID() ||
+           theAttrName == SketchPlugin_BSpline::DEGREE_ID() ||
+           theAttrName == SketchPlugin_BSpline::START_ID() ||
+           theAttrName == SketchPlugin_BSpline::END_ID();
+  }
+  else if (theOwnerName == SketchPlugin_BSplinePeriodic::ID()) {
+    return theAttrName == SketchPlugin_BSplinePeriodic::POLES_ID() ||
+           theAttrName == SketchPlugin_BSplinePeriodic::WEIGHTS_ID() ||
+           theAttrName == SketchPlugin_BSplinePeriodic::KNOTS_ID() ||
+           theAttrName == SketchPlugin_BSplinePeriodic::MULTS_ID() ||
+           theAttrName == SketchPlugin_BSplinePeriodic::DEGREE_ID();
+  }
+
+  // suppose that all remaining features are points
+  return theAttrName == SketchPlugin_Point::COORD_ID();
+}
+
+/// \brief Update value
+bool PlaneGCSSolver_Tools::updateValue(const double& theSource, double& theDest,
+                                       const double theTolerance)
+{
+  bool isUpdated = fabs(theSource - theDest) > theTolerance;
+  if (isUpdated)
+    theDest = theSource;
+  return isUpdated;
+}
+
+
+double PlaneGCSSolver_Tools::distance(const GCS::Point& thePnt1, const GCS::Point& thePnt2)
+{
+  double x = *thePnt1.x - *thePnt2.x;
+  double y = *thePnt1.y - *thePnt2.y;
+  return sqrt(x*x + y*y);
+}
+
+
+
+
+// ================   AttributeArray methods   ==========================
+PlaneGCSSolver_Tools::AttributeArray::AttributeArray(AttributePtr theAttribute)
+{
+  myDouble = std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(theAttribute);
+  myInteger = std::dynamic_pointer_cast<ModelAPI_AttributeIntArray>(theAttribute);
+}
+
+bool PlaneGCSSolver_Tools::AttributeArray::isInitialized() const
+{
+  return (myDouble && myDouble->isInitialized()) || (myInteger && myInteger->isInitialized());
+}
+
+int PlaneGCSSolver_Tools::AttributeArray::size() const
+{
+  return myDouble.get() ? myDouble->size() : myInteger->size();
+}
+
+double PlaneGCSSolver_Tools::AttributeArray::value(const int theIndex) const
+{
+  return myDouble.get() ? myDouble->value(theIndex) : myInteger->value(theIndex);
+}
+
 
 
 
@@ -440,7 +602,8 @@ ConstraintWrapperPtr createConstraintCoincidence(
 ConstraintWrapperPtr createConstraintPointOnEntity(
     const SketchSolver_ConstraintType& theType,
     std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
-    std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity)
+    std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity,
+    std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue)
 {
   GCSConstraintPtr aNewConstr;
 
@@ -466,6 +629,14 @@ ConstraintWrapperPtr createConstraintPointOnEntity(
         new GCS::ConstraintPointOnEllipse(*(thePoint->point()), *anEllipse));
     break;
     }
+  case ENTITY_BSPLINE: {
+    std::list<GCSConstraintPtr> aConstraints;
+    aConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintCurveValue(
+        *thePoint->point(), thePoint->point()->x, *theEntity->entity(), theValue->scalar())));
+    aConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintCurveValue(
+        *thePoint->point(), thePoint->point()->y, *theEntity->entity(), theValue->scalar())));
+    return ConstraintWrapperPtr(new PlaneGCSSolver_ConstraintWrapper(aConstraints, theType));
+  }
   default:
     return ConstraintWrapperPtr();
   }
@@ -705,7 +876,7 @@ ConstraintWrapperPtr createConstraintEqual(
     aConstrList.push_back(GCSConstraintPtr(
         new GCS::ConstraintP2PDistance(aLine2->p1, aLine2->p2, theIntermed->scalar())));
     // update value of intermediate parameter
-    theIntermed->setValue(distance(aLine1->p1, aLine1->p2));
+    theIntermed->setValue(PlaneGCSSolver_Tools::distance(aLine1->p1, aLine1->p2));
   }
   else if (theType == CONSTRAINT_EQUAL_ELLIPSES) {
     std::shared_ptr<GCS::Ellipse> anEllipse1 =
@@ -720,7 +891,7 @@ ConstraintWrapperPtr createConstraintEqual(
     aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
         anEllipse2->center, anEllipse2->focus1, theIntermed->scalar())));
     // update value of intermediate parameter
-    theIntermed->setValue(distance(anEllipse1->center, anEllipse1->focus1));
+    theIntermed->setValue(PlaneGCSSolver_Tools::distance(anEllipse1->center, anEllipse1->focus1));
   }
   else {
     std::shared_ptr<GCS::Circle> aCirc1 =
@@ -744,6 +915,13 @@ GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar)
   return aParams;
 }
 
+GCS::SET_pD scalarArrayParameters(const EntityWrapperPtr& theArray)
+{
+  ScalarArrayWrapperPtr anArray =
+      std::dynamic_pointer_cast<PlaneGCSSolver_ScalarArrayWrapper>(theArray);
+  return GCS::SET_pD(anArray->array().begin(), anArray->array().end());
+}
+
 GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint)
 {
   GCS::SET_pD aParams;
@@ -752,6 +930,19 @@ GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint)
   return aParams;
 }
 
+GCS::SET_pD pointArrayParameters(const EntityWrapperPtr& theArray)
+{
+  GCS::SET_pD aParams;
+  PointArrayWrapperPtr aPoints =
+      std::dynamic_pointer_cast<PlaneGCSSolver_PointArrayWrapper>(theArray);
+  for (std::vector<PointWrapperPtr>::const_iterator anIt = aPoints->array().begin();
+       anIt != aPoints->array().end(); ++anIt) {
+    GCS::SET_pD aPointParams = PlaneGCSSolver_Tools::parameters(*anIt);
+    aParams.insert(aPointParams.begin(), aPointParams.end());
+  }
+  return aParams;
+}
+
 GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine)
 {
   GCS::SET_pD aParams;
@@ -813,9 +1004,19 @@ GCS::SET_pD ellipticArcParameters(const EdgeWrapperPtr& theEllipticArc)
   return aParams;
 }
 
-double distance(const GCS::Point& thePnt1, const GCS::Point& thePnt2)
+GCS::SET_pD bsplineParameters(const EdgeWrapperPtr& theEdge)
 {
-  double x = *thePnt1.x - *thePnt2.x;
-  double y = *thePnt1.y - *thePnt2.y;
-  return sqrt(x*x + y*y);
+  GCS::SET_pD aParams;
+
+  std::shared_ptr<GCS::BSpline> aBSpline =
+    std::dynamic_pointer_cast<GCS::BSpline>(theEdge->entity());
+
+  for (GCS::VEC_P::iterator it = aBSpline->poles.begin(); it != aBSpline->poles.end(); ++it) {
+    aParams.insert(it->x);
+    aParams.insert(it->y);
+  }
+  for (GCS::VEC_pD::iterator it = aBSpline->weights.begin(); it != aBSpline->weights.end(); ++it)
+    aParams.insert(*it);
+
+  return aParams;
 }