b311480e |
1 | // Created on: 1997-03-10 |
2 | // Created by: Stagiaire Francois DUMONT |
3 | // Copyright (c) 1997-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. |
7fd59977 |
16 | |
17 | #include <BRepAlgo.ixx> |
18 | #include <BRepTools_WireExplorer.hxx> |
19 | #include <BRep_Tool.hxx> |
20 | #include <BRepLib_MakeEdge.hxx> |
21 | #include <BRepLib_MakeWire.hxx> |
22 | #include <gp_Pnt.hxx> |
23 | #include <GeomConvert.hxx> |
24 | #include <GeomLProp.hxx> |
25 | #include <Geom_TrimmedCurve.hxx> |
26 | #include <Precision.hxx> |
27 | #include <Standard_ConstructionError.hxx> |
28 | #include <TColGeom_Array1OfBSplineCurve.hxx> |
29 | #include <TColGeom_HArray1OfBSplineCurve.hxx> |
30 | #include <TColStd_Array1OfReal.hxx> |
31 | #include <TColStd_Array1OfBoolean.hxx> |
32 | #include <TopoDS_Edge.hxx> |
33 | #include <TopoDS_Vertex.hxx> |
34 | #include <TopLoc_Location.hxx> |
35 | #include <TopExp.hxx> |
36 | |
51a849d7 |
37 | #include <TColGeom_SequenceOfCurve.hxx> |
38 | #include <TopTools_SequenceOfShape.hxx> |
39 | #include <TColStd_SequenceOfReal.hxx> |
6f005d2a |
40 | #include <TColStd_SequenceOfBoolean.hxx> |
51a849d7 |
41 | #include <GeomAbs_CurveType.hxx> |
42 | #include <BRepAdaptor_Curve.hxx> |
43 | #include <ElCLib.hxx> |
44 | #include <BRepLib.hxx> |
45 | #include <TopoDS.hxx> |
46 | #include <ShapeFix_Shape.hxx> |
47 | #include <GeomConvert_CompCurveToBSplineCurve.hxx> |
48 | |
49 | //Temporary |
50 | #//include <DrawTrSurf.hxx> |
51 | |
52 | |
7fd59977 |
53 | //======================================================================= |
54 | //function : ConcatenateWire |
55 | //purpose : |
56 | //======================================================================= |
57 | |
58 | TopoDS_Wire BRepAlgo::ConcatenateWire(const TopoDS_Wire& W, |
59 | const GeomAbs_Shape Option, |
60 | const Standard_Real TolAngular) |
61 | { |
62 | |
63 | |
64 | Standard_Integer nb_curve, //number of curves in the Wire |
65 | index; |
66 | BRepTools_WireExplorer WExp(W) ; |
67 | TopoDS_Edge edge; |
68 | TopLoc_Location L ; |
69 | Standard_Real First=0.,Last=0., //extremal values for the curve |
70 | First0 =0., |
71 | toler =0., |
72 | tolleft,tolright; //Vertex tolerances |
73 | TopoDS_Vertex Vfirst,Vlast; //Vertex of the Wire |
74 | gp_Pnt Pfirst,Plast; //, Pint; corresponding points |
75 | |
76 | BRepLib_MakeWire MakeResult; |
77 | Standard_Real closed_tolerance =0.0; |
78 | Standard_Boolean closed_flag = Standard_False ; |
79 | |
80 | nb_curve = 0; |
81 | |
82 | while ( WExp.More()){ //computation of the curve number |
83 | nb_curve++ ; |
84 | WExp.Next(); |
85 | } |
86 | |
87 | if (nb_curve > 1) { |
88 | TColGeom_Array1OfBSplineCurve tab(0,nb_curve-1); //array of the wire's curve |
89 | TColStd_Array1OfReal tabtolvertex(0,nb_curve-2); //array of the tolerance's vertex |
90 | |
91 | WExp.Init(W); |
92 | |
93 | for (index=0 ;index<nb_curve; index++){ //main loop |
94 | edge = WExp.Current() ; |
51a849d7 |
95 | Handle(Geom_Curve) aCurve = BRep_Tool::Curve(edge, L, First, Last); |
96 | Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, First, Last); |
97 | tab(index) = GeomConvert::CurveToBSplineCurve(aTrCurve); //storage in a array |
7fd59977 |
98 | tab(index)->Transform(L.Transformation()); |
99 | GeomConvert::C0BSplineToC1BSplineCurve(tab(index),Precision::Confusion()); |
100 | |
101 | if (index >= 1){ //continuity test loop |
102 | if (edge.Orientation()==TopAbs_REVERSED) |
103 | tab(index)->Reverse(); |
104 | tolleft=BRep_Tool::Tolerance(TopExp::LastVertex(edge)); |
105 | tolright=BRep_Tool::Tolerance(TopExp::FirstVertex(edge)); |
106 | tabtolvertex(index-1)=Max(tolleft,tolright); |
107 | } |
108 | |
109 | if(index==0){ //storage of the first edge features |
110 | First0=First; |
111 | if(edge.Orientation()==TopAbs_REVERSED){ //(usefull for the closed wire) |
112 | Vfirst=TopExp::LastVertex(edge); |
113 | tab(index)->Reverse(); |
114 | } |
115 | else |
116 | Vfirst=TopExp::FirstVertex(edge); |
117 | } |
118 | |
119 | if(index==nb_curve-1){ //storage of the last edge features |
120 | if(edge.Orientation()==TopAbs_REVERSED) |
121 | Vlast=TopExp::FirstVertex(edge); |
122 | else |
123 | Vlast=TopExp::LastVertex(edge); |
124 | } |
125 | WExp.Next() ; |
126 | } |
127 | |
128 | if (BRep_Tool::Tolerance(Vfirst)>BRep_Tool::Tolerance(Vlast)) //computation of the closing tolerance |
129 | toler=BRep_Tool::Tolerance(Vfirst); |
130 | else |
131 | toler=BRep_Tool::Tolerance(Vlast); |
132 | |
133 | Pfirst=BRep_Tool::Pnt(Vfirst); |
134 | Plast=BRep_Tool::Pnt(Vlast); |
135 | |
136 | if ((Pfirst.Distance(Plast)<=toler)&& //C0 continuity test at the closing point |
137 | (GeomLProp::Continuity(tab(nb_curve-1),tab(0),Last,First0, |
138 | Standard_True,Standard_True, |
139 | toler, TolAngular)>=GeomAbs_G1)) |
140 | { |
141 | closed_tolerance =toler; //if ClosedG1!=0 it will be True and |
142 | closed_flag = Standard_True ; |
143 | } //with the toler value |
144 | Handle(TColGeom_HArray1OfBSplineCurve) concatcurve; //array of the concatenated curves |
145 | Handle(TColStd_HArray1OfInteger) ArrayOfIndices; //array of the remining Vertex |
146 | if (Option==GeomAbs_G1) |
147 | GeomConvert::ConcatG1(tab, |
148 | tabtolvertex, |
149 | concatcurve, |
150 | closed_flag, |
151 | closed_tolerance) ; //G1 concatenation |
152 | else |
153 | GeomConvert::ConcatC1(tab, |
154 | tabtolvertex, |
155 | ArrayOfIndices, |
156 | concatcurve, |
157 | closed_flag, |
158 | closed_tolerance); //C1 concatenation |
159 | |
160 | for (index=0;index<=(concatcurve->Length()-1);index++){ //building of the resulting Wire |
161 | BRepLib_MakeEdge EdgeBuilder(concatcurve->Value(index)); |
162 | edge = EdgeBuilder.Edge(); |
163 | MakeResult.Add(edge); |
164 | } |
165 | |
166 | } |
167 | else { |
168 | TColGeom_Array1OfBSplineCurve tab(0,0); //array of the wire's curve |
169 | TColStd_Array1OfReal tabtolvertex(0,0); //array of the tolerance's vertex |
170 | WExp.Init(W); |
171 | |
172 | edge = WExp.Current() ; |
173 | tab(0) = GeomConvert::CurveToBSplineCurve(new //storage in a array |
174 | Geom_TrimmedCurve(BRep_Tool::Curve(edge,L,First,Last),First,Last)); |
175 | tab(0)->Transform(L.Transformation()); |
176 | GeomConvert::C0BSplineToC1BSplineCurve(tab(0),Precision::Confusion()); |
177 | if (edge.Orientation()==TopAbs_REVERSED) |
178 | tab(0)->Reverse(); |
179 | tolleft=BRep_Tool::Tolerance(TopExp::LastVertex(edge)); |
180 | tolright=BRep_Tool::Tolerance(TopExp::FirstVertex(edge)); |
181 | tabtolvertex(0)=Max(tolleft,tolright); |
182 | if(edge.Orientation()==TopAbs_REVERSED){ //(usefull for the closed wire) |
183 | Vfirst=TopExp::LastVertex(edge); |
184 | Vlast=TopExp::FirstVertex(edge); |
185 | } |
186 | else { |
187 | |
188 | Vfirst=TopExp::FirstVertex(edge); |
189 | Vlast = TopExp::LastVertex(edge) ; |
190 | } |
191 | Pfirst=BRep_Tool::Pnt(Vfirst); |
192 | Plast=BRep_Tool::Pnt(Vlast); |
193 | if ((Pfirst.Distance(Plast)<=toler)&& //C0 continuity test at the closing point |
194 | (GeomLProp::Continuity(tab(0),tab(0),Last,First, |
195 | Standard_True,Standard_True, |
196 | toler, TolAngular)>=GeomAbs_G1)) |
197 | { |
198 | closed_tolerance =toler; //if ClosedG1!=0 it will be True and |
199 | closed_flag = Standard_True ; |
200 | } //with the toler value |
201 | Handle(TColGeom_HArray1OfBSplineCurve) concatcurve; //array of the concatenated curves |
202 | Handle(TColStd_HArray1OfInteger) ArrayOfIndices; //array of the remining Vertex |
203 | if (Option==GeomAbs_G1) |
204 | GeomConvert::ConcatG1(tab, |
205 | tabtolvertex, |
206 | concatcurve, |
207 | closed_flag, |
208 | closed_tolerance) ; //G1 concatenation |
209 | else |
210 | GeomConvert::ConcatC1(tab, |
211 | tabtolvertex, |
212 | ArrayOfIndices, |
213 | concatcurve, |
214 | closed_flag, |
215 | closed_tolerance); //C1 concatenation |
216 | |
217 | for (index=0;index<=(concatcurve->Length()-1);index++){ //building of the resulting Wire |
218 | BRepLib_MakeEdge EdgeBuilder(concatcurve->Value(index)); |
219 | edge = EdgeBuilder.Edge(); |
220 | MakeResult.Add(edge); |
221 | } |
222 | } |
223 | return MakeResult.Wire() ; |
224 | |
225 | } |
226 | |
51a849d7 |
227 | //======================================================================= |
228 | //function : ConcatenateWireC0 |
229 | //purpose : |
230 | //======================================================================= |
231 | |
232 | TopoDS_Edge BRepAlgo::ConcatenateWireC0(const TopoDS_Wire& aWire) |
233 | { |
234 | Standard_Real LinTol = Precision::Confusion(); |
235 | Standard_Real AngTol = Precision::Angular(); |
236 | |
237 | TopoDS_Edge ResEdge; |
7fd59977 |
238 | |
51a849d7 |
239 | TopoDS_Wire theWire = aWire; |
240 | BRepLib::BuildCurves3d(theWire); |
241 | Handle(ShapeFix_Shape) Fixer = new ShapeFix_Shape(theWire); |
242 | Fixer->SetPrecision(LinTol); |
243 | Fixer->SetMaxTolerance(LinTol); |
244 | Fixer->Perform(); |
245 | theWire = TopoDS::Wire(Fixer->Shape()); |
246 | |
247 | TColGeom_SequenceOfCurve CurveSeq; |
51a849d7 |
248 | TColStd_SequenceOfReal FparSeq; |
249 | TColStd_SequenceOfReal LparSeq; |
250 | TColStd_SequenceOfReal TolSeq; |
6f005d2a |
251 | TColStd_SequenceOfBoolean IsFwdSeq; |
1d47d8d0 |
252 | GeomAbs_CurveType CurType = GeomAbs_OtherCurve; |
51a849d7 |
253 | TopoDS_Vertex FirstVertex, LastVertex; |
51a849d7 |
254 | |
6f005d2a |
255 | BRepTools_WireExplorer wexp(theWire); |
51a849d7 |
256 | |
6f005d2a |
257 | for (; wexp.More(); wexp.Next()) { |
258 | TopoDS_Edge anEdge = wexp.Current(); |
259 | Standard_Real fpar, lpar; |
260 | Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar); |
51a849d7 |
261 | |
6f005d2a |
262 | if (aCurve.IsNull()) |
263 | continue; |
51a849d7 |
264 | |
6f005d2a |
265 | GeomAdaptor_Curve aGACurve(aCurve); |
266 | GeomAbs_CurveType aType = aGACurve.GetType(); |
267 | Handle(Geom_Curve) aBasisCurve = aGACurve.Curve(); |
268 | Standard_Boolean isFwd = (wexp.Orientation() != TopAbs_REVERSED); |
51a849d7 |
269 | |
6f005d2a |
270 | if (aBasisCurve->IsPeriodic()) { |
271 | ElCLib::AdjustPeriodic |
272 | (aBasisCurve->FirstParameter(), aBasisCurve->LastParameter(), |
273 | Precision::PConfusion(), fpar, lpar); |
274 | |
275 | |
276 | |
277 | } |
278 | |
279 | if (CurveSeq.IsEmpty()) { |
280 | CurveSeq.Append(aCurve); |
281 | FparSeq.Append(fpar); |
282 | LparSeq.Append(lpar); |
283 | IsFwdSeq.Append(isFwd); |
284 | CurType = aType; |
285 | FirstVertex = wexp.CurrentVertex(); |
286 | } else { |
287 | Standard_Boolean isSameCurve = Standard_False; |
498ce76b |
288 | Standard_Real NewFpar = RealFirst(), NewLpar = RealLast(); |
6f005d2a |
289 | GeomAdaptor_Curve GAprevcurve(CurveSeq.Last()); |
290 | |
291 | if (aCurve == CurveSeq.Last()) { |
292 | NewFpar = fpar; |
293 | NewLpar = lpar; |
294 | isSameCurve = Standard_True; |
295 | } else if (aType == CurType && |
296 | aType != GeomAbs_BezierCurve && |
297 | aType != GeomAbs_BSplineCurve && |
298 | aType != GeomAbs_OtherCurve) { |
299 | switch (aType) { |
300 | case GeomAbs_Line: |
301 | { |
302 | gp_Lin aLine = aGACurve.Line(); |
303 | gp_Lin PrevLine = GAprevcurve.Line(); |
304 | |
305 | if (aLine.Contains(PrevLine.Location(), LinTol) && |
306 | aLine.Direction().IsParallel(PrevLine.Direction(), AngTol)) { |
307 | gp_Pnt P1 = ElCLib::Value(fpar, aLine); |
308 | gp_Pnt P2 = ElCLib::Value(lpar, aLine); |
309 | |
310 | NewFpar = ElCLib::Parameter(PrevLine, P1); |
311 | NewLpar = ElCLib::Parameter(PrevLine, P2); |
312 | isSameCurve = Standard_True; |
313 | } |
314 | break; |
315 | } |
316 | case GeomAbs_Circle: |
317 | { |
318 | gp_Circ aCircle = aGACurve.Circle(); |
319 | gp_Circ PrevCircle = GAprevcurve.Circle(); |
320 | |
321 | if (aCircle.Location().Distance(PrevCircle.Location()) <= LinTol && |
322 | Abs(aCircle.Radius() - PrevCircle.Radius()) <= LinTol && |
323 | aCircle.Axis().IsParallel(PrevCircle.Axis(), AngTol)) { |
324 | gp_Pnt P1 = ElCLib::Value(fpar, aCircle); |
325 | gp_Pnt P2 = ElCLib::Value(lpar, aCircle); |
326 | |
327 | NewFpar = ElCLib::Parameter(PrevCircle, P1); |
328 | NewLpar = ElCLib::Parameter(PrevCircle, P2); |
329 | isSameCurve = Standard_True; |
330 | } |
331 | break; |
332 | } |
333 | case GeomAbs_Ellipse: |
334 | { |
335 | gp_Elips anEllipse = aGACurve.Ellipse(); |
336 | gp_Elips PrevEllipse = GAprevcurve.Ellipse(); |
337 | |
338 | if (anEllipse.Focus1().Distance(PrevEllipse.Focus1()) <= LinTol && |
339 | anEllipse.Focus2().Distance(PrevEllipse.Focus2()) <= LinTol && |
340 | Abs(anEllipse.MajorRadius() - PrevEllipse.MajorRadius()) <= LinTol && |
341 | Abs(anEllipse.MinorRadius() - PrevEllipse.MinorRadius()) <= LinTol && |
342 | anEllipse.Axis().IsParallel(PrevEllipse.Axis(), AngTol)) { |
343 | gp_Pnt P1 = ElCLib::Value(fpar, anEllipse); |
344 | gp_Pnt P2 = ElCLib::Value(lpar, anEllipse); |
345 | |
346 | NewFpar = ElCLib::Parameter(PrevEllipse, P1); |
347 | NewLpar = ElCLib::Parameter(PrevEllipse, P2); |
348 | isSameCurve = Standard_True; |
349 | } |
350 | break; |
351 | } |
352 | case GeomAbs_Hyperbola: |
353 | { |
354 | gp_Hypr aHypr = aGACurve.Hyperbola(); |
355 | gp_Hypr PrevHypr = GAprevcurve.Hyperbola(); |
356 | |
357 | if (aHypr.Focus1().Distance(PrevHypr.Focus1()) <= LinTol && |
358 | aHypr.Focus2().Distance(PrevHypr.Focus2()) <= LinTol && |
359 | Abs(aHypr.MajorRadius() - PrevHypr.MajorRadius()) <= LinTol && |
360 | Abs(aHypr.MinorRadius() - PrevHypr.MinorRadius()) <= LinTol && |
361 | aHypr.Axis().IsParallel(PrevHypr.Axis(), AngTol)) { |
362 | gp_Pnt P1 = ElCLib::Value(fpar, aHypr); |
363 | gp_Pnt P2 = ElCLib::Value(lpar, aHypr); |
364 | |
365 | NewFpar = ElCLib::Parameter(PrevHypr, P1); |
366 | NewLpar = ElCLib::Parameter(PrevHypr, P2); |
367 | isSameCurve = Standard_True; |
368 | } |
369 | break; |
370 | } |
371 | case GeomAbs_Parabola: |
372 | { |
373 | gp_Parab aParab = aGACurve.Parabola(); |
374 | gp_Parab PrevParab = GAprevcurve.Parabola(); |
375 | |
376 | if (aParab.Location().Distance(PrevParab.Location()) <= LinTol && |
377 | aParab.Focus().Distance(PrevParab.Focus()) <= LinTol && |
378 | Abs(aParab.Focal() - PrevParab.Focal()) <= LinTol && |
379 | aParab.Axis().IsParallel(PrevParab.Axis(), AngTol)) { |
380 | gp_Pnt P1 = ElCLib::Value(fpar, aParab); |
381 | gp_Pnt P2 = ElCLib::Value(lpar, aParab); |
382 | |
383 | NewFpar = ElCLib::Parameter(PrevParab, P1); |
384 | NewLpar = ElCLib::Parameter(PrevParab, P2); |
385 | isSameCurve = Standard_True; |
386 | } |
387 | break; |
388 | } |
389 | default: |
390 | break; |
391 | } //end of switch |
392 | } //end of else |
393 | |
394 | if (isSameCurve) { |
395 | const Standard_Boolean isSameDir = (isFwd == IsFwdSeq.Last()); |
396 | |
397 | if (aBasisCurve->IsPeriodic()) { |
398 | // Treat periodic curves. |
399 | const Standard_Real aPeriod = aBasisCurve->Period(); |
400 | |
401 | if (isSameDir) { |
402 | // Check if first parameter is greater then the last one. |
403 | while (NewFpar > NewLpar) { |
404 | NewFpar -= aPeriod; |
405 | } |
406 | } else { // !isSameDir |
407 | // Check if last parameter is greater then the first one. |
408 | while (NewLpar > NewFpar) { |
409 | NewLpar -= aPeriod; |
410 | } |
411 | |
412 | // Change parameters |
413 | const Standard_Real aTmpPar = NewLpar; |
414 | |
415 | NewLpar = NewFpar; |
416 | NewFpar = aTmpPar; |
417 | } |
418 | |
419 | // Udjust parameters on periodic curves. |
420 | if (IsFwdSeq.Last()) { |
421 | // The current curve should be after the previous one. |
422 | ElCLib::AdjustPeriodic(LparSeq.Last(), LparSeq.Last() + aPeriod, |
423 | Precision::PConfusion(), NewFpar, NewLpar); |
424 | } else { |
425 | // The current curve should be before the previous one. |
426 | ElCLib::AdjustPeriodic(FparSeq.Last() - aPeriod, FparSeq.Last(), |
427 | Precision::PConfusion(), NewFpar, NewLpar); |
428 | } |
429 | } else if (!isSameDir) { |
430 | // Not periodic curves. Opposite dirs. |
431 | const Standard_Real aTmpPar = NewLpar; |
432 | |
433 | NewLpar = NewFpar; |
434 | NewFpar = aTmpPar; |
435 | } |
436 | |
437 | if (IsFwdSeq.Last()) { |
438 | // Update last parameter |
439 | LparSeq(LparSeq.Length()) = NewLpar; |
440 | } else { |
441 | // Update first parameter |
442 | FparSeq(FparSeq.Length()) = NewFpar; |
443 | } |
444 | } else { |
445 | // Add new curve. |
446 | CurveSeq.Append(aCurve); |
447 | FparSeq.Append(fpar); |
448 | LparSeq.Append(lpar); |
449 | IsFwdSeq.Append(isFwd); |
450 | TolSeq.Append(BRep_Tool::Tolerance(wexp.CurrentVertex())); |
451 | CurType = aType; |
452 | } |
51a849d7 |
453 | } |
6f005d2a |
454 | } |
455 | |
51a849d7 |
456 | LastVertex = wexp.CurrentVertex(); |
457 | TolSeq.Append(BRep_Tool::Tolerance(LastVertex)); |
458 | |
6f005d2a |
459 | Standard_Boolean isReverse = Standard_False; |
460 | |
461 | if (!IsFwdSeq.IsEmpty()) { |
462 | isReverse = !IsFwdSeq(1); |
463 | } |
464 | |
465 | TopoDS_Vertex FirstVtx_final = (isReverse)? LastVertex : FirstVertex; |
51a849d7 |
466 | FirstVtx_final.Orientation(TopAbs_FORWARD); |
6f005d2a |
467 | TopoDS_Vertex LastVtx_final = (isReverse)? FirstVertex : LastVertex; |
51a849d7 |
468 | LastVtx_final.Orientation(TopAbs_REVERSED); |
469 | |
470 | if (CurveSeq.IsEmpty()) |
471 | return ResEdge; |
7fd59977 |
472 | |
51a849d7 |
473 | Standard_Integer nb_curve = CurveSeq.Length(); //number of curves |
474 | TColGeom_Array1OfBSplineCurve tab(0,nb_curve-1); //array of the curves |
475 | TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2); //array of the tolerances |
7fd59977 |
476 | |
51a849d7 |
477 | Standard_Integer i; |
478 | |
479 | if (nb_curve > 1) |
480 | { |
481 | for (i = 1; i <= nb_curve; i++) |
482 | { |
483 | if (CurveSeq(i)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) |
484 | CurveSeq(i) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(i))))->BasisCurve(); |
485 | |
486 | Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(CurveSeq(i), FparSeq(i), LparSeq(i)); |
487 | tab(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve); |
51a849d7 |
488 | GeomConvert::C0BSplineToC1BSplineCurve(tab(i-1), Precision::Confusion()); |
6f005d2a |
489 | |
490 | if (!IsFwdSeq(i)) { |
51a849d7 |
491 | tab(i-1)->Reverse(); |
6f005d2a |
492 | } |
51a849d7 |
493 | |
494 | //Temporary |
495 | //char* name = new char[100]; |
496 | //sprintf(name, "c%d", i); |
497 | //DrawTrSurf::Set(name, tab(i-1)); |
498 | |
499 | if (i > 1) |
500 | tabtolvertex(i-2) = TolSeq(i-1) * 5.; |
501 | } |
502 | tabtolvertex(nb_curve-1) = TolSeq(TolSeq.Length()) * 5.; |
503 | |
504 | Standard_Boolean closed_flag = Standard_False; |
505 | Standard_Real closed_tolerance = 0.; |
506 | if (FirstVertex.IsSame(LastVertex) && |
507 | GeomLProp::Continuity(tab(0), tab(nb_curve-1), |
508 | tab(0)->FirstParameter(), |
509 | tab(nb_curve-1)->LastParameter(), |
510 | Standard_False, Standard_False, LinTol, AngTol) >= GeomAbs_G1) |
511 | { |
512 | closed_flag = Standard_True ; |
513 | closed_tolerance = BRep_Tool::Tolerance(FirstVertex); |
514 | } |
515 | |
516 | Handle(TColGeom_HArray1OfBSplineCurve) concatcurve; //array of the concatenated curves |
517 | Handle(TColStd_HArray1OfInteger) ArrayOfIndices; //array of the remining Vertex |
518 | GeomConvert::ConcatC1(tab, |
519 | tabtolvertex, |
520 | ArrayOfIndices, |
521 | concatcurve, |
522 | closed_flag, |
523 | closed_tolerance); //C1 concatenation |
524 | |
525 | if (concatcurve->Length() > 1) |
526 | { |
527 | Standard_Real MaxTolVer = LinTol; |
528 | for (i = 1; i <= TolSeq.Length(); i++) |
529 | if (TolSeq(i) > MaxTolVer) |
530 | MaxTolVer = TolSeq(i); |
531 | MaxTolVer *= 5.; |
532 | |
533 | GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower())); |
534 | |
535 | for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++) |
536 | Concat.Add( concatcurve->Value(i), MaxTolVer, Standard_True ); |
537 | |
538 | concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve()); |
539 | } |
540 | |
541 | ResEdge = BRepLib_MakeEdge(concatcurve->Value(concatcurve->Lower()), |
542 | FirstVtx_final, LastVtx_final, |
543 | concatcurve->Value(concatcurve->Lower())->FirstParameter(), |
544 | concatcurve->Value(concatcurve->Lower())->LastParameter()); |
545 | } |
546 | else |
547 | { |
548 | if (CurveSeq(1)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) |
549 | CurveSeq(1) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(1))))->BasisCurve(); |
6f005d2a |
550 | |
551 | Handle(Geom_Curve) aCopyCurve = |
552 | Handle(Geom_Curve)::DownCast(CurveSeq(1)->Copy()); |
553 | |
554 | ResEdge = BRepLib_MakeEdge(aCopyCurve, |
51a849d7 |
555 | FirstVtx_final, LastVtx_final, |
556 | FparSeq(1), LparSeq(1)); |
557 | } |
558 | |
6f005d2a |
559 | if (isReverse) |
51a849d7 |
560 | ResEdge.Reverse(); |
561 | |
562 | return ResEdge; |
563 | } |