0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / ShapeUpgrade / ShapeUpgrade.cxx
1 // Created on: 1998-11-12
2 // Created by: data exchange team
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //    abv 24.05.99 S4174: methods Debug() commented
18
19 #include <BSplCLib.hxx>
20 #include <Geom2d_BSplineCurve.hxx>
21 #include <Geom_BSplineCurve.hxx>
22 #include <ShapeUpgrade.hxx>
23 #include <TColgp_Array1OfPnt.hxx>
24 #include <TColStd_Array1OfInteger.hxx>
25 #include <TColStd_Array1OfReal.hxx>
26
27 /*
28 // Debug state= True / False.
29 static Standard_Boolean Dbg=Standard_False;
30 void ShapeUpgrade::SetDebug(const Standard_Boolean State) 
31 {
32   Dbg=State;
33 }
34 Standard_Boolean ShapeUpgrade::Debug() 
35 {
36   return Dbg;
37 }
38 */
39 //=======================================================================
40 //function : C0BSplineToSequenceOfC1BSplineCurve
41 //purpose  : 
42 //=======================================================================
43  Standard_Boolean ShapeUpgrade::C0BSplineToSequenceOfC1BSplineCurve(const Handle(Geom_BSplineCurve)& BS,
44                                                                     Handle(TColGeom_HSequenceOfBoundedCurve)& seqBS) 
45 {
46   if (BS.IsNull() || (BS->IsCN (1))) return Standard_False;
47   
48   seqBS = new TColGeom_HSequenceOfBoundedCurve;
49   BS->SetNotPeriodic(); //to have equation NbPoles = NbKnots with Multiplicities - degree - 1
50   
51   Standard_Integer deg     = BS->Degree();
52   Standard_Integer NbKnots = BS->NbKnots();
53   Standard_Integer NbPoles = BS->NbPoles();
54   TColgp_Array1OfPnt      Poles        (1, NbPoles);
55   TColStd_Array1OfReal    Weights      (1, NbPoles);
56   TColStd_Array1OfReal    Knots        (1, NbKnots);
57   TColStd_Array1OfInteger Mults        (1, NbKnots);
58   TColStd_Array1OfReal    KnotSequence (1, NbPoles + deg + 1);
59
60   BS->Poles(Poles);
61   if (BS->IsRational())
62     BS->Weights(Weights);
63   else
64     Weights.Init(1.);
65   BS->Knots(Knots);
66   BS->Multiplicities(Mults);
67   BS->KnotSequence (KnotSequence);
68         
69   Standard_Integer StartKnotIndex, EndKnotIndex, j;
70
71   StartKnotIndex = BS->FirstUKnotIndex();
72   for ( EndKnotIndex = StartKnotIndex + 1; EndKnotIndex <= BS->LastUKnotIndex(); EndKnotIndex++ ) {
73     if ( ( Mults (EndKnotIndex) < deg ) && ( EndKnotIndex < BS->LastUKnotIndex() ) ) continue;
74
75     Standard_Integer StartFlatIndex = BSplCLib::FlatIndex (deg, StartKnotIndex, Mults, Standard_False);
76 //    StartFlatIndex += Mults (StartKnotIndex) - 1;
77     Standard_Integer EndFlatIndex   = BSplCLib::FlatIndex (deg, EndKnotIndex,   Mults, Standard_False);
78     EndFlatIndex -= Mults (EndKnotIndex) - 1;
79
80     TColStd_Array1OfReal    TempKnots (1, NbKnots);
81     TColStd_Array1OfInteger TempMults (1, NbKnots);
82     TempMults.Init (1);
83     Standard_Integer TempKnotIndex = 1;
84     TempKnots (TempKnotIndex) = KnotSequence (StartFlatIndex - deg);
85
86     for ( j = StartFlatIndex - deg + 1; j <= EndFlatIndex + deg; j++ )
87       if (Abs (KnotSequence (j) - KnotSequence (j - 1)) <= gp::Resolution())
88         TempMults (TempKnotIndex) ++;
89       else
90         TempKnots (++TempKnotIndex) = KnotSequence (j);
91     
92     Standard_Integer TempStartIndex = 1, TempEndIndex = TempKnotIndex;
93     if (TempMults (TempStartIndex) == 1)
94       TempMults (++TempStartIndex) ++;
95     if (TempMults (TempEndIndex) == 1)
96       TempMults (--TempEndIndex) ++;
97
98     Standard_Integer NewNbKnots = TempEndIndex - TempStartIndex + 1;
99     TColStd_Array1OfInteger newMults (1, NewNbKnots);
100     TColStd_Array1OfReal    newKnots (1, NewNbKnots);
101     for ( j = 1; j <= NewNbKnots; j++ ) {
102       newMults (j) = TempMults (j + TempStartIndex - 1);
103       newKnots (j) = TempKnots (j + TempStartIndex - 1);
104     }
105         
106     Standard_Integer NewNbPoles = BSplCLib::NbPoles(deg, Standard_False, newMults);
107     TColgp_Array1OfPnt   newPoles (1, NewNbPoles);
108     TColStd_Array1OfReal newWeights (1, NewNbPoles);
109     Standard_Integer PoleIndex = StartFlatIndex - deg;//Index of starting pole when splitting B-Spline is an index of starting knot
110     for (j = 1; j <= NewNbPoles; j++) {
111       newWeights (j) = Weights (j + PoleIndex - 1);
112       newPoles   (j) = Poles   (j + PoleIndex - 1);
113     }
114         
115     Handle(Geom_BSplineCurve) newC = new Geom_BSplineCurve
116       (newPoles, newWeights, newKnots, newMults,deg);
117     seqBS->Append (newC);
118     
119     StartKnotIndex = EndKnotIndex;
120   }
121   return Standard_True;
122 }
123
124 //=======================================================================
125 //function : C0BSplineToSequenceOfC1BSplineCurve
126 //purpose  : 
127 //=======================================================================
128
129 static Handle(Geom_BSplineCurve) BSplineCurve2dTo3d (const Handle(Geom2d_BSplineCurve)& BS)
130 {
131   Standard_Integer deg     = BS->Degree();
132   Standard_Integer NbKnots = BS->NbKnots();
133   Standard_Integer NbPoles = BS->NbPoles();
134   TColgp_Array1OfPnt2d    Poles2d (1,NbPoles);
135   TColStd_Array1OfReal    Weights (1,NbPoles);
136   TColStd_Array1OfReal    Knots   (1,NbKnots);
137   TColStd_Array1OfInteger Mults   (1,NbKnots);
138
139   BS->Poles(Poles2d);
140   if (BS->IsRational())
141     BS->Weights(Weights);
142   else
143     Weights.Init (1);
144   BS->Knots (Knots);
145   BS->Multiplicities (Mults);
146
147   TColgp_Array1OfPnt Poles3d (1,NbPoles);
148   for (Standard_Integer i = 1; i <= NbPoles; i++)
149     Poles3d (i) = gp_Pnt (Poles2d (i).X(), Poles2d (i).Y(), 0);
150   
151   Handle(Geom_BSplineCurve) BS3d = new Geom_BSplineCurve (Poles3d, Weights,
152                                                           Knots, Mults, deg, BS->IsPeriodic());
153   return BS3d;
154 }
155
156 static Handle(Geom2d_BSplineCurve) BSplineCurve3dTo2d (const Handle(Geom_BSplineCurve)& BS)
157 {
158   Standard_Integer deg     = BS->Degree();
159   Standard_Integer NbKnots = BS->NbKnots();
160   Standard_Integer NbPoles = BS->NbPoles();
161   TColgp_Array1OfPnt      Poles3d (1, NbPoles);
162   TColStd_Array1OfReal    Weights (1, NbPoles);
163   TColStd_Array1OfReal    Knots   (1, NbKnots);
164   TColStd_Array1OfInteger Mults   (1, NbKnots);
165
166   BS->Poles(Poles3d);
167   if (BS->IsRational())
168     BS->Weights(Weights);
169   else
170     Weights.Init (1);
171   BS->Knots (Knots);
172   BS->Multiplicities (Mults);
173
174   TColgp_Array1OfPnt2d Poles2d (1,NbPoles);
175   for (Standard_Integer i = 1; i <= NbPoles; i++)
176     Poles2d (i) = gp_Pnt2d (Poles3d (i).X(), Poles3d (i).Y());
177   
178   Handle(Geom2d_BSplineCurve) BS2d = new Geom2d_BSplineCurve (Poles2d, Weights,
179                                                               Knots, Mults, deg, BS->IsPeriodic());
180   return BS2d;
181 }
182
183  Standard_Boolean ShapeUpgrade::C0BSplineToSequenceOfC1BSplineCurve(const Handle(Geom2d_BSplineCurve)& BS,
184                                                                     Handle(TColGeom2d_HSequenceOfBoundedCurve)& seqBS) 
185 {
186   if (BS.IsNull() || (BS->IsCN (1))) return Standard_False;
187   
188   Handle(Geom_BSplineCurve) BS3d = BSplineCurve2dTo3d (BS);
189   Handle(TColGeom_HSequenceOfBoundedCurve) seqBS3d;
190   Standard_Boolean result = C0BSplineToSequenceOfC1BSplineCurve (BS3d, seqBS3d); 
191   if (result) {
192     seqBS = new TColGeom2d_HSequenceOfBoundedCurve;
193     for (Standard_Integer i = 1; i <= seqBS3d->Length(); i++)
194       seqBS->Append (BSplineCurve3dTo2d (Handle(Geom_BSplineCurve)::DownCast (seqBS3d->Value (i))));
195   }
196   return result;
197 }
198