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