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