0022492: Scaled sphere (Solid with BSplineSurface) is wrongly exported in STEP.
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_WireDivide.cxx
CommitLineData
7fd59977 1// File: ShapeUpgrade_FaceDivide.cxx
2// Created: Thu Apr 15 13:10:17 1999
3// Author: Roman LYGIN
4// <rln@kinox.nnov.matra-dtv.fr>
5// gka 23.06.99 S4208: using tool SU_TransferParameter
6// pdn 13.07.99 synchronizing splitting values on 3d curve and pcurve
7// abv 14.07.99 dealing with edges without 3d curve
8// svv 10.01.00 porting on DEC
9
10#include <ShapeUpgrade_WireDivide.ixx>
11#include <ShapeUpgrade.hxx>
12#include <BRep_Tool.hxx>
13#include <BRep_Builder.hxx>
14#include <BRepLib_MakeFace.hxx>
15#include <BRepLib_MakeWire.hxx>
16#include <TopoDS.hxx>
17#include <TopoDS_Vertex.hxx>
18#include <TopoDS_Edge.hxx>
19#include <TopoDS_Iterator.hxx>
20#include <ShapeBuild_Edge.hxx>
21#include <ShapeAnalysis_Edge.hxx>
22#include <Precision.hxx>
23#include <TopExp.hxx>
24#include <TopExp_Explorer.hxx>
25#include <TColStd_HSequenceOfReal.hxx>
26#include <TColGeom_HArray1OfCurve.hxx>
27#include <TColGeom2d_HArray1OfCurve.hxx>
28#include <gp_Pnt.hxx>
29#include <Geom_Curve.hxx>
30#include <Geom2d_Curve.hxx>
31#include <ShapeExtend.hxx>
32#include <TColStd_Array1OfBoolean.hxx>
33#include <ShapeBuild_ReShape.hxx>
34#include <ShapeAnalysis_TransferParametersProj.hxx>
35#include <ShapeUpgrade_FixSmallCurves.hxx>
36#include <TopTools_SequenceOfShape.hxx>
37#include <TColStd_SequenceOfReal.hxx>
38#include <GeomAdaptor_HSurface.hxx>
39#include <Geom2dAdaptor_HCurve.hxx>
40#include <ShapeAnalysis_Curve.hxx>
41#include <Adaptor3d_CurveOnSurface.hxx>
42
43//=======================================================================
44//function : ShapeUpgrade_WireDivide
45//purpose :
46//=======================================================================
47
48ShapeUpgrade_WireDivide::ShapeUpgrade_WireDivide():
49 ShapeUpgrade_Tool(), myStatus(0)
50{
51// if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide"<<endl;
52 mySplitCurve3dTool = new ShapeUpgrade_SplitCurve3d;
53 mySplitCurve2dTool = new ShapeUpgrade_SplitCurve2d;
54 myTransferParamTool = new ShapeAnalysis_TransferParametersProj;
55 myEdgeMode = 2;
56 myFixSmallCurveTool = new ShapeUpgrade_FixSmallCurves;
57 myEdgeDivide = new ShapeUpgrade_EdgeDivide;
58}
59
60//=======================================================================
61//function : Init
62//purpose :
63//=======================================================================
64
65void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W,
66 const TopoDS_Face& F)
67{
68// if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide::Init with Wire, Face"<<endl;
69 myWire = W;
70 myFace = F;
71 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
72}
73
74//=======================================================================
75//function : Init
76//purpose :
77//=======================================================================
78
79void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W,
80 const Handle(Geom_Surface)& S)
81{
82// if (ShapeUpgrade::Debug()) cout <<"ShapeUpgrade_WireDivide::Init with Wire, Surface "<<endl;
83 myWire = W;
1c72dff6 84 BRepLib_MakeFace mkf(S, Precision::Confusion());
7fd59977 85 myFace = mkf.Face();
86 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
87}
88
89//=======================================================================
90//function : Load
91//purpose :
92//=======================================================================
93
94void ShapeUpgrade_WireDivide::Load(const TopoDS_Wire& W)
95{
96 myWire = W;
97}
98
99//=======================================================================
100//function : Load
101//purpose :
102//=======================================================================
103
104void ShapeUpgrade_WireDivide::Load(const TopoDS_Edge& E)
105{
106 BRepLib_MakeWire MakeWire (E);
107 if (MakeWire.IsDone())
108 Load (MakeWire.Wire());
109}
110
111//=======================================================================
112//function : SetFace
113//purpose :
114//=======================================================================
115
116void ShapeUpgrade_WireDivide::SetFace(const TopoDS_Face& F)
117{
118 myFace = F;
119}
120
121//=======================================================================
122//function : SetSurface
123//purpose :
124//=======================================================================
125
126void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S)
127{
1c72dff6 128 BRepLib_MakeFace mkf(S, Precision::Confusion());
7fd59977 129 myFace = mkf.Face();
130}
131
132//=======================================================================
133//function : SetSurface
134//purpose :
135//=======================================================================
136
137void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S,
138 const TopLoc_Location& L)
139{
140 BRep_Builder B;
141 B.MakeFace(myFace,S,L,Precision::Confusion());
142}
143
144//=======================================================================
145//function : Perform
146//purpose :
147//=======================================================================
148
149static void CorrectSplitValues(const Handle(TColStd_HSequenceOfReal) orig3d,
150 const Handle(TColStd_HSequenceOfReal) orig2d,
151 Handle(TColStd_HSequenceOfReal) new2d,
152 Handle(TColStd_HSequenceOfReal) new3d)
153{
154 Standard_Real preci = Precision::PConfusion();
155 Standard_Integer len3d = orig3d->Length();
156 Standard_Integer len2d = orig2d->Length();
157 TColStd_Array1OfBoolean fixNew2d (1, len3d);
158 fixNew2d.Init (Standard_False);
159 TColStd_Array1OfBoolean fixNew3d (1, len2d);
160 fixNew3d.Init (Standard_False);
161 Standard_Real Last3d = orig3d->Value(len3d);
162 Standard_Real Last2d = orig2d->Value(len2d);
163
164 Standard_Integer i;// svv #1
165 for( i = 1; i <= len3d ; i++) {
166 Standard_Real par = new2d->Value(i);
167 Standard_Integer index = 0;
168 for(Standard_Integer j = 1; j <= len2d && !index; j++)
169 if(Abs(par-orig2d->Value(j)) < preci)
170 index = j;
171 if(index&&!fixNew3d(index)) {
172 Standard_Real newPar = orig2d->Value(index);
173 new2d->SetValue(i,newPar);
174 fixNew2d(i) = Standard_True;
175 Standard_Real newPar3d = orig3d->Value(i);
176 new3d->SetValue(index,newPar3d);
177 fixNew3d(index) = Standard_True;
178 }
179 }
180
181 for(i = 1; i <= len2d ; i++) {
182 Standard_Real par = new3d->Value(i);
183 Standard_Integer index = 0;
184 for(Standard_Integer j = 1; j <= len3d && !index; j++)
185 if(Abs(par-orig3d->Value(j)) < preci)
186 index = j;
187 if(index&&!fixNew2d(index)) {
188 Standard_Real newPar = orig3d->Value(index);
189 new3d->SetValue(i,newPar);
190 fixNew3d(i) = Standard_True;
191 Standard_Real newPar2d = orig2d->Value(i);
192 new2d->SetValue(index,newPar2d);
193 fixNew2d(index) = Standard_True;
194 }
195 }
196
197 Standard_Real dpreci = 2* preci;
198 for(i = 1; i < len3d; i++) {
199 Standard_Real dist = new2d->Value(i+1) - new2d->Value(i);
200 if(dist < preci) {
201 if(fixNew2d(i+1)) {
202 //changing
203 Standard_Real tmp = new2d->Value(i+1);
204 new2d->SetValue(i+1,new2d->Value(i)+dpreci);
205 new2d->SetValue(i,tmp);
206 fixNew2d(i) = Standard_True;
207 fixNew2d(i+1) = Standard_False;
208 }
209 else
210 new2d->SetValue(i+1,new2d->Value(i)+dpreci);
211 }
212 }
213 if(new2d->Value(len3d) > Last3d) {
214 Standard_Integer ind; // svv #1
215 for( ind = len3d; ind > 1 && !fixNew2d(ind); ind--);
216 Standard_Real lastFix = new2d->Value(ind);
217 for(i = len3d; i >= ind; i--) {
218 new2d->SetValue(i,lastFix);
219 lastFix-=dpreci;
220 }
221 }
222
223 for(i = 1; i < len2d; i++) {
224 Standard_Real dist = new3d->Value(i+1) - new3d->Value(i);
225 if(dist < preci) {
226 if(fixNew3d(i+1)) {
227 //changing
228 Standard_Real tmp = new3d->Value(i+1);
229 new3d->SetValue(i+1,new3d->Value(i)+dpreci);
230 new3d->SetValue(i,tmp);
231 fixNew3d(i) = Standard_True;
232 fixNew3d(i+1) = Standard_False;
233 }
234 else
235 new3d->SetValue(i+1,new3d->Value(i)+dpreci);
236 }
237 }
238 if(new3d->Value(len2d) > Last2d) {
239 Standard_Integer ind; // svv #1
240 for(ind = len2d; ind > 1 && !fixNew3d(ind); ind--);
241 Standard_Real lastFix = new3d->Value(ind);
242 for(i = len2d; i >= ind; i--) {
243 new3d->SetValue(i,lastFix);
244 lastFix-=dpreci;
245 }
246 }
247}
248
249void ShapeUpgrade_WireDivide::Perform ()
250{
251
252 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
253
254// if (ShapeUpgrade::Debug()) cout << "ShapeUpgrade_WireDivide::Perform" << endl;
255
256 BRep_Builder B;
257 ShapeAnalysis_Edge sae;
258
259 TopoDS_Wire newWire;
260 B.MakeWire (newWire);
261 TopLoc_Location Loc;
262 Handle(Geom_Surface) Surf;
263 if(!myFace.IsNull())
264 Surf = BRep_Tool::Surface(myFace, Loc);
265
266 Standard_Boolean isSplit3d = Standard_True;
267 switch(myEdgeMode) {
268 case 0: if(!myFace.IsNull()) isSplit3d = Standard_False; break;
269 case 1: if(myFace.IsNull()) isSplit3d = Standard_False; break;
270 default : break;
271 }
272 myEdgeDivide->SetFace(myFace);
273 if(isSplit3d)
274 myEdgeDivide->SetSplitCurve3dTool(GetSplitCurve3dTool());
275 myEdgeDivide->SetSplitCurve2dTool(GetSplitCurve2dTool());
276 for (TopoDS_Iterator ItW (myWire,Standard_False); ItW.More(); ItW.Next()) {
277 // for each Edge:
278 TopoDS_Shape sh = Context()->Apply(ItW.Value(),TopAbs_SHAPE);
279 for(TopExp_Explorer exp(sh,TopAbs_EDGE); exp.More(); exp.Next()) {
280 TopoDS_Edge E = TopoDS::Edge(exp.Current());
281// if (ShapeUpgrade::Debug()) cout << ".. Edge " << (void*) &(*E.TShape()) << endl;
282
283 // skip degenerated edges (and also INTERNAL/EXTERNAL, to avoid failures)
284 if ( E.Orientation() == TopAbs_INTERNAL || E.Orientation() == TopAbs_EXTERNAL ) {
285 B.Add ( newWire, E );
286 continue;
287 }
288
289 if(!myEdgeDivide->Compute(E)) {
290 B.Add ( newWire, E );
291 continue;
292 }
293 // first iteration: getting split knots
294 // on 3D curve: preliminary
295
296 Handle(ShapeAnalysis_TransferParameters) theTransferParamTool = GetTransferParamTool();
297 theTransferParamTool->SetMaxTolerance(MaxTolerance());
298 theTransferParamTool->Init(E,myFace);
299 Standard_Boolean wasSR = theTransferParamTool->IsSameRange();
300
301 // on pcurve(s): all knots
302 // assume that if seam-edge, its pcurve1 and pcurve2 has the same split knots !!!
303 Handle(TColStd_HSequenceOfReal) theKnots3d = myEdgeDivide->Knots3d();
304 Handle(TColStd_HSequenceOfReal) theKnots2d = myEdgeDivide->Knots2d();
305
306 // second iteration: transfer parameters and build segments
307 Handle(TColStd_HSequenceOfReal) SplitValues2d;
308 Handle(TColStd_HSequenceOfReal) SplitValues3d;
309 if(myEdgeDivide->HasCurve2d() && myEdgeDivide->HasCurve3d() ) {
310 SplitValues2d = theTransferParamTool->Perform(theKnots3d,Standard_True);
311 SplitValues3d = theTransferParamTool->Perform(theKnots2d,Standard_False);
312 CorrectSplitValues(theKnots3d,theKnots2d,SplitValues2d,SplitValues3d);
313 }
314 Handle(ShapeUpgrade_SplitCurve3d) theSplit3dTool = myEdgeDivide->GetSplitCurve3dTool();
315 Handle(ShapeUpgrade_SplitCurve2d) theSplit2dTool = myEdgeDivide->GetSplitCurve2dTool();
316
317 if ( myEdgeDivide->HasCurve2d() ) {
318 if(! theKnots3d.IsNull() ) {
319 SplitValues2d->Remove(1);
320 SplitValues2d->Remove(SplitValues2d->Length());
321 theSplit2dTool->SetSplitValues (SplitValues2d);
322 }
323 theSplit2dTool->Build(Standard_True);
324 }
325 if ( myEdgeDivide->HasCurve3d() ) {
326 if( ! theKnots2d.IsNull() ) {
327 SplitValues3d->Remove(1);
328 SplitValues3d->Remove(SplitValues3d->Length());
329 theSplit3dTool->SetSplitValues (SplitValues3d);
330 }
331 theSplit3dTool->Build (Standard_True);
332 }
333 // get 2d and 3d split values which should be the same
334 if ( myEdgeDivide->HasCurve2d() ) theKnots2d = theSplit2dTool->SplitValues();
335 if ( myEdgeDivide->HasCurve3d() ) theKnots3d = theSplit3dTool->SplitValues();
336
337 Standard_Boolean isSeam = Standard_False;
338 if (! myFace.IsNull() )
339 isSeam = BRep_Tool::IsClosed ( E, myFace );
340 Handle(TColGeom2d_HArray1OfCurve) theSegments2d;
341 if(myEdgeDivide->HasCurve2d())
342 theSegments2d = theSplit2dTool->GetCurves();
343 Handle(TColGeom2d_HArray1OfCurve) theSegments2dR;
344 if ( isSeam ) {
345 Handle(Geom2d_Curve) c2;
346 Standard_Real f2, l2;
347//smh#8
348 TopoDS_Shape tmpE = E.Reversed();
349 TopoDS_Edge erev = TopoDS::Edge (tmpE );
350 if ( sae.PCurve ( erev, myFace, c2, f2, l2, Standard_False) ) {
351 theSplit2dTool->Init (c2, f2, l2);
352 if(!theKnots2d.IsNull())
353 theSplit2dTool->SetSplitValues (theKnots2d);
354 theSplit2dTool->Perform (Standard_True);
355 Handle(TColStd_HSequenceOfReal) revKnots2d = theSplit2dTool->SplitValues();
356 if(revKnots2d->Length()!=revKnots2d->Length()) {
357 isSeam = Standard_False;
358#ifdef DEB
359 cout << "Error: ShapeUpgrade_WireDivide: seam has different splitting values on pcurvesd" << endl;
360#endif
361 }
362 else
363 theSegments2dR = theSplit2dTool->GetCurves();
364 }
365 else isSeam = Standard_False;
366 }
367
368 // Exploring theEdge
369 TopoDS_Vertex V1o = TopExp::FirstVertex (E, Standard_False);
370 TopoDS_Vertex V2o = TopExp::LastVertex (E, Standard_False);
371 Standard_Boolean isForward = ( E.Orientation() == TopAbs_FORWARD );
372 Standard_Real TolEdge = BRep_Tool::Tolerance (E);
373 Standard_Boolean isDeg = BRep_Tool::Degenerated ( E );
374
375 // Copy vertices to protect original shape against SameParamseter
376//smh#8
377 TopoDS_Shape emptyCopiedV1 = V1o.EmptyCopied();
378 TopoDS_Vertex V1 = TopoDS::Vertex ( emptyCopiedV1 );
379 Context()->Replace ( V1o, V1 );
380 TopoDS_Vertex V2;
381 if ( V1o.IsSame ( V2o ) ) {
382//smh#8
383 TopoDS_Shape tmpV = V1.Oriented(V2o.Orientation() );
384 V2 = TopoDS::Vertex ( tmpV );
385 }
386 else {
387//smh#8
388 TopoDS_Shape emptyCopied = V2o.EmptyCopied();
389 V2 = TopoDS::Vertex ( emptyCopied );
390 Context()->Replace ( V2o, V2 );
391 }
392
393 //collect NM vertices
394
395 Standard_Real af,al;
396 Handle(Geom_Curve) c3d;
397 Adaptor3d_CurveOnSurface AdCS;
398 if(myEdgeDivide->HasCurve3d())
399 sae.Curve3d(E,c3d,af,al,Standard_False);
400 else if(myEdgeDivide->HasCurve2d() && !Surf.IsNull()) {
401 Handle(Geom2d_Curve) c2d;
402 sae.PCurve ( E, myFace, c2d, af, al, Standard_False);
403 Handle(GeomAdaptor_HSurface) AdS = new GeomAdaptor_HSurface(Surf);
404 Handle(Geom2dAdaptor_HCurve) AC2d = new Geom2dAdaptor_HCurve(c2d,af,al);
405 AdCS.Load(AC2d);
406 AdCS.Load(AdS);
407 }
408 TopTools_SequenceOfShape aSeqNMVertices;
409 TColStd_SequenceOfReal aSeqParNM;
410 TopoDS_Iterator aItv(E,Standard_False);
411 ShapeAnalysis_Curve sac;
412 for ( ; aItv.More() ; aItv.Next()) {
413 if(aItv.Value().Orientation() == TopAbs_INTERNAL ||
414 aItv.Value().Orientation() == TopAbs_EXTERNAL) {
415 TopoDS_Vertex aVold = TopoDS::Vertex(aItv.Value());
416 aSeqNMVertices.Append(aVold);
417 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aVold));
418 Standard_Real ppar;
419 gp_Pnt pproj;
420 if(!c3d.IsNull())
421 sac.Project(c3d,aP,Precision(),pproj,ppar,af,al,Standard_False);
422 else
423 sac.Project(AdCS,aP,Precision(),pproj,ppar);
424 aSeqParNM.Append(ppar);
425 }
426 }
427
428 // creating new edge(s)
429 Handle(TColGeom_HArray1OfCurve) theSegments3d;
430 if(myEdgeDivide->HasCurve3d()) theSegments3d = theSplit3dTool->GetCurves();
431
432 Standard_Integer nbc = 0;
433 if (!theSegments3d.IsNull()) {
434 nbc = theSegments3d->Length();
435 if ( !theSegments2d.IsNull() ) {
436 Standard_Integer nbc2d = theSegments2d->Length();
437 if (nbc!=nbc2d) {
438#ifdef DEB
439 cout<<"Error: Number of intervals are not equal for 2d 3d. Ignored."<<endl;
440#endif
441 nbc = Min( nbc,nbc2d);
442 }
443 }
444 }
445 else
446 if(!theSegments2d.IsNull())// if theSegments have different length ???
447 nbc = theSegments2d->Length();
448
449 if ( nbc <= 1 && ! theSplit3dTool->Status ( ShapeExtend_DONE ) &&
450 ! theSplit2dTool->Status ( ShapeExtend_DONE ) ) {
451 B.Add ( newWire, E );
452 continue;
453 }
454
455 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
456
457 TopoDS_Wire resWire;
458 B.MakeWire (resWire);
459// TopoDS_Vertex firstVertex, lastVertex;
460 Standard_Integer numE =0;
461 gp_Pnt pntV1 = BRep_Tool::Pnt(V1);
462 //gp_Pnt pntV2 = BRep_Tool::Pnt(V2); // pntV2 not used - see below (skl)
463 Standard_Real V1Tol = LimitTolerance( BRep_Tool::Tolerance(V1) );
464 //Standard_Real V2Tol = LimitTolerance( BRep_Tool::Tolerance(V2) ); // V2Tol not used - see below (skl)
465
466 Handle(ShapeUpgrade_FixSmallCurves) FixSmallCurveTool = GetFixSmallCurveTool(); //gka Precision
467 FixSmallCurveTool->SetMinTolerance(MinTolerance());
468 FixSmallCurveTool->Init(E, myFace);
469 FixSmallCurveTool->SetSplitCurve3dTool(theSplit3dTool);
470 FixSmallCurveTool->SetSplitCurve2dTool(theSplit2dTool);
471 FixSmallCurveTool->SetPrecision(MinTolerance());
472 Standard_Integer Savnum =0;
473 Standard_Real SavParf;
474 Standard_Integer Small = 0;
475 for ( Standard_Integer icurv = 1; icurv <= nbc; icurv++ ) {
476
477 Handle(Geom_Curve) theNewCurve3d;
478 if(!theSegments3d.IsNull()) theNewCurve3d = theSegments3d->Value(icurv);
479
480 Handle(Geom2d_Curve) theNewPCurve1;
481 if(!theSegments2d.IsNull()) theNewPCurve1 = theSegments2d->Value(icurv);
482 Handle(Geom2d_Curve) revPCurve;
483 if(isSeam)
484 revPCurve = theSegments2dR->Value(icurv);
485 // construction of the intermediate Vertex
486 TopoDS_Vertex V;
487 if ( icurv <= nbc && nbc != 1 && ! isDeg ) {
488 Standard_Real par,parf /*,SavParl*/;
489 //Standard_Real SaveParf; // SaveParf not used - see below (skl)
490 gp_Pnt P,P1,PM;
491 // if edge has 3d curve, take point from it
492 if ( ! theNewCurve3d.IsNull() ) {
493 if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
494 par = theNewCurve3d->LastParameter();
495 parf = theNewCurve3d->FirstParameter();
496 }
497 else {
498 par = theKnots3d->Value (icurv + 1);
499 parf = theKnots3d->Value (icurv);
500 }
501 P = theNewCurve3d->Value (par);
502 P1 = theNewCurve3d->Value (parf);
503 PM = theNewCurve3d->Value ((parf+par)/2);
504 }
505 // else use pcurve and surface (suppose that both exist)
506 else {
507 if ( Surf.IsNull() ) Surf = BRep_Tool::Surface ( myFace, Loc );
508 if ( theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) ) {
509 par = theNewPCurve1->LastParameter();
510 parf = theNewPCurve1->FirstParameter();
511 }
512 else {
513 par = theKnots2d->Value (icurv + 1);
514 parf = theKnots2d->Value (icurv);
515 }
516 gp_Pnt2d p2d = theNewPCurve1->Value (par);
517 gp_Pnt2d p2df = theNewPCurve1->Value (parf);
518 gp_Pnt2d p2dM = theNewPCurve1->Value ((parf+par)/2);
519 P = Surf->Value ( p2d.X(), p2d.Y() );
520 P1 = Surf->Value ( p2df.X(), p2df.Y() );
521 PM = Surf->Value ( p2dM.X(), p2dM.Y() );
522 P.Transform ( Loc.Transformation() );
523 P1.Transform ( Loc.Transformation() );
524 PM.Transform ( Loc.Transformation() );
525 }
526 if(P.Distance(pntV1) < MinTolerance() && P.Distance(PM) < MinTolerance() && !myFace.IsNull()) {
527 if(!Small) {
528 SavParf = parf;
529 Savnum = icurv;
530 }
531 //SavParl = par;
532 Small++;
533 if(icurv == nbc) {
534 TopoDS_Vertex VVV = V1;
535 VVV.Orientation ( V2.Orientation() );
536 Context()->Replace(V2,VVV);
537 }
538 continue;
539 }
540 if(Small) {
541 if(P.Distance(P1) > MinTolerance() || P.Distance(PM) > MinTolerance()) {
542 //FixSmallCurveTool->Perform(prevEdge,theNewCurve3d,theNewPCurve1,revPCurve,SavParf,SavParl);
543 gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() );
544 B.UpdateVertex(V1,pmid,0);
545 }
546 else {
547 Handle(Geom_Curve) atmpCurve;
548 Handle(Geom2d_Curve) atmpCurve2d1,atmprepcurve;
549 if(FixSmallCurveTool->Approx( atmpCurve,atmpCurve2d1,atmprepcurve,SavParf,par)) { //BRepTools
550 theNewCurve3d = atmpCurve;
551 theNewPCurve1 = atmpCurve2d1;
552 revPCurve = atmprepcurve;
553 }
554 else {
555 gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() );
556 B.UpdateVertex(V1,pmid,0);
557 }
558 }
559 Small =0;
560 }
561 //pdn
562 /* if(P.Distance (pntV1) < V1Tol)
563 V = V1;
564 else if (P.Distance (pntV2) < V2Tol) {
565 V = V2;
566 V1Tol = V2Tol;
567 pntV1 = pntV2;
568 }
569 else {*/
570 if(icurv != nbc) {
571 B.MakeVertex (V, P, TolEdge); //tolerance of the edge
572 pntV1 = P;
573 V1Tol = LimitTolerance( TolEdge );
574 }
575 else V = V2;
576 // else V2;
577 // }
578// if (ShapeUpgrade::Debug()) cout <<"... New intermediate Vertex ("
579// <<P.X()<<","<<P.Y()<<","<<P.Z()<<") :"<<(void*) &(*V.TShape())
580// <<" with Tolerance "<<TolEdge <<endl;
581 }
582 //else V = V2;
583
584 TopoDS_Edge newEdge;
585 ShapeBuild_Edge sbe;
586 if ( isForward ) {
587 V1.Orientation ( TopAbs_FORWARD );
588 V.Orientation ( TopAbs_REVERSED );
589 newEdge = sbe.CopyReplaceVertices ( E, V1, V );
590 }
591 else {
592 V1.Orientation ( TopAbs_REVERSED );
593 V.Orientation ( TopAbs_FORWARD );
594 newEdge = sbe.CopyReplaceVertices ( E, V, V1 );
595 }
596 sbe.CopyPCurves ( newEdge, E );
597 if(!theNewCurve3d.IsNull())
598 B.UpdateEdge ( newEdge, theNewCurve3d, 0. );
599 else if ( isDeg )
600 B.Degenerated( newEdge, Standard_True);
601 //if(isSeam) {
602 // Handle(Geom2d_Curve) revPCurve = theSegments2dR->Value(icurv);
603 //if(newEdge.Orientation()==TopAbs_FORWARD)
604 //B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. );
605 //else
606 //B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. );
607 //}
608 //else if ( ! myFace.IsNull() )
609 //B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. );
610
611 Standard_Real f3d = 0., l3d =0.;
612 if(!Savnum) Savnum = icurv;
613 Standard_Boolean srNew;
614 if(!theNewCurve3d.IsNull()) {
615 if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
616 f3d = theNewCurve3d->FirstParameter();
617 l3d = theNewCurve3d->LastParameter();
618 srNew = ((f3d == theKnots3d->Value (Savnum)) && (l3d == theKnots3d->Value (icurv + 1)));
619 }
620 else {
621 f3d = theKnots3d->Value (Savnum);
622 l3d = theKnots3d->Value (icurv + 1);
623 srNew = Standard_True;
624 }
625 }
626 else
627 srNew = Standard_True;
628
629 Standard_Real f2d=0, l2d=0;
630 if(!theNewPCurve1.IsNull()){
631 if(theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) {
632 f2d = theNewPCurve1->FirstParameter();
633 l2d = theNewPCurve1->LastParameter();
634 srNew &= ((f2d == theKnots2d->Value (Savnum)) && (l2d == theKnots2d->Value (icurv + 1)));
635 }
636 else {
637 f2d = theKnots2d->Value (Savnum);
638 l2d = theKnots2d->Value (icurv + 1);
639 }
640 }
641 //if(!Savnum) Savnum = icurv;
642 if(!theNewCurve3d.IsNull())
643 theTransferParamTool->TransferRange(newEdge,theKnots3d->Value (Savnum),theKnots3d->Value (icurv + 1),Standard_False);
644 else
645 theTransferParamTool->TransferRange(newEdge,theKnots2d->Value (Savnum),theKnots2d->Value (icurv + 1),Standard_True);
646 /*
647 Standard_Real alpha = (theKnots3d->Value (icurv) - f)/(l - f);
648 Standard_Real beta = (theKnots3d->Value (icurv + 1) - f)/(l - f);
649 sbe.CopyRanges(newEdge,E, alpha, beta);*/
650 Savnum =0;
651 Handle(Geom2d_Curve) c2dTmp;
652 Standard_Real setF, setL;
653 if( ! myFace.IsNull() && sae.PCurve (newEdge, myFace, c2dTmp, setF, setL, Standard_False))
654 srNew &= ( (setF==f2d) && (setL==l2d) );
655
656 if(isSeam) {
657 // Handle(Geom2d_Curve revPCurve = theSegments2dR->Value(icurv);
658 if(newEdge.Orientation()==TopAbs_FORWARD)
659 B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. );
660 else
661 B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. );
662 }
663 else if ( ! myFace.IsNull() ) {
664 B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. );
665 }
666
667 if(!theNewCurve3d.IsNull())
668 sbe.SetRange3d(newEdge,f3d,l3d);
669 if(!theNewPCurve1.IsNull())
670 B.Range ( newEdge, myFace, f2d, l2d);
671 if((!wasSR || !srNew)&&!BRep_Tool::Degenerated(newEdge) )
672 B.SameRange(newEdge, Standard_False);
673
674 //addition NM vertices to new edges
675 Standard_Real afpar = (myEdgeDivide->HasCurve3d() ? f3d : f2d);
676
677 Standard_Real alpar = (myEdgeDivide->HasCurve3d() ? l3d: l2d);
678 Standard_Integer n =1;
679 for( ; n <= aSeqParNM.Length(); n++) {
680 Standard_Real apar = aSeqParNM.Value(n);
681 TopoDS_Vertex aVold = TopoDS::Vertex(aSeqNMVertices.Value(n));
682 TopoDS_Vertex aNMVer =ShapeAnalysis_TransferParametersProj::CopyNMVertex(aVold,newEdge,E);
683 Context()->Replace(aVold,aNMVer);
684 if(fabs(apar - afpar) <= Precision::PConfusion())
685 Context()->Replace(aNMVer,V1);
686 else if(fabs(apar - alpar) <= Precision::PConfusion())
687 Context()->Replace(aNMVer,V);
688 else if( apar > afpar && apar <alpar)
689 B.Add (newEdge,aNMVer);
690 else continue;
691 aSeqNMVertices.Remove(n);
692 aSeqParNM.Remove(n);
693 n--;
694 }
695
696
697// if (ShapeUpgrade::Debug()) cout <<"... New Edge "
698// <<(void*) &(*newEdge.TShape())<<" on vertices "
699// <<(void*) &(*V1.TShape())<<", " <<(void*) &(*V.TShape())
700// <<" with Tolerance "<<TolEdge <<endl;
701 B.Add ( resWire, newEdge );
702 B.Add ( newWire, newEdge );
703 numE++;
704 V1 = V;
705 }
706 if(numE)
707 Context()->Replace(E,resWire);
708 else
709 Context()->Remove(E);
710 }
711 }
712 if ( Status ( ShapeExtend_DONE ) ) {
713//smh#8
714 TopoDS_Shape tmpW = Context()->Apply ( newWire ).Oriented(myWire.Orientation());
715 myWire = TopoDS::Wire (tmpW );
716 }
717}
718
719//=======================================================================
720//function : Face
721//purpose :
722//=======================================================================
723
724const TopoDS_Wire& ShapeUpgrade_WireDivide::Wire() const
725{
726 return myWire;
727}
728
729//=======================================================================
730//function : Status
731//purpose :
732//=======================================================================
733
734Standard_Boolean ShapeUpgrade_WireDivide::Status (const ShapeExtend_Status status) const
735{
736 return ShapeExtend::DecodeStatus ( myStatus, status );
737}
738
739//=======================================================================
740//function : SetSplitCurve3dTool
741//purpose :
742//=======================================================================
743
744void ShapeUpgrade_WireDivide::SetSplitCurve3dTool(const Handle(ShapeUpgrade_SplitCurve3d)& splitCurve3dTool)
745{
746 mySplitCurve3dTool = splitCurve3dTool;
747}
748
749//=======================================================================
750//function : SetSplitCurve2dTool
751//purpose :
752//=======================================================================
753
754void ShapeUpgrade_WireDivide::SetSplitCurve2dTool(const Handle(ShapeUpgrade_SplitCurve2d)& splitCurve2dTool)
755{
756 mySplitCurve2dTool = splitCurve2dTool;
757}
758
759//=======================================================================
760//function : GetSplitCurve3dTool
761//purpose :
762//=======================================================================
763
764Handle(ShapeUpgrade_SplitCurve3d) ShapeUpgrade_WireDivide::GetSplitCurve3dTool() const
765{
766 return mySplitCurve3dTool;
767}
768
769//=======================================================================
770//function : GetSplitCurve2dTool
771//purpose :
772//=======================================================================
773
774Handle(ShapeUpgrade_SplitCurve2d) ShapeUpgrade_WireDivide::GetSplitCurve2dTool() const
775{
776 return mySplitCurve2dTool;
777}
778
779//=======================================================================
780//function : SetEdgeDivideTool
781//purpose :
782//=======================================================================
783
784void ShapeUpgrade_WireDivide::SetEdgeDivideTool(const Handle (ShapeUpgrade_EdgeDivide)& edgeDivideTool)
785{
786 myEdgeDivide = edgeDivideTool;
787}
788
789//=======================================================================
790//function : GetEdgeDivideTool
791//purpose :
792//=======================================================================
793
794Handle (ShapeUpgrade_EdgeDivide) ShapeUpgrade_WireDivide::GetEdgeDivideTool() const
795{
796 return myEdgeDivide;
797}
798
799//=======================================================================
800//function : SetTransferParamTool
801//purpose :
802//=======================================================================
803
804void ShapeUpgrade_WireDivide::SetTransferParamTool(const Handle(ShapeAnalysis_TransferParameters)& TransferParam)
805{
806 myTransferParamTool = TransferParam;
807}
808
809//=======================================================================
810//function : GetTransferParamTool
811//purpose :
812//=======================================================================
813
814Handle(ShapeAnalysis_TransferParameters) ShapeUpgrade_WireDivide::GetTransferParamTool()
815{
816 return myTransferParamTool;
817}
818
819//=======================================================================
820//function : SetEdgeMode
821//purpose :
822//=======================================================================
823
824 void ShapeUpgrade_WireDivide::SetEdgeMode(const Standard_Integer EdgeMode)
825{
826 myEdgeMode = EdgeMode;
827}
828
829//=======================================================================
830//function : SetFixSmallCurveTool
831//purpose :
832//=======================================================================
833
834 void ShapeUpgrade_WireDivide::SetFixSmallCurveTool(const Handle(ShapeUpgrade_FixSmallCurves)& FixSmallCurvesTool)
835{
836 myFixSmallCurveTool = FixSmallCurvesTool;
837}
838
839//=======================================================================
840//function : GetFixSmallCurveTool
841//purpose :
842//=======================================================================
843
844 Handle(ShapeUpgrade_FixSmallCurves) ShapeUpgrade_WireDivide::GetFixSmallCurveTool() const
845{
846 return myFixSmallCurveTool;
847}