Salome HOME
Import profiles protection (Bug #203).
[modules/hydro.git] / src / HYDROData / HYDROData_BSplineOperation.cxx
1
2 #include <HYDROData_BSplineOperation.h>
3
4 #include <TColgp_HArray1OfPnt.hxx>
5
6 #include <GeomAPI_Interpolate.hxx>
7 #include <GeomConvert_BSplineCurveToBezierCurve.hxx>
8 #include <Geom_BezierCurve.hxx>
9
10 #include <QPainterPath>
11
12 HYDROData_BSplineOperation::HYDROData_BSplineOperation(
13   const NCollection_Sequence<gp_XYZ>& thePoints,
14   const bool                          theIsClosed,
15   const double                        theTolerance )
16 {
17   // skip equal points
18   int aNbPoints = thePoints.Size();
19   NCollection_Sequence<gp_XYZ> aPoints;
20   if ( aNbPoints > 0 ) {
21     gp_XYZ aPrevPoint = thePoints.Value( 1 );
22     aPoints.Append( aPrevPoint );
23     for( int i = 2 ; i <= aNbPoints; ++i )
24     {
25       gp_XYZ aPoint( thePoints.Value( i ) );
26       if ( !aPoint.IsEqual( aPrevPoint, theTolerance ) )
27         aPoints.Append( aPoint );
28       aPrevPoint = aPoint;
29     }
30   }
31
32   // fill array for algorithm by the received coordinates
33   aNbPoints = aPoints.Size();
34   Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt( 1, aNbPoints );
35   for ( int i = 1; i <= aNbPoints; i++ )
36   {
37     gp_Pnt aPnt( aPoints.Value( i ) );
38     aHCurvePoints->SetValue( i, aPnt );
39   }
40
41   // compute BSpline
42   GeomAPI_Interpolate aGBC( aHCurvePoints, theIsClosed, gp::Resolution() );
43   aGBC.Perform();
44   if ( aGBC.IsDone() )
45     myCurve = aGBC.Curve();
46 }
47
48 void HYDROData_BSplineOperation::ComputePath( QPainterPath& thePath ) const
49 {
50   if ( myCurve.IsNull() ) // returns an empty Path if original curve is invalid
51     return;
52
53   GeomConvert_BSplineCurveToBezierCurve aConverter(myCurve);
54   int a, aNumArcs = aConverter.NbArcs();
55   for(a = 1; a <= aNumArcs; a++)
56   {
57     Handle(Geom_BezierCurve) anArc = aConverter.Arc(a);
58     if (a == 1) { // set a start point
59       gp_Pnt aStart = anArc->StartPoint();
60       thePath.moveTo(aStart.X(), aStart.Y());
61     }
62     gp_Pnt anEnd = anArc->EndPoint();
63     if (anArc->NbPoles() == 3) { // quadric segment in the path (pole 1 is start, pole 3 is end)
64       gp_Pnt aPole = anArc->Pole(2);
65       thePath.quadTo(aPole.X(), aPole.Y(), anEnd.X(), anEnd.Y());
66     } else if (anArc->NbPoles() == 4) { // cubic segment (usually this is used)
67       gp_Pnt aPole1 = anArc->Pole(2);
68       gp_Pnt aPole2 = anArc->Pole(3);
69       thePath.cubicTo(
70         aPole1.X(), aPole1.Y(), aPole2.X(), aPole2.Y(), anEnd.X(), anEnd.Y());
71     } else { // error, another number of poles is not supported
72       continue;
73     }
74   }
75 }