1 // Created on: 1999-04-15
2 // Created by: Roman LYGIN
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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
22 #include <Adaptor3d_CurveOnSurface.hxx>
23 #include <BRep_Builder.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRepLib_MakeFace.hxx>
26 #include <BRepLib_MakeWire.hxx>
27 #include <Geom2d_BoundedCurve.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2dAdaptor_HCurve.hxx>
30 #include <Geom_BoundedCurve.hxx>
31 #include <Geom_Curve.hxx>
32 #include <Geom_Surface.hxx>
33 #include <GeomAdaptor_HSurface.hxx>
35 #include <Precision.hxx>
36 #include <ShapeAnalysis_Curve.hxx>
37 #include <ShapeAnalysis_Edge.hxx>
38 #include <ShapeAnalysis_TransferParameters.hxx>
39 #include <ShapeAnalysis_TransferParametersProj.hxx>
40 #include <ShapeBuild_Edge.hxx>
41 #include <ShapeBuild_ReShape.hxx>
42 #include <ShapeExtend.hxx>
43 #include <ShapeUpgrade.hxx>
44 #include <ShapeUpgrade_EdgeDivide.hxx>
45 #include <ShapeUpgrade_FixSmallCurves.hxx>
46 #include <ShapeUpgrade_SplitCurve2d.hxx>
47 #include <ShapeUpgrade_SplitCurve3d.hxx>
48 #include <ShapeUpgrade_WireDivide.hxx>
49 #include <Standard_Type.hxx>
50 #include <TColGeom2d_HArray1OfCurve.hxx>
51 #include <TColGeom_HArray1OfCurve.hxx>
52 #include <TColStd_Array1OfBoolean.hxx>
53 #include <TColStd_HSequenceOfReal.hxx>
54 #include <TColStd_SequenceOfReal.hxx>
56 #include <TopExp_Explorer.hxx>
57 #include <TopLoc_Location.hxx>
59 #include <TopoDS_Edge.hxx>
60 #include <TopoDS_Face.hxx>
61 #include <TopoDS_Iterator.hxx>
62 #include <TopoDS_Vertex.hxx>
63 #include <TopoDS_Wire.hxx>
64 #include <TopTools_SequenceOfShape.hxx>
66 IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_WireDivide,ShapeUpgrade_Tool)
68 //=======================================================================
69 //function : ShapeUpgrade_WireDivide
71 //=======================================================================
72 ShapeUpgrade_WireDivide::ShapeUpgrade_WireDivide():
73 ShapeUpgrade_Tool(), myStatus(0)
75 // if (ShapeUpgrade::Debug()) std::cout <<"ShapeUpgrade_WireDivide"<<std::endl;
76 mySplitCurve3dTool = new ShapeUpgrade_SplitCurve3d;
77 mySplitCurve2dTool = new ShapeUpgrade_SplitCurve2d;
78 myTransferParamTool = new ShapeAnalysis_TransferParametersProj;
80 myFixSmallCurveTool = new ShapeUpgrade_FixSmallCurves;
81 myEdgeDivide = new ShapeUpgrade_EdgeDivide;
84 //=======================================================================
87 //=======================================================================
89 void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W,
92 // if (ShapeUpgrade::Debug()) std::cout <<"ShapeUpgrade_WireDivide::Init with Wire, Face"<<std::endl;
95 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
98 //=======================================================================
101 //=======================================================================
103 void ShapeUpgrade_WireDivide::Init(const TopoDS_Wire& W,
104 const Handle(Geom_Surface)& S)
106 // if (ShapeUpgrade::Debug()) std::cout <<"ShapeUpgrade_WireDivide::Init with Wire, Surface "<<std::endl;
108 BRepLib_MakeFace mkf(S, Precision::Confusion());
110 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
113 //=======================================================================
116 //=======================================================================
118 void ShapeUpgrade_WireDivide::Load(const TopoDS_Wire& W)
123 //=======================================================================
126 //=======================================================================
128 void ShapeUpgrade_WireDivide::Load(const TopoDS_Edge& E)
130 BRepLib_MakeWire MakeWire (E);
131 if (MakeWire.IsDone())
132 Load (MakeWire.Wire());
135 //=======================================================================
138 //=======================================================================
140 void ShapeUpgrade_WireDivide::SetFace(const TopoDS_Face& F)
145 //=======================================================================
146 //function : SetSurface
148 //=======================================================================
150 void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S)
152 BRepLib_MakeFace mkf(S, Precision::Confusion());
156 //=======================================================================
157 //function : SetSurface
159 //=======================================================================
161 void ShapeUpgrade_WireDivide::SetSurface(const Handle(Geom_Surface)& S,
162 const TopLoc_Location& L)
165 B.MakeFace(myFace,S,L,Precision::Confusion());
168 //=======================================================================
171 //=======================================================================
173 static void CorrectSplitValues(const Handle(TColStd_HSequenceOfReal) orig3d,
174 const Handle(TColStd_HSequenceOfReal) orig2d,
175 Handle(TColStd_HSequenceOfReal) new2d,
176 Handle(TColStd_HSequenceOfReal) new3d)
178 Standard_Real preci = Precision::PConfusion();
179 Standard_Integer len3d = orig3d->Length();
180 Standard_Integer len2d = orig2d->Length();
181 TColStd_Array1OfBoolean fixNew2d (1, len3d);
182 fixNew2d.Init (Standard_False);
183 TColStd_Array1OfBoolean fixNew3d (1, len2d);
184 fixNew3d.Init (Standard_False);
185 Standard_Real Last3d = orig3d->Value(len3d);
186 Standard_Real Last2d = orig2d->Value(len2d);
188 Standard_Integer i;// svv #1
189 for( i = 1; i <= len3d ; i++) {
190 Standard_Real par = new2d->Value(i);
191 Standard_Integer index = 0;
192 for(Standard_Integer j = 1; j <= len2d && !index; j++)
193 if(Abs(par-orig2d->Value(j)) < preci)
195 if(index&&!fixNew3d(index)) {
196 Standard_Real newPar = orig2d->Value(index);
197 new2d->SetValue(i,newPar);
198 fixNew2d(i) = Standard_True;
199 Standard_Real newPar3d = orig3d->Value(i);
200 new3d->SetValue(index,newPar3d);
201 fixNew3d(index) = Standard_True;
205 for(i = 1; i <= len2d ; i++) {
206 Standard_Real par = new3d->Value(i);
207 Standard_Integer index = 0;
208 for(Standard_Integer j = 1; j <= len3d && !index; j++)
209 if(Abs(par-orig3d->Value(j)) < preci)
211 if(index&&!fixNew2d(index)) {
212 Standard_Real newPar = orig3d->Value(index);
213 new3d->SetValue(i,newPar);
214 fixNew3d(i) = Standard_True;
215 Standard_Real newPar2d = orig2d->Value(i);
216 new2d->SetValue(index,newPar2d);
217 fixNew2d(index) = Standard_True;
221 Standard_Real dpreci = 2* preci;
222 for(i = 1; i < len3d; i++) {
223 Standard_Real dist = new2d->Value(i+1) - new2d->Value(i);
227 Standard_Real tmp = new2d->Value(i+1);
228 new2d->SetValue(i+1,new2d->Value(i)+dpreci);
229 new2d->SetValue(i,tmp);
230 fixNew2d(i) = Standard_True;
231 fixNew2d(i+1) = Standard_False;
234 new2d->SetValue(i+1,new2d->Value(i)+dpreci);
237 if(new2d->Value(len3d) > Last3d) {
238 Standard_Integer ind; // svv #1
239 for( ind = len3d; ind > 1 && !fixNew2d(ind); ind--);
240 Standard_Real lastFix = new2d->Value(ind);
241 for(i = len3d; i >= ind; i--) {
242 new2d->SetValue(i,lastFix);
247 for(i = 1; i < len2d; i++) {
248 Standard_Real dist = new3d->Value(i+1) - new3d->Value(i);
252 Standard_Real tmp = new3d->Value(i+1);
253 new3d->SetValue(i+1,new3d->Value(i)+dpreci);
254 new3d->SetValue(i,tmp);
255 fixNew3d(i) = Standard_True;
256 fixNew3d(i+1) = Standard_False;
259 new3d->SetValue(i+1,new3d->Value(i)+dpreci);
262 if(new3d->Value(len2d) > Last2d) {
263 Standard_Integer ind; // svv #1
264 for(ind = len2d; ind > 1 && !fixNew3d(ind); ind--);
265 Standard_Real lastFix = new3d->Value(ind);
266 for(i = len2d; i >= ind; i--) {
267 new3d->SetValue(i,lastFix);
273 void ShapeUpgrade_WireDivide::Perform ()
276 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
278 // if (ShapeUpgrade::Debug()) std::cout << "ShapeUpgrade_WireDivide::Perform" << std::endl;
281 ShapeAnalysis_Edge sae;
284 B.MakeWire (newWire);
286 Handle(Geom_Surface) Surf;
288 Surf = BRep_Tool::Surface(myFace, Loc);
290 Standard_Boolean isSplit3d = Standard_True;
292 case 0: if(!myFace.IsNull()) isSplit3d = Standard_False; break;
293 case 1: if(myFace.IsNull()) isSplit3d = Standard_False; break;
296 myEdgeDivide->SetFace(myFace);
298 myEdgeDivide->SetSplitCurve3dTool(GetSplitCurve3dTool());
299 myEdgeDivide->SetSplitCurve2dTool(GetSplitCurve2dTool());
300 for (TopoDS_Iterator ItW (myWire,Standard_False); ItW.More(); ItW.Next()) {
302 TopoDS_Shape sh = Context()->Apply(ItW.Value(),TopAbs_SHAPE);
303 for(TopExp_Explorer exp(sh,TopAbs_EDGE); exp.More(); exp.Next()) {
304 TopoDS_Edge E = TopoDS::Edge(exp.Current());
305 // if (ShapeUpgrade::Debug()) std::cout << ".. Edge " << (void*) &(*E.TShape()) << std::endl;
307 // skip degenerated edges (and also INTERNAL/EXTERNAL, to avoid failures)
308 if ( E.Orientation() == TopAbs_INTERNAL || E.Orientation() == TopAbs_EXTERNAL ) {
309 B.Add ( newWire, E );
313 if(!myEdgeDivide->Compute(E)) {
314 B.Add ( newWire, E );
317 // first iteration: getting split knots
318 // on 3D curve: preliminary
320 Handle(ShapeAnalysis_TransferParameters) theTransferParamTool = GetTransferParamTool();
321 theTransferParamTool->SetMaxTolerance(MaxTolerance());
322 theTransferParamTool->Init(E,myFace);
323 Standard_Boolean wasSR = theTransferParamTool->IsSameRange();
325 // on pcurve(s): all knots
326 // assume that if seam-edge, its pcurve1 and pcurve2 has the same split knots !!!
327 Handle(TColStd_HSequenceOfReal) theKnots3d = myEdgeDivide->Knots3d();
328 Handle(TColStd_HSequenceOfReal) theKnots2d = myEdgeDivide->Knots2d();
330 // second iteration: transfer parameters and build segments
331 Handle(TColStd_HSequenceOfReal) SplitValues2d;
332 Handle(TColStd_HSequenceOfReal) SplitValues3d;
333 if(myEdgeDivide->HasCurve2d() && myEdgeDivide->HasCurve3d() ) {
334 SplitValues2d = theTransferParamTool->Perform(theKnots3d,Standard_True);
335 SplitValues3d = theTransferParamTool->Perform(theKnots2d,Standard_False);
336 CorrectSplitValues(theKnots3d,theKnots2d,SplitValues2d,SplitValues3d);
338 Handle(ShapeUpgrade_SplitCurve3d) theSplit3dTool = myEdgeDivide->GetSplitCurve3dTool();
339 Handle(ShapeUpgrade_SplitCurve2d) theSplit2dTool = myEdgeDivide->GetSplitCurve2dTool();
341 if ( myEdgeDivide->HasCurve2d() ) {
342 if(! theKnots3d.IsNull() ) {
343 SplitValues2d->Remove(1);
344 SplitValues2d->Remove(SplitValues2d->Length());
345 theSplit2dTool->SetSplitValues (SplitValues2d);
347 theSplit2dTool->Build(Standard_True);
349 if ( myEdgeDivide->HasCurve3d() ) {
350 if( ! theKnots2d.IsNull() ) {
351 SplitValues3d->Remove(1);
352 SplitValues3d->Remove(SplitValues3d->Length());
353 theSplit3dTool->SetSplitValues (SplitValues3d);
355 theSplit3dTool->Build (Standard_True);
357 // get 2d and 3d split values which should be the same
358 if ( myEdgeDivide->HasCurve2d() ) theKnots2d = theSplit2dTool->SplitValues();
359 if ( myEdgeDivide->HasCurve3d() ) theKnots3d = theSplit3dTool->SplitValues();
361 Standard_Boolean isSeam = Standard_False;
362 if (! myFace.IsNull() )
363 isSeam = BRep_Tool::IsClosed ( E, myFace );
364 Handle(TColGeom2d_HArray1OfCurve) theSegments2d;
365 if(myEdgeDivide->HasCurve2d())
366 theSegments2d = theSplit2dTool->GetCurves();
367 Handle(TColGeom2d_HArray1OfCurve) theSegments2dR;
369 Handle(Geom2d_Curve) c2;
370 Standard_Real f2, l2;
372 TopoDS_Shape tmpE = E.Reversed();
373 TopoDS_Edge erev = TopoDS::Edge (tmpE );
374 if ( sae.PCurve ( erev, myFace, c2, f2, l2, Standard_False) ) {
375 theSplit2dTool->Init (c2, f2, l2);
376 if(!theKnots2d.IsNull())
377 theSplit2dTool->SetSplitValues (theKnots2d);
378 theSplit2dTool->Perform (Standard_True);
379 Handle(TColStd_HSequenceOfReal) revKnots2d = theSplit2dTool->SplitValues();
380 if(revKnots2d->Length()!=theKnots2d->Length()) {
381 isSeam = Standard_False;
383 std::cout << "Error: ShapeUpgrade_WireDivide: seam has different splitting values on pcurvesd" << std::endl;
387 theSegments2dR = theSplit2dTool->GetCurves();
389 else isSeam = Standard_False;
393 TopoDS_Vertex V1o = TopExp::FirstVertex (E, Standard_False);
394 TopoDS_Vertex V2o = TopExp::LastVertex (E, Standard_False);
395 Standard_Boolean isForward = ( E.Orientation() == TopAbs_FORWARD );
396 Standard_Real TolEdge = BRep_Tool::Tolerance (E);
397 Standard_Boolean isDeg = BRep_Tool::Degenerated ( E );
399 // Copy vertices to protect original shape against SameParamseter
401 TopoDS_Shape emptyCopiedV1 = V1o.EmptyCopied();
402 TopoDS_Vertex V1 = TopoDS::Vertex ( emptyCopiedV1 );
403 Context()->Replace ( V1o, V1 );
405 if ( V1o.IsSame ( V2o ) ) {
407 TopoDS_Shape tmpV = V1.Oriented(V2o.Orientation() );
408 V2 = TopoDS::Vertex ( tmpV );
412 TopoDS_Shape emptyCopied = V2o.EmptyCopied();
413 V2 = TopoDS::Vertex ( emptyCopied );
414 Context()->Replace ( V2o, V2 );
417 //collect NM vertices
419 Standard_Real af = 0.,al = 0.;
420 Handle(Geom_Curve) c3d;
421 Adaptor3d_CurveOnSurface AdCS;
422 if(myEdgeDivide->HasCurve3d())
423 sae.Curve3d(E,c3d,af,al,Standard_False);
424 else if(myEdgeDivide->HasCurve2d() && !Surf.IsNull()) {
425 Handle(Geom2d_Curve) c2d;
426 sae.PCurve ( E, myFace, c2d, af, al, Standard_False);
427 Handle(Adaptor3d_HSurface) AdS = new GeomAdaptor_HSurface(Surf);
428 Handle(Adaptor2d_HCurve2d) AC2d = new Geom2dAdaptor_HCurve(c2d,af,al);
432 TopTools_SequenceOfShape aSeqNMVertices;
433 TColStd_SequenceOfReal aSeqParNM;
434 TopoDS_Iterator aItv(E,Standard_False);
435 ShapeAnalysis_Curve sac;
436 for ( ; aItv.More() ; aItv.Next()) {
437 if(aItv.Value().Orientation() == TopAbs_INTERNAL ||
438 aItv.Value().Orientation() == TopAbs_EXTERNAL) {
439 TopoDS_Vertex aVold = TopoDS::Vertex(aItv.Value());
440 aSeqNMVertices.Append(aVold);
441 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aVold));
445 sac.Project(c3d,aP,Precision(),pproj,ppar,af,al,Standard_False);
447 sac.Project(AdCS,aP,Precision(),pproj,ppar);
448 aSeqParNM.Append(ppar);
452 // creating new edge(s)
453 Handle(TColGeom_HArray1OfCurve) theSegments3d;
454 if(myEdgeDivide->HasCurve3d()) theSegments3d = theSplit3dTool->GetCurves();
456 Standard_Integer nbc = 0;
457 if (!theSegments3d.IsNull()) {
458 nbc = theSegments3d->Length();
459 if ( !theSegments2d.IsNull() ) {
460 Standard_Integer nbc2d = theSegments2d->Length();
463 std::cout<<"Error: Number of intervals are not equal for 2d 3d. Ignored."<<std::endl;
465 nbc = Min( nbc,nbc2d);
470 if(!theSegments2d.IsNull())// if theSegments have different length ???
471 nbc = theSegments2d->Length();
473 if ( nbc <= 1 && ! theSplit3dTool->Status ( ShapeExtend_DONE ) &&
474 ! theSplit2dTool->Status ( ShapeExtend_DONE ) ) {
475 B.Add ( newWire, E );
479 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
482 B.MakeWire (resWire);
483 // TopoDS_Vertex firstVertex, lastVertex;
484 Standard_Integer numE =0;
485 gp_Pnt pntV1 = BRep_Tool::Pnt(V1);
486 //gp_Pnt pntV2 = BRep_Tool::Pnt(V2); // pntV2 not used - see below (skl)
487 //Standard_Real V2Tol = LimitTolerance( BRep_Tool::Tolerance(V2) ); // V2Tol not used - see below (skl)
489 Handle(ShapeUpgrade_FixSmallCurves) FixSmallCurveTool = GetFixSmallCurveTool(); //gka Precision
490 FixSmallCurveTool->SetMinTolerance(MinTolerance());
491 FixSmallCurveTool->Init(E, myFace);
492 FixSmallCurveTool->SetSplitCurve3dTool(theSplit3dTool);
493 FixSmallCurveTool->SetSplitCurve2dTool(theSplit2dTool);
494 FixSmallCurveTool->SetPrecision(MinTolerance());
495 Standard_Integer Savnum =0;
496 Standard_Real SavParf;
497 Standard_Integer Small = 0;
498 for ( Standard_Integer icurv = 1; icurv <= nbc; icurv++ ) {
500 Handle(Geom_Curve) theNewCurve3d;
501 if(!theSegments3d.IsNull()) theNewCurve3d = theSegments3d->Value(icurv);
503 Handle(Geom2d_Curve) theNewPCurve1;
504 if(!theSegments2d.IsNull()) theNewPCurve1 = theSegments2d->Value(icurv);
505 Handle(Geom2d_Curve) revPCurve;
507 revPCurve = theSegments2dR->Value(icurv);
508 // construction of the intermediate Vertex
510 if ( icurv <= nbc && nbc != 1 && ! isDeg ) {
511 Standard_Real par,parf /*,SavParl*/;
512 //Standard_Real SaveParf; // SaveParf not used - see below (skl)
514 // if edge has 3d curve, take point from it
515 if ( ! theNewCurve3d.IsNull() ) {
516 if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
517 par = theNewCurve3d->LastParameter();
518 parf = theNewCurve3d->FirstParameter();
521 par = theKnots3d->Value (icurv + 1);
522 parf = theKnots3d->Value (icurv);
524 P = theNewCurve3d->Value (par);
525 P1 = theNewCurve3d->Value (parf);
526 PM = theNewCurve3d->Value ((parf+par)/2);
528 // else use pcurve and surface (suppose that both exist)
530 if ( Surf.IsNull() ) Surf = BRep_Tool::Surface ( myFace, Loc );
531 if ( theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) ) {
532 par = theNewPCurve1->LastParameter();
533 parf = theNewPCurve1->FirstParameter();
536 par = theKnots2d->Value (icurv + 1);
537 parf = theKnots2d->Value (icurv);
539 gp_Pnt2d p2d = theNewPCurve1->Value (par);
540 gp_Pnt2d p2df = theNewPCurve1->Value (parf);
541 gp_Pnt2d p2dM = theNewPCurve1->Value ((parf+par)/2);
542 P = Surf->Value ( p2d.X(), p2d.Y() );
543 P1 = Surf->Value ( p2df.X(), p2df.Y() );
544 PM = Surf->Value ( p2dM.X(), p2dM.Y() );
545 P.Transform ( Loc.Transformation() );
546 P1.Transform ( Loc.Transformation() );
547 PM.Transform ( Loc.Transformation() );
549 if(P.Distance(pntV1) < MinTolerance() && P.Distance(PM) < MinTolerance() && !myFace.IsNull()) {
557 TopoDS_Vertex VVV = V1;
558 VVV.Orientation ( V2.Orientation() );
559 Context()->Replace(V2,VVV);
564 if(P.Distance(P1) > MinTolerance() || P.Distance(PM) > MinTolerance()) {
565 //FixSmallCurveTool->Perform(prevEdge,theNewCurve3d,theNewPCurve1,revPCurve,SavParf,SavParl);
566 gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() );
567 B.UpdateVertex(V1,pmid,0);
570 Handle(Geom_Curve) atmpCurve;
571 Handle(Geom2d_Curve) atmpCurve2d1,atmprepcurve;
572 if(FixSmallCurveTool->Approx( atmpCurve,atmpCurve2d1,atmprepcurve,SavParf,par)) { //BRepTools
573 theNewCurve3d = atmpCurve;
574 theNewPCurve1 = atmpCurve2d1;
575 revPCurve = atmprepcurve;
578 gp_Pnt pmid = 0.5 * ( pntV1.XYZ() + P1.XYZ() );
579 B.UpdateVertex(V1,pmid,0);
585 /* if(P.Distance (pntV1) < V1Tol)
587 else if (P.Distance (pntV2) < V2Tol) {
594 B.MakeVertex (V, P, TolEdge); //tolerance of the edge
600 // if (ShapeUpgrade::Debug()) std::cout <<"... New intermediate Vertex ("
601 // <<P.X()<<","<<P.Y()<<","<<P.Z()<<") :"<<(void*) &(*V.TShape())
602 // <<" with Tolerance "<<TolEdge <<std::endl;
609 V1.Orientation ( TopAbs_FORWARD );
610 V.Orientation ( TopAbs_REVERSED );
611 newEdge = sbe.CopyReplaceVertices ( E, V1, V );
614 V1.Orientation ( TopAbs_REVERSED );
615 V.Orientation ( TopAbs_FORWARD );
616 newEdge = sbe.CopyReplaceVertices ( E, V, V1 );
618 sbe.CopyPCurves ( newEdge, E );
619 if(!theNewCurve3d.IsNull())
620 B.UpdateEdge ( newEdge, theNewCurve3d, 0. );
622 B.Degenerated( newEdge, Standard_True);
624 // Handle(Geom2d_Curve) revPCurve = theSegments2dR->Value(icurv);
625 //if(newEdge.Orientation()==TopAbs_FORWARD)
626 //B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. );
628 //B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. );
630 //else if ( ! myFace.IsNull() )
631 //B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. );
633 Standard_Real f3d = 0., l3d =0.;
634 if(!Savnum) Savnum = icurv;
635 Standard_Boolean srNew;
636 if(!theNewCurve3d.IsNull()) {
637 if(theNewCurve3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
638 f3d = theNewCurve3d->FirstParameter();
639 l3d = theNewCurve3d->LastParameter();
640 srNew = ((f3d == theKnots3d->Value (Savnum)) && (l3d == theKnots3d->Value (icurv + 1)));
643 f3d = theKnots3d->Value (Savnum);
644 l3d = theKnots3d->Value (icurv + 1);
645 srNew = Standard_True;
649 srNew = Standard_True;
651 Standard_Real f2d=0, l2d=0;
652 if(!theNewPCurve1.IsNull()){
653 if(theNewPCurve1->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) {
654 f2d = theNewPCurve1->FirstParameter();
655 l2d = theNewPCurve1->LastParameter();
656 srNew &= ((f2d == theKnots2d->Value (Savnum)) && (l2d == theKnots2d->Value (icurv + 1)));
659 f2d = theKnots2d->Value (Savnum);
660 l2d = theKnots2d->Value (icurv + 1);
663 //if(!Savnum) Savnum = icurv;
664 if(!theNewCurve3d.IsNull())
665 theTransferParamTool->TransferRange(newEdge,theKnots3d->Value (Savnum),theKnots3d->Value (icurv + 1),Standard_False);
667 theTransferParamTool->TransferRange(newEdge,theKnots2d->Value (Savnum),theKnots2d->Value (icurv + 1),Standard_True);
669 Standard_Real alpha = (theKnots3d->Value (icurv) - f)/(l - f);
670 Standard_Real beta = (theKnots3d->Value (icurv + 1) - f)/(l - f);
671 sbe.CopyRanges(newEdge,E, alpha, beta);*/
673 Handle(Geom2d_Curve) c2dTmp;
674 Standard_Real setF, setL;
675 if( ! myFace.IsNull() && sae.PCurve (newEdge, myFace, c2dTmp, setF, setL, Standard_False))
676 srNew &= ( (setF==f2d) && (setL==l2d) );
679 // Handle(Geom2d_Curve revPCurve = theSegments2dR->Value(icurv);
680 if(newEdge.Orientation()==TopAbs_FORWARD)
681 B.UpdateEdge ( newEdge, theNewPCurve1, revPCurve, myFace, 0. );
683 B.UpdateEdge ( newEdge, revPCurve, theNewPCurve1, myFace, 0. );
685 else if ( ! myFace.IsNull() ) {
686 B.UpdateEdge ( newEdge, theNewPCurve1, myFace, 0. );
689 if(!theNewCurve3d.IsNull())
690 sbe.SetRange3d(newEdge,f3d,l3d);
691 if(!theNewPCurve1.IsNull())
693 B.Range ( newEdge, myFace, f2d, l2d);
695 if((!wasSR || !srNew)&&!BRep_Tool::Degenerated(newEdge) )
697 B.SameRange(newEdge, Standard_False);
700 //addition NM vertices to new edges
701 Standard_Real afpar = (myEdgeDivide->HasCurve3d () ? f3d : f2d);
702 Standard_Real alpar = (myEdgeDivide->HasCurve3d () ? l3d : l2d);
703 for (Standard_Integer n = 1; n <= aSeqParNM.Length (); ++n)
705 Standard_Real apar = aSeqParNM.Value (n);
706 TopoDS_Vertex aVold = TopoDS::Vertex (aSeqNMVertices.Value (n));
707 TopoDS_Vertex aNMVer = ShapeAnalysis_TransferParametersProj::CopyNMVertex (aVold, newEdge, E);
708 Context ()->Replace (aVold, aNMVer);
709 if (fabs (apar - afpar) <= Precision::PConfusion ())
711 Context ()->Replace (aNMVer, V1);
713 else if (fabs (apar - alpar) <= Precision::PConfusion ())
715 Context ()->Replace (aNMVer, V);
717 else if (apar > afpar && apar < alpar)
719 B.Add (newEdge, aNMVer);
726 aSeqNMVertices.Remove (n);
727 aSeqParNM.Remove (n);
731 // if (ShapeUpgrade::Debug()) std::cout <<"... New Edge "
732 // <<(void*) &(*newEdge.TShape())<<" on vertices "
733 // <<(void*) &(*V1.TShape())<<", " <<(void*) &(*V.TShape())
734 // <<" with Tolerance "<<TolEdge <<std::endl;
735 B.Add ( resWire, newEdge );
736 B.Add ( newWire, newEdge );
742 resWire.Closed (BRep_Tool::IsClosed (resWire));
743 Context()->Replace(E,resWire);
746 Context()->Remove(E);
749 if ( Status ( ShapeExtend_DONE ) ) {
751 newWire.Closed (BRep_Tool::IsClosed (newWire));
752 TopoDS_Shape tmpW = Context()->Apply ( newWire ).Oriented(myWire.Orientation());
753 myWire = TopoDS::Wire (tmpW );
757 //=======================================================================
760 //=======================================================================
762 const TopoDS_Wire& ShapeUpgrade_WireDivide::Wire() const
767 //=======================================================================
770 //=======================================================================
772 Standard_Boolean ShapeUpgrade_WireDivide::Status (const ShapeExtend_Status status) const
774 return ShapeExtend::DecodeStatus ( myStatus, status );
777 //=======================================================================
778 //function : SetSplitCurve3dTool
780 //=======================================================================
782 void ShapeUpgrade_WireDivide::SetSplitCurve3dTool(const Handle(ShapeUpgrade_SplitCurve3d)& splitCurve3dTool)
784 mySplitCurve3dTool = splitCurve3dTool;
787 //=======================================================================
788 //function : SetSplitCurve2dTool
790 //=======================================================================
792 void ShapeUpgrade_WireDivide::SetSplitCurve2dTool(const Handle(ShapeUpgrade_SplitCurve2d)& splitCurve2dTool)
794 mySplitCurve2dTool = splitCurve2dTool;
797 //=======================================================================
798 //function : GetSplitCurve3dTool
800 //=======================================================================
802 Handle(ShapeUpgrade_SplitCurve3d) ShapeUpgrade_WireDivide::GetSplitCurve3dTool() const
804 return mySplitCurve3dTool;
807 //=======================================================================
808 //function : GetSplitCurve2dTool
810 //=======================================================================
812 Handle(ShapeUpgrade_SplitCurve2d) ShapeUpgrade_WireDivide::GetSplitCurve2dTool() const
814 return mySplitCurve2dTool;
817 //=======================================================================
818 //function : SetEdgeDivideTool
820 //=======================================================================
822 void ShapeUpgrade_WireDivide::SetEdgeDivideTool(const Handle (ShapeUpgrade_EdgeDivide)& edgeDivideTool)
824 myEdgeDivide = edgeDivideTool;
827 //=======================================================================
828 //function : GetEdgeDivideTool
830 //=======================================================================
832 Handle (ShapeUpgrade_EdgeDivide) ShapeUpgrade_WireDivide::GetEdgeDivideTool() const
837 //=======================================================================
838 //function : SetTransferParamTool
840 //=======================================================================
842 void ShapeUpgrade_WireDivide::SetTransferParamTool(const Handle(ShapeAnalysis_TransferParameters)& TransferParam)
844 myTransferParamTool = TransferParam;
847 //=======================================================================
848 //function : GetTransferParamTool
850 //=======================================================================
852 Handle(ShapeAnalysis_TransferParameters) ShapeUpgrade_WireDivide::GetTransferParamTool()
854 return myTransferParamTool;
857 //=======================================================================
858 //function : SetEdgeMode
860 //=======================================================================
862 void ShapeUpgrade_WireDivide::SetEdgeMode(const Standard_Integer EdgeMode)
864 myEdgeMode = EdgeMode;
867 //=======================================================================
868 //function : SetFixSmallCurveTool
870 //=======================================================================
872 void ShapeUpgrade_WireDivide::SetFixSmallCurveTool(const Handle(ShapeUpgrade_FixSmallCurves)& FixSmallCurvesTool)
874 myFixSmallCurveTool = FixSmallCurvesTool;
877 //=======================================================================
878 //function : GetFixSmallCurveTool
880 //=======================================================================
882 Handle(ShapeUpgrade_FixSmallCurves) ShapeUpgrade_WireDivide::GetFixSmallCurveTool() const
884 return myFixSmallCurveTool;