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