b311480e |
1 | // Created on: 1994-09-01 |
2 | // Created by: Christian CAILLET |
3 | // Copyright (c) 1994-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
7fd59977 |
17 | // modif du 31/01/97 : mjm |
18 | // on commence par les SplineCurves. |
19 | // modif du 17/03/97 : mjm |
20 | // SplineSurfaces. |
21 | //%13 pdn 12.02.99: USA60293 avoid applying transformation twice |
22 | |
7fd59977 |
23 | #include <BSplCLib.hxx> |
7fd59977 |
24 | #include <BSplSLib.hxx> |
42cf5bc1 |
25 | #include <Geom2d_BSplineCurve.hxx> |
26 | #include <Geom_BSplineCurve.hxx> |
27 | #include <Geom_BSplineSurface.hxx> |
28 | #include <GeomConvert_CompCurveToBSplineCurve.hxx> |
7fd59977 |
29 | #include <gp_GTrsf.hxx> |
30 | #include <gp_Trsf.hxx> |
42cf5bc1 |
31 | #include <IGESConvGeom.hxx> |
32 | #include <IGESData_ToolLocation.hxx> |
33 | #include <IGESGeom_SplineCurve.hxx> |
34 | #include <IGESGeom_SplineSurface.hxx> |
7fd59977 |
35 | #include <PLib.hxx> |
7fd59977 |
36 | #include <TColgp_HArray1OfPnt.hxx> |
37 | #include <TColgp_HArray2OfPnt.hxx> |
7fd59977 |
38 | #include <TColStd_Array1OfInteger.hxx> |
39 | #include <TColStd_Array1OfReal.hxx> |
40 | #include <TColStd_HArray1OfReal.hxx> |
41 | |
7fd59977 |
42 | //======================================================================= |
43 | //function : IGESConvGeom::SplineCurveFromIGES |
44 | //purpose : |
45 | //======================================================================= |
46 | Standard_Integer IGESConvGeom::SplineCurveFromIGES |
47 | (const Handle(IGESGeom_SplineCurve)& st, |
48 | const Standard_Real /*epscoef*/, const Standard_Real epsgeom, |
49 | Handle(Geom_BSplineCurve)& res) |
50 | { |
51 | Standard_Integer returned = 0; |
52 | |
53 | // on recupere le degre |
54 | Standard_Integer degree = st->SplineType(); |
55 | if (degree > 3) degree = 3; |
56 | |
57 | // on recupere le nombre de segments. |
58 | Standard_Integer nbSegs = st->NbSegments(); |
59 | if (nbSegs < 1) return 5; // FAIL : no segment |
60 | |
61 | Standard_Integer nbKnots = nbSegs+1; |
62 | |
63 | // Array of multiplicities. |
64 | TColStd_Array1OfInteger multi(1, nbKnots); |
65 | multi.Init(degree); |
66 | multi.SetValue(multi.Lower(), degree+1); |
67 | multi.SetValue(multi.Upper(), degree+1); |
68 | |
69 | // Array of knots. |
70 | TColStd_Array1OfReal knots(1, nbKnots); |
71 | TColStd_Array1OfReal delta(1, nbSegs); |
72 | Standard_Integer i; // svv Jan 10 2000 : porting on DEC |
73 | for (i = 1; i<= nbKnots; i++) |
74 | knots.SetValue(i, st->BreakPoint(i)); |
75 | |
76 | for (i = 1; i <= nbSegs; i++) |
77 | delta.SetValue(i, st->BreakPoint(i+1) - st->BreakPoint(i)); |
78 | |
79 | TColgp_Array1OfPnt bspoles(1, nbSegs*degree+1); |
80 | Standard_Integer ibspole = bspoles.Lower()-1; // Bspole Index. |
81 | // il faut reparametrer avant de passer dans PLib. |
82 | // on est entre[0, T(i+1)-T(i)] et on veut [0,1] |
83 | |
84 | for (i = 1; i <= nbSegs; i++) { |
85 | Standard_Real AX,BX,CX,DX,AY,BY,CY,DY,AZ,BZ,CZ,DZ; |
86 | st->XCoordPolynomial(i, AX, BX, CX, DX); |
87 | st->YCoordPolynomial(i, AY, BY, CY, DY); |
88 | st->ZCoordPolynomial(i, AZ, BZ, CZ, DZ); |
89 | if (st->NbDimensions() == 2 ) BZ=0.,CZ=0.,DZ=0.; |
90 | Standard_Real Di = delta(i); |
91 | Standard_Real Di2 = delta(i)*delta(i); |
92 | Standard_Real Di3 = delta(i)*delta(i)*delta(i); |
93 | |
94 | TColgp_Array1OfPnt coeff(0, degree); |
95 | switch (degree) { |
96 | case 3 : |
97 | coeff.SetValue(coeff.Lower()+3, gp_Pnt(DX*Di3, DY*Di3, DZ*Di3)); |
98 | case 2 : |
99 | coeff.SetValue(coeff.Lower()+2, gp_Pnt(CX*Di2, CY*Di2, CZ*Di2)); |
100 | case 1 : |
101 | coeff.SetValue(coeff.Lower()+1, gp_Pnt(BX*Di, BY*Di, BZ*Di)); |
102 | coeff.SetValue(coeff.Lower()+0, gp_Pnt(AX, AY, AZ)); |
103 | break; |
104 | default: |
105 | break; |
106 | } |
107 | |
108 | |
109 | TColgp_Array1OfPnt bzpoles(0, degree); |
110 | PLib::CoefficientsPoles(coeff,PLib::NoWeights(),bzpoles,PLib::NoWeights()); |
111 | |
112 | // C0 test. |
113 | // Not to check the first pole of the first segment. |
114 | if (ibspole > bspoles.Lower()) { |
115 | Standard_Integer bzlow = bzpoles.Lower(); |
116 | if (!(bspoles.Value(ibspole).IsEqual(bzpoles.Value(bzlow), epsgeom))) { |
117 | returned = 1; |
118 | // Medium point computing. |
119 | bspoles.SetValue (ibspole, |
120 | gp_Pnt((bspoles.Value(ibspole).X() + bzpoles.Value(bzlow).X())/2., |
121 | (bspoles.Value(ibspole).Y() + bzpoles.Value(bzlow).Y())/2., |
122 | (bspoles.Value(ibspole).Z() + bzpoles.Value(bzlow).Z())/2.)); |
123 | } |
124 | } |
125 | if (i == 1) bspoles.SetValue(++ibspole, bzpoles.Value(bzpoles.Lower())); |
126 | |
127 | for (Standard_Integer j = bzpoles.Lower()+1; j <= bzpoles.Upper(); j++) |
128 | bspoles.SetValue(++ibspole, bzpoles.Value(j)); |
129 | } |
130 | if (ibspole != bspoles.Upper()) { |
131 | // Just to be sure. |
132 | return 3; // FAIL : Error during creation of control points |
133 | } |
134 | |
135 | // Building result taking into account transformation if any : |
136 | // =========================================================== |
137 | |
138 | //%13 pdn 12.02.99 USA60293 |
139 | // if (st->HasTransf()) { |
140 | // gp_Trsf trsf; |
141 | // Standard_Real epsilon = 1.E-04; |
142 | // if (IGESData_ToolLocation::ConvertLocation |
143 | // (epsilon,st->CompoundLocation(),trsf)) { |
144 | // for (Standard_Integer i = bspoles.Lower(); i <= bspoles.Upper(); i++) |
145 | // bspoles.SetValue(i, bspoles.Value(i).Transformed(trsf)); |
146 | // } |
147 | // else |
148 | // AddFail(st, "Transformation : not a similarity"); |
149 | // } |
150 | res = new Geom_BSplineCurve (bspoles, knots, multi, degree); |
151 | // GeomConvert_CompCurveToBSplineCurve CompCurve = |
152 | // GeomConvert_CompCurveToBSplineCurve(res); |
153 | // res = CompCurve.BSplineCurve(); |
154 | return returned; |
155 | } |
156 | |
157 | |
158 | |
159 | //======================================================================= |
160 | //function : IGESConvGeom::IncreaseCurveContinuity |
161 | //purpose : |
162 | //======================================================================= |
163 | Standard_Integer IGESConvGeom::IncreaseCurveContinuity (const Handle(Geom_BSplineCurve)& res, |
164 | const Standard_Real epsgeom, |
165 | const Standard_Integer continuity) |
166 | { |
167 | if (continuity < 1) return continuity; |
168 | Standard_Boolean isC1 = Standard_True, isC2 = Standard_True; |
169 | Standard_Integer degree = res->Degree(); |
170 | |
171 | |
172 | Standard_Boolean isModified; |
173 | do { |
174 | isModified = Standard_False; |
175 | for (Standard_Integer i = res->FirstUKnotIndex()+1; i < res->LastUKnotIndex(); i++) |
176 | if(degree - res->Multiplicity(i) < continuity) { |
177 | if (continuity >= 2) { |
178 | if (!res->RemoveKnot(i, degree-2, epsgeom)) { |
179 | isC2 = Standard_False; |
180 | Standard_Boolean locOK = res->RemoveKnot(i, degree-1, epsgeom); // is C1 ? |
181 | isC1 &= locOK; |
182 | isModified |= locOK; |
183 | } |
184 | else |
185 | isModified = Standard_True; |
186 | } |
187 | else { |
188 | Standard_Boolean locOK = res->RemoveKnot(i, degree-1, epsgeom); // is C1 ? |
189 | isC1 &= locOK; |
190 | isModified |= locOK; |
191 | } |
192 | } |
193 | } |
194 | while (isModified); |
195 | |
196 | if (!isC1) return 0; |
197 | if (continuity >= 2 && !isC2) return 1; |
198 | return continuity; |
199 | } |
200 | |
201 | //======================================================================= |
202 | //function : IncreaseCurveContinuity |
203 | //purpose : |
204 | //======================================================================= |
205 | |
206 | Standard_Integer IGESConvGeom::IncreaseCurveContinuity (const Handle(Geom2d_BSplineCurve)& res, |
207 | const Standard_Real epsgeom, |
208 | const Standard_Integer continuity) |
209 | { |
210 | if (continuity < 1) return continuity; |
211 | Standard_Boolean isC1 = Standard_True, isC2 = Standard_True; |
212 | Standard_Integer degree = res->Degree(); |
213 | |
214 | Standard_Boolean isModified; |
215 | do { |
216 | isModified = Standard_False; |
217 | for (Standard_Integer i = res->FirstUKnotIndex()+1; i < res->LastUKnotIndex(); i++) |
218 | if(degree - res->Multiplicity(i) < continuity) { |
219 | if (continuity >= 2) { |
220 | if (!res->RemoveKnot(i, degree-2, epsgeom)) { |
221 | isC2 = Standard_False; |
222 | Standard_Boolean locOK = res->RemoveKnot(i, degree-1, epsgeom); // is C1 ? |
223 | isC1 &= locOK; |
224 | isModified |= locOK; |
225 | } |
226 | else |
227 | isModified = Standard_True; |
228 | } |
229 | else { |
230 | Standard_Boolean locOK = res->RemoveKnot(i, degree-1, epsgeom); // is C1 ? |
231 | isC1 &= locOK; |
232 | isModified |= locOK; |
233 | } |
234 | } |
235 | } |
236 | while (isModified); |
237 | |
238 | if (!isC1) return 0; |
239 | if (continuity >= 2 && !isC2) return 1; |
240 | return continuity; |
241 | } |
242 | |
243 | |
244 | //======================================================================= |
245 | //function : IGESConvGeom::SplineSurfaceFromIGES |
246 | //purpose : |
247 | //======================================================================= |
248 | Standard_Integer IGESConvGeom::SplineSurfaceFromIGES |
249 | (const Handle(IGESGeom_SplineSurface)& st, |
250 | const Standard_Real /*epscoef*/, const Standard_Real epsgeom, |
251 | Handle(Geom_BSplineSurface)& res) |
252 | { |
253 | Standard_Integer returned = 0; |
254 | Standard_Integer degree = st->BoundaryType(); |
255 | if (degree > 3) degree = 3; |
256 | Standard_Integer DegreeU = degree; |
257 | Standard_Integer DegreeV = degree; |
258 | |
259 | Standard_Integer NbUSeg = st->NbUSegments(); |
260 | Standard_Integer NbVSeg = st->NbVSegments(); |
261 | |
262 | if ((NbUSeg < 1) || (NbVSeg < 1)) return 5; |
263 | |
264 | // Output BSpline knots & multiplicities arraies for U & V : |
265 | // ========================================================= |
266 | |
267 | TColStd_Array1OfReal UKnot(1,NbUSeg+1); |
268 | TColStd_Array1OfReal VKnot(1,NbVSeg+1); |
269 | TColStd_Array1OfReal deltaU(1,NbUSeg); |
270 | TColStd_Array1OfReal deltaV(1,NbVSeg); |
271 | |
272 | Standard_Integer i; // svv Jan 10 2000 : porting on DEC |
273 | for (i=1; i <= NbUSeg+1; i++) |
274 | UKnot.SetValue(i, st->UBreakPoint(i)); |
275 | |
276 | for (i=1; i <= NbUSeg; i++) |
277 | deltaU.SetValue(i, st->UBreakPoint(i+1)- st->UBreakPoint(i)); |
278 | |
279 | for (i=1; i <= NbVSeg+1; i++) |
280 | VKnot.SetValue(i, st->VBreakPoint(i)); |
281 | |
282 | for (i=1; i <= NbVSeg; i++) |
283 | deltaV.SetValue(i, st->VBreakPoint(i+1)- st->VBreakPoint(i)); |
284 | |
285 | TColStd_Array1OfInteger UMult(1,NbUSeg+1); UMult.Init(DegreeU); |
286 | UMult.SetValue(UMult.Lower(),DegreeU+1); |
287 | UMult.SetValue(UMult.Upper(),DegreeU+1); |
288 | |
289 | TColStd_Array1OfInteger VMult(1,NbVSeg+1); VMult.Init(DegreeV); |
290 | VMult.SetValue(VMult.Lower(),DegreeV+1); |
291 | VMult.SetValue(VMult.Upper(),DegreeV+1); |
292 | |
293 | |
294 | // Poles computing |
295 | // =============== |
296 | |
297 | Standard_Integer NbUPoles = NbUSeg * DegreeU + 1; |
298 | Standard_Integer NbVPoles = NbVSeg * DegreeV + 1; |
299 | |
300 | TColgp_Array2OfPnt BsPole(1, NbUPoles, 1, NbVPoles); |
301 | |
302 | Standard_Integer iBs, jBs, iBz, jBz; |
303 | Standard_Boolean wasC0 = Standard_True; |
304 | |
305 | // Patch (1,1) |
306 | // =========== |
307 | Standard_Integer USeg, VSeg, j; |
308 | USeg = 1; |
309 | VSeg = 1; |
310 | |
311 | Handle(TColStd_HArray1OfReal) XPoly = st->XPolynomial(USeg, VSeg); |
312 | Handle(TColStd_HArray1OfReal) YPoly = st->YPolynomial(USeg, VSeg); |
313 | Handle(TColStd_HArray1OfReal) ZPoly = st->ZPolynomial(USeg, VSeg); |
314 | |
315 | TColgp_Array2OfPnt Coef(1, DegreeU+1, 1, DegreeV+1); |
316 | Standard_Real ParamU, ParamV; |
317 | ParamU = 1.; |
318 | for (i=1; i<=DegreeU+1; i++) { |
319 | ParamV = 1.; |
320 | for (j=1; j<=DegreeV+1; j++) { |
321 | Standard_Integer PolyIndex = i + 4*(j-1); |
322 | gp_Pnt aPoint(XPoly->Value(PolyIndex)*ParamU*ParamV, |
323 | YPoly->Value(PolyIndex)*ParamU*ParamV, |
324 | ZPoly->Value(PolyIndex)*ParamU*ParamV); |
325 | Coef.SetValue(i, j, aPoint); |
326 | ParamV = ParamV *deltaV(VSeg); |
327 | } |
328 | ParamU = ParamU * deltaU(USeg); |
329 | } |
330 | TColgp_Array2OfPnt BzPole(1, DegreeU+1, 1, DegreeV+1); |
331 | PLib::CoefficientsPoles(Coef,PLib::NoWeights2(),BzPole,PLib::NoWeights2()); |
332 | |
333 | iBs = BsPole.LowerRow(); |
334 | jBs = BsPole.LowerCol(); |
335 | |
336 | // Making output BSpline poles array : |
337 | for (iBz=BzPole.LowerRow(); iBz<=BzPole.UpperRow(); iBz++) { |
338 | for (jBz=BzPole.LowerCol(); jBz<=BzPole.UpperCol(); jBz++) |
339 | BsPole.SetValue(iBs, jBs++, BzPole.Value(iBz,jBz)); |
340 | jBs = BsPole.LowerCol(); |
341 | iBs++; |
342 | } |
343 | |
344 | |
345 | // Patches (1<USeg<NbUSeg, 1) |
346 | // ========================== |
347 | |
348 | VSeg = 1; |
349 | for (USeg=2; USeg<=NbUSeg; USeg++) { |
350 | XPoly = st->XPolynomial(USeg, VSeg); |
351 | YPoly = st->YPolynomial(USeg, VSeg); |
352 | ZPoly = st->ZPolynomial(USeg, VSeg); |
7fd59977 |
353 | ParamU = 1.; |
354 | for (i=Coef.LowerRow(); i<=Coef.UpperRow(); i++) { |
355 | ParamV = 1.; |
356 | for (j=Coef.LowerCol(); j<=Coef.UpperCol(); j++) { |
357 | Standard_Integer PolyIndex = i + 4*(j-1); |
358 | gp_Pnt aPoint; |
359 | aPoint.SetCoord(XPoly->Value(PolyIndex)*ParamU*ParamV, |
360 | YPoly->Value(PolyIndex)*ParamU*ParamV, |
361 | ZPoly->Value(PolyIndex)*ParamU*ParamV); |
362 | Coef.SetValue(i, j, aPoint); |
363 | ParamV = ParamV *deltaV(VSeg); |
364 | } |
365 | ParamU = ParamU * deltaU(USeg); |
366 | } |
367 | PLib::CoefficientsPoles(Coef,PLib::NoWeights2(),BzPole,PLib::NoWeights2()); |
368 | |
369 | // C0 check and correction for poles lying on isoparametrics U=0 & V=0 |
51740958 |
370 | Standard_Integer iBsPole = BsPole.LowerRow() + (USeg-1)*DegreeU; |
371 | Standard_Integer jBsPole = BsPole.LowerCol(); |
7fd59977 |
372 | iBz = BzPole.LowerRow(); |
373 | for (jBz=BzPole.LowerCol(); jBz<=BzPole.UpperCol(); jBz++) { |
51740958 |
374 | if (!BzPole.Value(iBz,jBz).IsEqual(BsPole.Value(iBsPole,jBsPole), epsgeom)) { |
7fd59977 |
375 | wasC0=Standard_False; |
376 | gp_Pnt MidPoint; |
377 | Standard_Real XCoord = |
51740958 |
378 | 0.5 * (BzPole.Value(iBz,jBz).X() + BsPole.Value(iBsPole,jBsPole).X()); |
7fd59977 |
379 | Standard_Real YCoord = |
51740958 |
380 | 0.5 * (BzPole.Value(iBz,jBz).Y() + BsPole.Value(iBsPole,jBsPole).Y()); |
7fd59977 |
381 | Standard_Real ZCoord = |
51740958 |
382 | 0.5 * (BzPole.Value(iBz,jBz).Z() + BsPole.Value(iBsPole,jBsPole).Z()); |
7fd59977 |
383 | MidPoint.SetCoord(XCoord, YCoord, ZCoord); |
51740958 |
384 | BsPole.SetValue(iBsPole, jBsPole++, MidPoint); |
7fd59977 |
385 | } |
386 | else { |
51740958 |
387 | BsPole.SetValue(iBsPole, jBsPole++, BzPole.Value(iBz,jBz)); |
7fd59977 |
388 | } |
389 | } |
390 | |
391 | // Other poles (no check about C0) : |
51740958 |
392 | iBsPole++; |
393 | jBsPole = BsPole.LowerCol(); |
7fd59977 |
394 | for (iBz=BzPole.LowerRow()+1; iBz<=BzPole.UpperRow(); iBz++) { |
395 | for (jBz=BzPole.LowerCol(); jBz<=BzPole.UpperCol(); jBz++) |
51740958 |
396 | BsPole.SetValue(iBsPole, jBsPole++, BzPole.Value(iBz,jBz)); |
397 | iBsPole++; |
398 | jBsPole = BsPole.LowerCol(); |
7fd59977 |
399 | } |
400 | } |
401 | |
402 | |
403 | |
404 | // Patches (1, 1<VSeg<NbVSeg) |
405 | // ========================== |
406 | |
407 | USeg = 1; |
408 | for (VSeg=2; VSeg <= NbVSeg; VSeg++) { |
409 | XPoly = st->XPolynomial(USeg, VSeg); |
410 | YPoly = st->YPolynomial(USeg, VSeg); |
411 | ZPoly = st->ZPolynomial(USeg, VSeg); |
7fd59977 |
412 | ParamU = 1.; |
413 | for (i=Coef.LowerRow(); i<=Coef.UpperRow(); i++) { |
414 | ParamV = 1.; |
415 | for (j=Coef.LowerCol(); j<=Coef.UpperCol(); j++) { |
416 | Standard_Integer PolyIndex = i + 4*(j-1); |
417 | gp_Pnt aPoint; |
418 | aPoint.SetCoord(XPoly->Value(PolyIndex)*ParamU*ParamV, |
419 | YPoly->Value(PolyIndex)*ParamU*ParamV, |
420 | ZPoly->Value(PolyIndex)*ParamU*ParamV); |
421 | Coef.SetValue(i, j, aPoint); |
422 | ParamV = ParamV *deltaV(VSeg); |
423 | } |
424 | ParamU = ParamU * deltaU(USeg); |
425 | } |
426 | PLib::CoefficientsPoles(Coef,PLib::NoWeights2(),BzPole,PLib::NoWeights2()); |
427 | |
428 | // C0 check and correction for poles lying on isoparametrics U=0 & V=0 |
429 | iBs = BsPole.LowerRow(); |
430 | jBs = BsPole.LowerCol() + (VSeg-1)*DegreeV; |
431 | jBz = BzPole.LowerCol(); |
432 | for (iBz=BzPole.LowerRow(); iBz<=BzPole.UpperRow(); iBz++) { |
433 | if (!BzPole.Value(iBz,jBz).IsEqual(BsPole.Value(iBs,jBs), epsgeom)) { |
434 | wasC0=Standard_False; |
435 | gp_Pnt MidPoint; |
436 | Standard_Real XCoord = 0.5 * |
437 | (BzPole.Value(iBz,jBz).X() + BsPole.Value(iBs,jBs).X()); |
438 | Standard_Real YCoord = 0.5 * |
439 | (BzPole.Value(iBz,jBz).Y() + BsPole.Value(iBs,jBs).Y()); |
440 | Standard_Real ZCoord = 0.5 * |
441 | (BzPole.Value(iBz,jBz).Z() + BsPole.Value(iBs,jBs).Z()); |
442 | MidPoint.SetCoord(XCoord, YCoord, ZCoord); |
443 | BsPole.SetValue(iBs++, jBs, MidPoint); |
444 | } |
445 | else{ |
446 | BsPole.SetValue(iBs++, jBs, BzPole.Value(iBz,jBz)); |
447 | } |
448 | } |
449 | |
450 | jBs++; |
451 | iBs = BsPole.LowerRow(); |
452 | for (jBz=BzPole.LowerCol()+1; jBz<=BzPole.UpperCol(); jBz++) { |
453 | for (iBz=BzPole.LowerRow(); iBz<=BzPole.UpperRow(); iBz++) |
454 | BsPole.SetValue(iBs++, jBs, BzPole.Value(iBz,jBz)); |
455 | iBs = BsPole.LowerRow(); |
456 | jBs++; |
457 | } |
458 | } |
459 | |
460 | |
461 | // Patches (1<USeg<NbUSeg, 1<VSeg<NbVSeg) |
462 | // ====================================== |
463 | |
464 | for (VSeg=2; VSeg <= NbVSeg; VSeg++) { |
465 | for (USeg=2; USeg <= NbUSeg; USeg++) { |
466 | XPoly = st->XPolynomial(USeg, VSeg); |
467 | YPoly = st->YPolynomial(USeg, VSeg); |
468 | ZPoly = st->ZPolynomial(USeg, VSeg); |
7fd59977 |
469 | ParamU = 1.; |
470 | for (i=Coef.LowerRow(); i<=Coef.UpperRow(); i++) { |
471 | ParamV = 1.; |
472 | for (j=Coef.LowerCol(); j<=Coef.UpperCol(); j++) { |
473 | Standard_Integer PolyIndex = i + 4*(j-1); |
474 | gp_Pnt aPoint; |
475 | aPoint.SetCoord(XPoly->Value(PolyIndex)*ParamU*ParamV, |
476 | YPoly->Value(PolyIndex)*ParamU*ParamV, |
477 | ZPoly->Value(PolyIndex)*ParamU*ParamV); |
478 | Coef.SetValue(i, j, aPoint); |
479 | ParamV = ParamV *deltaV(VSeg); |
480 | } |
481 | ParamU = ParamU * deltaU(USeg); |
482 | } |
483 | PLib::CoefficientsPoles(Coef,PLib::NoWeights2(),BzPole,PLib::NoWeights2()); |
484 | |
485 | // C0 check and correction for poles lying on isoparametrics U=0 & V=0 |
486 | iBs = (USeg-1)*DegreeU + BsPole.LowerRow(); |
487 | jBs = (VSeg-1)*DegreeV + BsPole.LowerCol(); |
488 | jBz = BzPole.LowerCol(); |
489 | for (iBz=BzPole.LowerRow(); iBz<=BzPole.UpperRow(); iBz++) { |
490 | if (!BzPole.Value(iBz,jBz).IsEqual(BsPole.Value(iBs,jBs), epsgeom)) { |
491 | wasC0=Standard_False; |
492 | gp_Pnt MidPoint; |
493 | Standard_Real XCoord = 0.5 * |
494 | (BzPole.Value(iBz,jBz).X() + BsPole.Value(iBs,jBs).X()); |
495 | Standard_Real YCoord = 0.5 * |
496 | (BzPole.Value(iBz,jBz).Y() + BsPole.Value(iBs,jBs).Y()); |
497 | Standard_Real ZCoord = 0.5 * |
498 | (BzPole.Value(iBz,jBz).Z() + BsPole.Value(iBs,jBs).Z()); |
499 | MidPoint.SetCoord(XCoord, YCoord, ZCoord); |
500 | BsPole.SetValue(iBs++, jBs, MidPoint); |
501 | } |
502 | else |
503 | BsPole.SetValue(iBs++, jBs, BzPole.Value(iBz,jBz)); |
504 | } |
505 | |
506 | iBs = (USeg-1)*DegreeU + BsPole.LowerRow(); |
507 | iBz = BzPole.LowerRow(); |
508 | for (jBz=BzPole.LowerCol(); jBz<=BzPole.UpperCol(); jBz++) { |
509 | // C0 check and correction for poles lying on isoparametrics U=0 & V=0 |
510 | if (!BzPole.Value(iBz,jBz).IsEqual(BsPole.Value(iBs,jBs), epsgeom)) { |
511 | wasC0=Standard_False; |
512 | gp_Pnt MidPoint; |
513 | Standard_Real XCoord = 0.5 * |
514 | (BzPole.Value(iBz,jBz).X() + BsPole.Value(iBs,jBs).X()); |
515 | Standard_Real YCoord = 0.5 * |
516 | (BzPole.Value(iBz,jBz).Y() + BsPole.Value(iBs,jBs).Y()); |
517 | Standard_Real ZCoord = 0.5 * |
518 | (BzPole.Value(iBz,jBz).Z() + BsPole.Value(iBs,jBs).Z()); |
519 | MidPoint.SetCoord(XCoord, YCoord, ZCoord); |
520 | BsPole.SetValue(iBs, jBs++, MidPoint); |
521 | } |
522 | else |
523 | BsPole.SetValue(iBs, jBs++, BzPole.Value(iBz,jBz)); |
524 | } |
525 | |
526 | iBs = BsPole.LowerRow() + (USeg-1)*DegreeU + 1; |
527 | jBs = BsPole.LowerCol() + (VSeg-1)*DegreeV + 1; |
528 | for (iBz=BzPole.LowerRow()+1; iBz<=BzPole.UpperRow(); iBz++) { |
529 | for (jBz=BzPole.LowerCol()+1; jBz<=BzPole.UpperCol(); jBz++) |
530 | BsPole.SetValue(iBs, jBs++, BzPole.Value(iBz,jBz)); |
531 | jBs = BsPole.LowerCol() + (VSeg-1)*DegreeV + 1; |
532 | iBs++; |
533 | } |
534 | } |
535 | } |
536 | |
537 | // Building result taking into account transformation if any : |
538 | // =========================================================== |
539 | |
540 | if (st->HasTransf()) { |
541 | gp_GTrsf GSplTrsf(st->CompoundLocation()); |
542 | gp_Trsf SplTrsf; |
543 | Standard_Real epsilon = 1.E-04; |
544 | if (IGESData_ToolLocation::ConvertLocation(epsilon,GSplTrsf,SplTrsf)) |
545 | for (iBs=BsPole.LowerRow(); iBs<=BsPole.UpperRow(); iBs++) |
546 | for (jBs=BsPole.LowerCol(); jBs<=BsPole.UpperCol(); jBs++) |
547 | BsPole.SetValue(iBs, jBs, BsPole.Value(iBs,jBs).Transformed(SplTrsf)); |
548 | // else |
549 | // AddWarning(start, "Transformation skipped : Not a similarity"); |
550 | } |
551 | |
552 | res = new Geom_BSplineSurface |
553 | (BsPole, UKnot, VKnot, UMult, VMult, DegreeU, DegreeV); |
554 | if (wasC0) returned += 1; |
555 | return returned; |
556 | } |
557 | |
558 | |
559 | //======================================================================= |
560 | //function : IGESConvGeom::IncreaseSurfaceContinuity |
561 | //purpose : |
562 | //======================================================================= |
563 | Standard_Integer IGESConvGeom::IncreaseSurfaceContinuity (const Handle(Geom_BSplineSurface)& res, |
564 | const Standard_Real epsgeom, |
565 | const Standard_Integer continuity) |
566 | { |
567 | if (continuity < 1) return continuity; |
568 | Standard_Boolean isC1 = Standard_True, isC2 = Standard_True; |
7fd59977 |
569 | Standard_Integer DegreeU = res->UDegree(); |
570 | |
571 | Standard_Boolean isModified; |
572 | do { |
573 | isModified = Standard_False; |
96a95605 |
574 | for (Standard_Integer i = res->FirstUKnotIndex()+1; i < res->LastUKnotIndex(); i++) |
7fd59977 |
575 | if(DegreeU - res->UMultiplicity(i) < continuity) { |
576 | if (continuity >= 2) { |
577 | if (!res->RemoveUKnot(i, DegreeU-2, epsgeom)) { |
578 | isC2 = Standard_False; |
579 | Standard_Boolean locOK = res->RemoveUKnot(i, DegreeU-1, epsgeom); // is C1 ? |
580 | isC1 &= locOK; |
581 | isModified |= locOK; |
582 | } |
583 | else |
584 | isModified = Standard_True; |
585 | } |
586 | else { |
587 | Standard_Boolean locOK = res->RemoveUKnot(i, DegreeU-1, epsgeom); // is C1 ? |
588 | isC1 &= locOK; |
589 | isModified |= locOK; |
590 | } |
591 | } |
592 | } |
593 | while (isModified); |
594 | |
595 | Standard_Integer DegreeV = res->VDegree(); |
596 | do { |
597 | isModified = Standard_False; |
96a95605 |
598 | for (Standard_Integer i = res->FirstVKnotIndex()+1; i < res->LastVKnotIndex(); i++) |
7fd59977 |
599 | if(DegreeV - res->VMultiplicity(i) < continuity) { |
600 | if (continuity >= 2) { |
601 | if (!res->RemoveVKnot(i, DegreeV-2, epsgeom)) { |
602 | isC2 = Standard_False; |
603 | Standard_Boolean locOK = res->RemoveVKnot(i, DegreeV-1, epsgeom); // is C1 ? |
604 | isC1 &= locOK; |
605 | isModified |= locOK; |
606 | } |
607 | else |
608 | isModified = Standard_True; |
609 | } |
610 | else { |
611 | Standard_Boolean locOK = res->RemoveVKnot(i, DegreeV-1, epsgeom); // is C1 ? |
612 | isC1 &= locOK; |
613 | isModified |= locOK; |
614 | } |
615 | } |
616 | } |
617 | while (isModified); |
618 | |
619 | /* |
620 | while (--i > j) { // from 2 to NbKnots-1 |
621 | if (continuity >= 2) { |
622 | if (!res->RemoveUKnot(i, DegreeU-2, epsgeom)) { // is C2 ? |
623 | isC2 = Standard_False; |
624 | isC1 &= res->RemoveUKnot(i, DegreeU-1, epsgeom); // is C1 ? |
625 | } |
626 | } |
627 | else { |
628 | isC1 &= res->RemoveUKnot(i, DegreeU-1, epsgeom); // is C1 ? |
629 | } |
630 | } |
631 | |
632 | i = res->LastVKnotIndex(); //knots.Upper(); |
633 | j = res->FirstVKnotIndex(); //knots.Lower(); |
634 | Standard_Integer DegreeV = res->VDegree(); |
635 | while (--i > j) { // from 2 to NbKnots-1 |
636 | if (continuity >= 2) { |
637 | if (!res->RemoveVKnot(i, DegreeV-2, epsgeom)) { // is C2 ? |
638 | isC2 = Standard_False; |
639 | isC1 &= res->RemoveVKnot(i, DegreeV-1, epsgeom); // is C1 ? |
640 | } |
641 | } |
642 | else { |
643 | isC1 &= res->RemoveVKnot(i, DegreeV-1, epsgeom); // is C1 ? |
644 | } |
645 | }*/ |
646 | |
647 | |
648 | if (!isC1) return 0; |
649 | if (continuity >= 2 && !isC2) return 1; |
650 | return continuity; |
651 | } |
652 | |