0025748: Parallel version of progress indicator
[occt.git] / src / ShapeProcess / ShapeProcess_OperLibrary.cxx
1 // Created on: 2000-08-31
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BRep_Builder.hxx>
18 #include <BRepLib.hxx>
19 #include <BRepTools_Modification.hxx>
20 #include <BRepTools_Modifier.hxx>
21 #include <Message_MsgFile.hxx>
22 #include <Message_ProgressScope.hxx>
23 #include <Precision.hxx>
24 #include <ShapeBuild_ReShape.hxx>
25 #include <ShapeCustom_BSplineRestriction.hxx>
26 #include <ShapeCustom_ConvertToBSpline.hxx>
27 #include <ShapeCustom_ConvertToRevolution.hxx>
28 #include <ShapeCustom_DirectModification.hxx>
29 #include <ShapeCustom_RestrictionParameters.hxx>
30 #include <ShapeCustom_SweptToElementary.hxx>
31 #include <ShapeExtend.hxx>
32 #include <ShapeExtend_MsgRegistrator.hxx>
33 #include <ShapeFix.hxx>
34 #include <ShapeFix_Face.hxx>
35 #include <ShapeFix_FixSmallFace.hxx>
36 #include <ShapeFix_FixSmallSolid.hxx>
37 #include <ShapeFix_Shape.hxx>
38 #include <ShapeFix_ShapeTolerance.hxx>
39 #include <ShapeFix_SplitCommonVertex.hxx>
40 #include <ShapeFix_Wire.hxx>
41 #include <ShapeFix_Wireframe.hxx>
42 #include <ShapeProcess.hxx>
43 #include <ShapeProcess_OperLibrary.hxx>
44 #include <ShapeProcess_ShapeContext.hxx>
45 #include <ShapeProcess_UOperator.hxx>
46 #include <ShapeUpgrade_ShapeConvertToBezier.hxx>
47 #include <ShapeUpgrade_ShapeDivideAngle.hxx>
48 #include <ShapeUpgrade_ShapeDivideClosed.hxx>
49 #include <ShapeUpgrade_ShapeDivideClosedEdges.hxx>
50 #include <ShapeUpgrade_ShapeDivideContinuity.hxx>
51 #include <TopoDS_Compound.hxx>
52 #include <TopoDS_Iterator.hxx>
53 #include <TopoDS_Shape.hxx>
54
55 //=======================================================================
56 //function : ApplyModifier
57 //purpose  : Applies BRepTools_Modification to a shape,
58 //           taking into account sharing of components of compounds
59 //=======================================================================
60 TopoDS_Shape ShapeProcess_OperLibrary::ApplyModifier (const TopoDS_Shape &S, 
61                                                       const Handle(ShapeProcess_ShapeContext)& context,
62                                                       const Handle(BRepTools_Modification) &M,
63                                                       TopTools_DataMapOfShapeShape &map,
64                                                       const Handle(ShapeExtend_MsgRegistrator) &msg,
65                                                       Standard_Boolean theMutableInput)
66 {
67   // protect against INTERNAL/EXTERNAL shapes
68   TopoDS_Shape SF = S.Oriented(TopAbs_FORWARD);
69
70   // Process COMPOUNDs separately in order to handle sharing in assemblies
71   if ( SF.ShapeType() == TopAbs_COMPOUND ) {
72     Standard_Boolean locModified = Standard_False;
73     TopoDS_Compound C;
74     BRep_Builder B;
75     B.MakeCompound ( C );
76     for ( TopoDS_Iterator it(SF); it.More(); it.Next() ) {
77       TopoDS_Shape shape = it.Value();
78       TopLoc_Location L = shape.Location(), nullLoc;
79       shape.Location ( nullLoc );
80       TopoDS_Shape res;
81       if(map.IsBound ( shape ))
82         res = map.Find ( shape ).Oriented ( shape.Orientation() );
83
84       else {
85         res = ApplyModifier (shape, context, M, map, 0, theMutableInput );
86         map.Bind ( shape, res );
87       }
88       if ( ! res.IsSame ( shape ) ) locModified = Standard_True;
89       res.Location ( L );
90       B.Add ( C, res );
91     }
92     if ( ! locModified ) return S;
93     
94     map.Bind ( SF, C );
95     return C.Oriented ( S.Orientation() );
96   }
97
98   // Modify the shape
99   BRepTools_Modifier MD(SF);
100   MD.SetMutableInput(theMutableInput);
101   MD.Perform(M);
102   context->RecordModification ( SF, MD, msg );
103   return MD.ModifiedShape(SF).Oriented(S.Orientation());
104 }
105
106
107 //=======================================================================
108 //function : directfaces
109 //purpose  : 
110 //=======================================================================
111
112 static Standard_Boolean directfaces (const Handle(ShapeProcess_Context)& context,
113                                      const Message_ProgressRange&)
114 {
115   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
116   if ( ctx.IsNull() ) return Standard_False;
117
118   // activate message mechanism if it is supported by context
119   Handle(ShapeExtend_MsgRegistrator) msg;
120   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
121
122   Handle(ShapeCustom_DirectModification) DM = new ShapeCustom_DirectModification;
123   DM->SetMsgRegistrator( msg );
124   TopTools_DataMapOfShapeShape map;
125   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, DM, map,  msg, Standard_True );
126   ctx->RecordModification ( map, msg );
127   ctx->SetResult ( res );
128   return Standard_True;
129 }
130
131
132 //=======================================================================
133 //function : sameparam
134 //purpose  :
135 //=======================================================================
136
137 static Standard_Boolean sameparam (const Handle(ShapeProcess_Context)& context,
138                                    const Message_ProgressRange&)
139 {
140   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
141   if ( ctx.IsNull() ) return Standard_False;
142
143   // activate message mechanism if it is supported by context
144   Handle(ShapeExtend_MsgRegistrator) msg;
145   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
146
147   ShapeFix::SameParameter ( ctx->Result(),
148                             ctx->BooleanVal ( "Force", Standard_False ),
149                             ctx->RealVal ( "Tolerance3d", Precision::Confusion() /* -1 */),
150                             Message_ProgressRange(), msg );
151
152   if ( !msg.IsNull() )
153   {
154     // WARNING: not FULL update of context yet!
155     Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
156     ctx->RecordModification( reshape, msg );
157   }
158   return Standard_True;
159 }
160
161
162 //=======================================================================
163 //function : settol
164 //purpose  : 
165 //=======================================================================
166
167 static Standard_Boolean settol (const Handle(ShapeProcess_Context)& context,
168                                 const Message_ProgressRange&)
169 {
170   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
171   if ( ctx.IsNull() ) return Standard_False;
172
173   Standard_Real val;
174   if ( ctx->IntegerVal ( "Mode", 0 ) >0 && ctx->GetReal ( "Value", val ) ) {
175     Standard_Real rat = ctx->RealVal ( "Ratio", 1. );
176     if ( rat >= 1 ) {
177       ShapeFix_ShapeTolerance SFST;
178       SFST.LimitTolerance (ctx->Result(), val/rat, val*rat);
179     }
180   }
181
182   BRepLib::UpdateTolerances (ctx->Result(),Standard_True);
183
184   Standard_Real reg;
185   if ( ctx->GetReal ("Regularity", reg) )  
186     BRepLib::EncodeRegularity (ctx->Result(), reg);
187
188   // WARNING: no update of context yet!
189   return Standard_True;
190 }
191
192
193 //=======================================================================
194 //function : splitangle
195 //purpose  :
196 //=======================================================================
197
198 static Standard_Boolean splitangle (const Handle(ShapeProcess_Context)& context,
199                                     const Message_ProgressRange&)
200 {
201   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
202   if ( ctx.IsNull() ) return Standard_False;
203
204   // activate message mechanism if it is supported by context
205   Handle(ShapeExtend_MsgRegistrator) msg;
206   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
207
208   ShapeUpgrade_ShapeDivideAngle SDA ( ctx->RealVal ( "Angle", 2*M_PI ), ctx->Result() );
209   SDA.SetMaxTolerance ( ctx->RealVal ( "MaxTolerance", 1. ) );
210   SDA.SetMsgRegistrator ( msg );
211
212   if ( ! SDA.Perform() && SDA.Status (ShapeExtend_FAIL) ) {
213 #ifdef OCCT_DEBUG
214     std::cout<<"ShapeDivideAngle failed"<<std::endl;
215 #endif
216     return Standard_False;
217   }
218
219   ctx->RecordModification ( SDA.GetContext(), msg );
220   ctx->SetResult ( SDA.Result() );
221   return Standard_True;
222 }
223
224
225 //=======================================================================
226 //function : bsplinerestriction
227 //purpose  : 
228 //=======================================================================
229
230 static Standard_Boolean bsplinerestriction (const Handle(ShapeProcess_Context)& context,
231                                             const Message_ProgressRange&)
232 {
233   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
234   if ( ctx.IsNull() ) return Standard_False;
235
236   // activate message mechanism if it is supported by context
237   Handle(ShapeExtend_MsgRegistrator) msg;
238   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
239
240   Standard_Boolean ModeSurf  = ctx->BooleanVal ( "SurfaceMode", Standard_True );
241   Standard_Boolean ModeC3d   = ctx->BooleanVal ( "Curve3dMode", Standard_True );
242   Standard_Boolean ModeC2d   = ctx->BooleanVal ( "Curve2dMode", Standard_True );
243
244   Standard_Real aTol3d = ctx->RealVal ( "Tolerance3d", 0.01 );
245   Standard_Real aTol2d = ctx->RealVal ( "Tolerance2d", 1e-06 );
246   
247   GeomAbs_Shape aCont3d = ctx->ContinuityVal ( "Continuity3d", GeomAbs_C1 );
248   GeomAbs_Shape aCont2d = ctx->ContinuityVal ( "Continuity2d", GeomAbs_C2 );
249
250   Standard_Integer aMaxDeg = ctx->IntegerVal ( "RequiredDegree", 9 );
251   Standard_Integer aMaxSeg = ctx->IntegerVal ( "RequiredNbSegments", 10000 );
252   
253   Standard_Boolean ModeDeg  = ctx->BooleanVal ( "PreferDegree", Standard_True );
254   Standard_Boolean Rational = ctx->BooleanVal ( "RationalToPolynomial", Standard_False );
255   
256   Handle(ShapeCustom_RestrictionParameters)   aParameters = new ShapeCustom_RestrictionParameters;
257   ctx->GetInteger ( "MaxDegree",          aParameters->GMaxDegree() );
258   ctx->GetInteger ( "MaxNbSegments",      aParameters->GMaxSeg() );
259   ctx->GetBoolean ( "OffsetSurfaceMode",  aParameters->ConvertOffsetSurf() );
260   ctx->GetBoolean ( "OffsetCurve3dMode",  aParameters->ConvertOffsetCurv3d() );
261   ctx->GetBoolean ( "OffsetCurve2dMode",  aParameters->ConvertOffsetCurv2d() );
262   ctx->GetBoolean ( "LinearExtrusionMode",aParameters->ConvertExtrusionSurf() );
263   ctx->GetBoolean ( "RevolutionMode",     aParameters->ConvertRevolutionSurf() );
264   ctx->GetBoolean ( "SegmentSurfaceMode", aParameters->SegmentSurfaceMode() );
265   ctx->GetBoolean ( "ConvCurve3dMode",    aParameters->ConvertCurve3d() );
266   ctx->GetBoolean ( "ConvCurve2dMode",    aParameters->ConvertCurve2d() );
267   ctx->GetBoolean ( "BezierMode",         aParameters->ConvertBezierSurf() );
268   //modes to convert elementary surfaces
269   ctx->GetBoolean ( "PlaneMode",          aParameters->ConvertPlane() );
270   //ctx->GetBoolean ("ElementarySurfMode", aParameters->ConvertElementarySurf());
271   ctx->GetBoolean ( "ConicalSurfMode", aParameters->ConvertConicalSurf());
272   ctx->GetBoolean ( "CylindricalSurfMode", aParameters->ConvertCylindricalSurf());
273   ctx->GetBoolean ( "ToroidalSurfMode", aParameters->ConvertToroidalSurf());
274   ctx->GetBoolean ( "SphericalSurfMode", aParameters->ConvertSphericalSurf());
275   
276   Handle(ShapeCustom_BSplineRestriction) LD = 
277     new ShapeCustom_BSplineRestriction ( ModeSurf, ModeC3d, ModeC2d,
278                                          aTol3d, aTol2d, aCont3d, aCont2d,
279                                          aMaxDeg, aMaxSeg, ModeDeg, Rational, aParameters );
280   LD->SetMsgRegistrator( msg );
281   TopTools_DataMapOfShapeShape map;
282   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, LD, map,  msg, Standard_True );
283   ctx->RecordModification ( map, msg );
284   ctx->SetResult ( res );
285   return Standard_True;
286 }
287
288
289 //=======================================================================
290 //function : torevol
291 //purpose  : 
292 //=======================================================================
293
294 static Standard_Boolean torevol (const Handle(ShapeProcess_Context)& context,
295                                  const Message_ProgressRange&)
296 {
297   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
298   if ( ctx.IsNull() ) return Standard_False;
299
300   // activate message mechanism if it is supported by context
301   Handle(ShapeExtend_MsgRegistrator) msg;
302   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
303
304   Handle(ShapeCustom_ConvertToRevolution) CR = new ShapeCustom_ConvertToRevolution();
305   CR->SetMsgRegistrator( msg );
306   TopTools_DataMapOfShapeShape map;
307   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, CR, map,  msg, Standard_True );
308   ctx->RecordModification ( map, msg );
309   ctx->SetResult ( res );
310   return Standard_True;
311 }
312
313
314 //=======================================================================
315 //function : swepttoelem
316 //purpose  : 
317 //=======================================================================
318
319 static Standard_Boolean swepttoelem (const Handle(ShapeProcess_Context)& context,
320                                      const Message_ProgressRange&)
321 {
322   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
323   if ( ctx.IsNull() ) return Standard_False;
324
325   // activate message mechanism if it is supported by context
326   Handle(ShapeExtend_MsgRegistrator) msg;
327   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
328
329   Handle(ShapeCustom_SweptToElementary) SE = new ShapeCustom_SweptToElementary();
330   SE->SetMsgRegistrator( msg );
331   TopTools_DataMapOfShapeShape map;
332   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, SE, map, msg, Standard_True  );
333   ctx->RecordModification ( map, msg );
334   ctx->SetResult ( res );
335   return Standard_True;
336 }
337
338
339 //=======================================================================
340 //function : shapetobezier
341 //purpose  : 
342 //=======================================================================
343
344 static Standard_Boolean shapetobezier (const Handle(ShapeProcess_Context)& context,
345                                        const Message_ProgressRange&)
346 {
347   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
348   if ( ctx.IsNull() ) return Standard_False;
349
350   // activate message mechanism if it is supported by context
351   Handle(ShapeExtend_MsgRegistrator) msg;
352   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
353
354   Standard_Boolean ModeC3d        = ctx->BooleanVal ( "Curve3dMode",        Standard_False );
355   Standard_Boolean ModeC2d        = ctx->BooleanVal ( "Curve2dMode",        Standard_False );
356   Standard_Boolean ModeSurf       = ctx->BooleanVal ( "SurfaceMode",        Standard_False );
357   Standard_Boolean ModeLine3d     = ctx->BooleanVal ( "Line3dMode",         Standard_True );
358   Standard_Boolean ModeCircle3d   = ctx->BooleanVal ( "Circle3dMode",       Standard_True );
359   Standard_Boolean ModeConic3d    = ctx->BooleanVal ( "Conic3dMode",        Standard_True );
360   Standard_Boolean SegmentMode    = ctx->BooleanVal ( "SegmentSurfaceMode", Standard_True );
361   Standard_Boolean PlaneMode      = ctx->BooleanVal ( "PlaneMode",          Standard_True );
362   Standard_Boolean RevolutionMode = ctx->BooleanVal ( "RevolutionMode",     Standard_True );
363   Standard_Boolean ExtrusionMode  = ctx->BooleanVal ( "ExtrusionMode",      Standard_True );
364   Standard_Boolean BSplineMode    = ctx->BooleanVal ( "BSplineMode",        Standard_True );
365
366   ShapeUpgrade_ShapeConvertToBezier SCB (ctx->Result());
367   SCB.SetMsgRegistrator( msg );
368   SCB.SetSurfaceSegmentMode(SegmentMode);
369   SCB.SetSurfaceConversion (ModeSurf);
370   SCB.Set2dConversion (ModeC2d);
371   SCB.Set3dConversion (ModeC3d);
372   if(ModeC3d) {
373     SCB.Set3dLineConversion (ModeLine3d);
374     SCB.Set3dCircleConversion (ModeCircle3d);
375     SCB.Set3dConicConversion (ModeConic3d);
376   }
377   if(ModeSurf) {
378     SCB.SetPlaneMode(PlaneMode);
379     SCB.SetRevolutionMode(RevolutionMode);
380     SCB.SetExtrusionMode(ExtrusionMode);
381     SCB.SetBSplineMode(BSplineMode);
382   }
383   
384   Standard_Real maxTol, minTol;
385   if ( ctx->GetReal ( "MaxTolerance",   maxTol ) ) SCB.SetMaxTolerance(maxTol);
386   if ( ctx->GetReal ( "MinCurveLength", minTol ) ) SCB.SetMinTolerance(minTol);
387   
388   Standard_Boolean EdgeMode;
389   if ( ctx->GetBoolean ( "EdgeMode", EdgeMode ) ) SCB.SetEdgeMode(EdgeMode);
390  
391   if ( ! SCB.Perform() && SCB.Status (ShapeExtend_FAIL) ) { 
392 #ifdef OCCT_DEBUG
393     std::cout<<"Shape::ShapeConvertToBezier failed"<<std::endl; // !!!!
394 #endif
395     return Standard_False;
396   }
397
398   ctx->RecordModification ( SCB.GetContext(), msg );
399   ctx->SetResult ( SCB.Result() );
400   return Standard_True;
401 }
402
403
404 //=======================================================================
405 //function : converttobspline
406 //purpose  : 
407 //=======================================================================
408
409 static Standard_Boolean converttobspline (const Handle(ShapeProcess_Context)& context,
410                                           const Message_ProgressRange&)
411 {
412   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
413   if ( ctx.IsNull() ) return Standard_False;
414
415   // activate message mechanism if it is supported by context
416   Handle(ShapeExtend_MsgRegistrator) msg;
417   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
418
419   Standard_Boolean extrMode   = ctx->BooleanVal ( "LinearExtrusionMode", Standard_True );
420   Standard_Boolean revolMode  = ctx->BooleanVal ( "RevolutionMode",      Standard_True ); 
421   Standard_Boolean offsetMode = ctx->BooleanVal ( "OffsetMode",          Standard_True );
422   
423   Handle(ShapeCustom_ConvertToBSpline) CBspl = new ShapeCustom_ConvertToBSpline();
424   CBspl->SetExtrusionMode(extrMode);
425   CBspl->SetRevolutionMode(revolMode);
426   CBspl->SetOffsetMode(offsetMode);
427   CBspl->SetMsgRegistrator( msg );
428     
429   TopTools_DataMapOfShapeShape map;
430   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier( ctx->Result(), ctx, CBspl, map,  msg, Standard_True );
431   ctx->RecordModification ( map, msg );
432   ctx->SetResult ( res );
433   return Standard_True;
434 }
435
436
437 //=======================================================================
438 //function : splitcontinuity
439 //purpose  : Split by Continuity
440 //=======================================================================
441
442 static Standard_Boolean splitcontinuity (const Handle(ShapeProcess_Context)& context,
443                                          const Message_ProgressRange&)
444 {
445   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
446   if ( ctx.IsNull() ) return Standard_False;
447
448   // activate message mechanism if it is supported by context
449   Handle(ShapeExtend_MsgRegistrator) msg;
450   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
451
452   Standard_Real aTol = ctx->RealVal ( "Tolerance3d", 1.e-7 );
453   Standard_Real aTol2D = ctx->RealVal ( "Tolerance2d", 1.e-9 );
454   GeomAbs_Shape aCrvCont = ctx->ContinuityVal ( "CurveContinuity",   GeomAbs_C1 );
455   GeomAbs_Shape aSrfCont = ctx->ContinuityVal ( "SurfaceContinuity", GeomAbs_C1 );
456   GeomAbs_Shape aCrv2dCont = ctx->ContinuityVal ( "Curve2dContinuity",   GeomAbs_C1 );
457   ShapeUpgrade_ShapeDivideContinuity tool (ctx->Result());
458   tool.SetBoundaryCriterion(aCrvCont);
459   tool.SetSurfaceCriterion(aSrfCont);
460   tool.SetPCurveCriterion(aCrv2dCont);
461   tool.SetTolerance(aTol);
462   tool.SetTolerance2d(aTol2D);
463
464   tool.SetMsgRegistrator( msg );
465     
466   Standard_Real maxTol;
467   if ( ctx->GetReal ( "MaxTolerance", maxTol ) ) tool.SetMaxTolerance(maxTol);
468   
469   if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) { 
470 #ifdef OCCT_DEBUG
471     std::cout<<"SplitContinuity failed"<<std::endl; 
472 #endif
473     return Standard_False; 
474   }
475   
476   ctx->RecordModification ( tool.GetContext(), msg );
477   ctx->SetResult ( tool.Result() );
478   return Standard_True;
479 }
480
481
482 //=======================================================================
483 //function : splitclosedfaces
484 //purpose  : 
485 //=======================================================================
486
487 static Standard_Boolean splitclosedfaces (const Handle(ShapeProcess_Context)& context,
488                                           const Message_ProgressRange&)
489 {
490   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
491   if ( ctx.IsNull() ) return Standard_False;
492
493   // activate message mechanism if it is supported by context
494   Handle(ShapeExtend_MsgRegistrator) msg;
495   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
496
497   ShapeUpgrade_ShapeDivideClosed tool ( ctx->Result() );
498   tool.SetMsgRegistrator( msg );
499
500   Standard_Real closeTol;
501   if ( ctx->GetReal ( "CloseTolerance", closeTol ) ) tool.SetPrecision(closeTol);
502   
503   Standard_Real maxTol;
504   if ( ctx->GetReal ( "MaxTolerance", maxTol ) ) tool.SetMaxTolerance(maxTol);
505   
506   Standard_Integer num = ctx->IntegerVal ( "NbSplitPoints", 1 );
507    Standard_Boolean hasSeg = Standard_True;
508    ctx->GetBoolean ( "SegmentSurfaceMode", hasSeg);
509   
510   tool.SetNbSplitPoints(num);
511   tool.SetSurfaceSegmentMode(hasSeg);
512   if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) { 
513 #ifdef OCCT_DEBUG
514     std::cout<<"Splitting of closed faces failed"<<std::endl; 
515 #endif
516     return Standard_False; 
517   }
518   
519   ctx->RecordModification ( tool.GetContext(), msg );
520   ctx->SetResult ( tool.Result() );
521   return Standard_True;
522 }
523
524
525 //=======================================================================
526 //function : fixfacesize
527 //purpose  : 
528 //=======================================================================
529
530 static Standard_Boolean fixfacesize (const Handle(ShapeProcess_Context)& context,
531                                      const Message_ProgressRange&)
532 {
533   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
534   if ( ctx.IsNull() ) return Standard_False;
535
536   // activate message mechanism if it is supported by context
537   Handle(ShapeExtend_MsgRegistrator) msg;
538   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
539
540   Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
541   ShapeFix_FixSmallFace FSC;
542   FSC.SetContext(reshape);
543   FSC.Init(ctx->Result());
544   FSC.SetMsgRegistrator ( msg );
545
546   Standard_Real aTol;
547   if ( ctx->GetReal ( "Tolerance", aTol ) ) FSC.SetPrecision (aTol);
548
549   FSC.Perform();
550   TopoDS_Shape newsh = FSC.Shape();
551
552   if ( newsh != ctx->Result() ) {
553     ctx->RecordModification ( reshape, msg );
554     ctx->SetResult ( newsh );
555   }
556
557   return Standard_True;
558 }
559
560
561 //=======================================================================
562 //function : fixwgaps
563 //purpose  : 
564 //=======================================================================
565
566 static Standard_Boolean fixwgaps (const Handle(ShapeProcess_Context)& context,
567                                   const Message_ProgressRange&)
568 {
569   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
570   if ( ctx.IsNull() ) return Standard_False;
571
572   // activate message mechanism if it is supported by context
573   Handle(ShapeExtend_MsgRegistrator) msg;
574   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
575
576   Standard_Real aTol3d = ctx->RealVal ( "Tolerance3d", Precision::Confusion() );
577
578   Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
579   Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe(ctx->Result());
580   sfwf->SetMsgRegistrator( msg );
581   sfwf->SetContext(reshape);
582   sfwf->SetPrecision(aTol3d);
583   sfwf->FixWireGaps();
584   TopoDS_Shape result = sfwf->Shape();
585
586   if ( result != ctx->Result() ) {
587     ctx->RecordModification ( reshape, msg );
588     ctx->SetResult ( result );
589   }
590   return Standard_True;
591 }
592
593 //=======================================================================
594 //function : dropsmallsolids
595 //purpose  : 
596 //=======================================================================
597
598 static Standard_Boolean dropsmallsolids (const Handle(ShapeProcess_Context)& context,
599                                          const Message_ProgressRange&)
600 {
601   Handle(ShapeProcess_ShapeContext) ctx =
602     Handle(ShapeProcess_ShapeContext)::DownCast (context);
603   if (ctx.IsNull()) return Standard_False;
604
605   // activate message mechanism if it is supported by context
606   Handle(ShapeExtend_MsgRegistrator) msg;
607   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
608
609   ShapeFix_FixSmallSolid FSS;
610   FSS.SetMsgRegistrator( msg );
611
612   Standard_Real aThreshold;
613   Standard_Integer aMode;
614   if (ctx->GetInteger ("FixMode", aMode))
615     FSS.SetFixMode (aMode);
616   if (ctx->GetReal ("VolumeThreshold", aThreshold))
617     FSS.SetVolumeThreshold (aThreshold);
618   if (ctx->GetReal ("WidthFactorThreshold", aThreshold))
619     FSS.SetWidthFactorThreshold (aThreshold);
620
621   Standard_Boolean aMerge = Standard_False;
622   ctx->GetBoolean ("MergeSolids", aMerge);
623
624   Handle(ShapeBuild_ReShape) aReShape = new ShapeBuild_ReShape;
625
626   TopoDS_Shape aResult;
627   if (aMerge)
628     aResult = FSS.Merge  (ctx->Result(), aReShape);
629   else
630     aResult = FSS.Remove (ctx->Result(), aReShape);
631
632   if (aResult != ctx->Result())
633   {
634     ctx->RecordModification (aReShape, msg);
635     ctx->SetResult (aResult);
636   }
637
638   return Standard_True;
639 }
640
641 /*
642 //=======================================================================
643 //function :
644 //purpose  : 
645 //=======================================================================
646
647 static Standard_Boolean dropsmalledges (const Handle(ShapeProcess_Context)& context)
648 {
649   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
650   if ( ctx.IsNull() ) return Standard_False;
651
652   //Handle(ShapeBuild_ReShape) ctx = new ShapeBuild_ReShape;
653   Handle(MoniFrame_Element) elem = astep->Operand();
654   TopoDS_Shape Shape = MoniShape::Shape(elem);
655   Standard_Real aTol3d = Precision::Confusion();
656   Handle(MoniFrame_TypedValue) ptol3d   = aproc->StackParam("Tolerance3d",Standard_True);
657   if (ptol3d->IsSetValue()) aTol3d = ptol3d->RealValue();
658   Handle(ShapeBuild_ReShape) context; 
659   TopoDS_Shape result = ShapeFix::RemoveSmallEdges(Shape,aTol3d,context);
660   if (result == Shape) astep->AddTouched (aproc->Infos(),MoniShape::Element(Shape));
661   else 
662     MoniShapeSW::UpdateFromReShape (aproc->Infos(), astep, Shape, context, TopAbs_FACE);
663   return 0;
664 }
665 */
666
667
668 //=======================================================================
669 //function : mergesmalledges
670 //purpose  : 
671 //=======================================================================
672
673 static Standard_Boolean mergesmalledges (const Handle(ShapeProcess_Context)& context,
674                                          const Message_ProgressRange&)
675 {
676   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
677   if ( ctx.IsNull() ) return Standard_False;
678
679   // activate message mechanism if it is supported by context
680   Handle(ShapeExtend_MsgRegistrator) msg;
681   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
682
683   Standard_Real aTol3d = ctx->RealVal ( "Tolerance3d", Precision::Confusion() );
684
685   Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
686   ShapeFix_Wireframe ShapeFixWireframe(ctx->Result());
687   ShapeFixWireframe.SetContext(reshape);
688   ShapeFixWireframe.SetPrecision(aTol3d);
689   ShapeFixWireframe.SetMsgRegistrator( msg );
690   
691   if ( ShapeFixWireframe.FixSmallEdges() ) {
692     ctx->RecordModification ( reshape, msg );
693   }
694   return Standard_True;
695 }
696
697
698 //=======================================================================
699 //function : fixshape
700 //purpose  : 
701 //=======================================================================
702
703 static Standard_Boolean fixshape (const Handle(ShapeProcess_Context)& context,
704                                   const Message_ProgressRange& theProgress)
705 {
706   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
707   if ( ctx.IsNull() ) return Standard_False;
708
709   // activate message mechanism if it is supported by context
710   Handle(ShapeExtend_MsgRegistrator) msg;
711   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
712   
713   Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
714   Handle(ShapeFix_Face) sff  = sfs->FixFaceTool();
715   Handle(ShapeFix_Wire) sfw  = sfs->FixWireTool();
716   sfs->SetMsgRegistrator( msg );
717   
718   sfs->SetPrecision    ( ctx->RealVal ( "Tolerance3d",    Precision::Confusion() ) );
719   sfs->SetMinTolerance ( ctx->RealVal ( "MinTolerance3d", Precision::Confusion() ) );
720   sfs->SetMaxTolerance ( ctx->RealVal ( "MaxTolerance3d", Precision::Confusion() ) );   
721
722   sfs->FixFreeShellMode()     = ctx->IntegerVal ( "FixFreeShellMode", -1 );
723   sfs->FixFreeFaceMode()      = ctx->IntegerVal ( "FixFreeFaceMode", -1 );
724   sfs->FixFreeWireMode()      = ctx->IntegerVal ( "FixFreeWireMode", -1 );
725   sfs->FixSameParameterMode() = ctx->IntegerVal ( "FixSameParameterMode", -1 );
726   sfs->FixSolidMode()         = ctx->IntegerVal ( "FixSolidMode", -1 );
727   sfs->FixVertexPositionMode() = ctx->IntegerVal ( "FixVertexPositionMode", 0 );
728   sfs->FixVertexTolMode()      = ctx->IntegerVal ( "FixVertexToleranceMode", -1 );
729
730   sfs->FixSolidTool()->FixShellMode() = ctx->IntegerVal ( "FixShellMode", -1 );
731   sfs->FixSolidTool()->FixShellOrientationMode() = ctx->IntegerVal ( "FixShellOrientationMode", -1 );
732   sfs->FixSolidTool()->CreateOpenSolidMode() = ctx->BooleanVal ( "CreateOpenSolidMode", Standard_True );
733
734   sfs->FixShellTool()->FixFaceMode() = ctx->IntegerVal ( "FixFaceMode", -1 );
735   sfs->FixShellTool()->SetNonManifoldFlag(ctx->IsNonManifold());
736   sfs->FixShellTool()->FixOrientationMode() = ctx->IntegerVal("FixFaceOrientationMode", -1);
737
738   //parameters for ShapeFix_Face
739   sff->FixWireMode()              = ctx->IntegerVal ( "FixWireMode", -1 );
740   sff->FixOrientationMode()       = ctx->IntegerVal ( "FixOrientationMode", -1 );
741   sff->FixAddNaturalBoundMode()   = ctx->IntegerVal ( "FixAddNaturalBoundMode", -1 );
742   sff->FixMissingSeamMode()       = ctx->IntegerVal ( "FixMissingSeamMode", -1 );
743   sff->FixSmallAreaWireMode()     = ctx->IntegerVal ( "FixSmallAreaWireMode", -1 );
744   sff->RemoveSmallAreaFaceMode()  = ctx->IntegerVal ( "RemoveSmallAreaFaceMode", -1 );
745   sff->FixIntersectingWiresMode() = ctx->IntegerVal ( "FixIntersectingWiresMode", -1 );
746   sff->FixLoopWiresMode()         = ctx->IntegerVal ( "FixLoopWiresMode", -1 );
747   sff->FixSplitFaceMode()         = ctx->IntegerVal ( "FixSplitFaceMode", -1 );
748
749   //parameters for ShapeFix_Wire
750   sfw->ModifyTopologyMode()   = ctx->BooleanVal ( "ModifyTopologyMode",   Standard_False );
751   sfw->ModifyGeometryMode()   = ctx->BooleanVal ( "ModifyGeometryMode",   Standard_True );
752   sfw->ClosedWireMode()       = ctx->BooleanVal ( "ClosedWireMode",       Standard_True );
753   sfw->PreferencePCurveMode() = ctx->BooleanVal ( "PreferencePCurveMode", Standard_True );
754   sfw->FixReorderMode()              = ctx->IntegerVal ( "FixReorderMode", -1 );
755   sfw->FixSmallMode()                = ctx->IntegerVal ( "FixSmallMode", -1 );
756   sfw->FixConnectedMode()            = ctx->IntegerVal ( "FixConnectedMode", -1 );
757   sfw->FixEdgeCurvesMode()           = ctx->IntegerVal ( "FixEdgeCurvesMode", -1 );
758   sfw->FixDegeneratedMode()          = ctx->IntegerVal ( "FixDegeneratedMode", -1 );
759   sfw->FixLackingMode()              = ctx->IntegerVal ( "FixLackingMode", -1 );
760   sfw->FixSelfIntersectionMode()     = ctx->IntegerVal ( "FixSelfIntersectionMode", -1 );
761   sfw->ModifyRemoveLoopMode()        = ctx->IntegerVal ( "RemoveLoopMode", -1);
762   sfw->FixReversed2dMode()           = ctx->IntegerVal ( "FixReversed2dMode", -1 );
763   sfw->FixRemovePCurveMode()         = ctx->IntegerVal ( "FixRemovePCurveMode", -1 );
764   sfw->FixRemoveCurve3dMode()        = ctx->IntegerVal ( "FixRemoveCurve3dMode", -1 );
765   sfw->FixAddPCurveMode()            = ctx->IntegerVal ( "FixAddPCurveMode", -1 );
766   sfw->FixAddCurve3dMode()           = ctx->IntegerVal ( "FixAddCurve3dMode", -1 );
767   sfw->FixShiftedMode()              = ctx->IntegerVal ( "FixShiftedMode", -1 );
768   sfw->FixSeamMode()                 = ctx->IntegerVal ( "FixSeamMode", -1 );
769   sfw->FixSameParameterMode()        = ctx->IntegerVal ( "FixEdgeSameParameterMode", -1 );
770   sfw->FixNotchedEdgesMode()         = ctx->IntegerVal ( "FixNotchedEdgesMode", -1 );
771   sfw->FixTailMode() = ctx->IntegerVal("FixTailMode", 0);
772   sfw->SetMaxTailAngle(ctx->RealVal("MaxTailAngle", 0) * (M_PI / 180));
773   sfw->SetMaxTailWidth(ctx->RealVal("MaxTailWidth", -1));
774   sfw->FixSelfIntersectingEdgeMode() = ctx->IntegerVal ( "FixSelfIntersectingEdgeMode", -1 );
775   sfw->FixIntersectingEdgesMode()    = ctx->IntegerVal ( "FixIntersectingEdgesMode", -1 );
776   sfw->FixNonAdjacentIntersectingEdgesMode() = ctx->IntegerVal ( "FixNonAdjacentIntersectingEdgesMode", -1 );
777   Message_ProgressScope aPS(theProgress, NULL, 2);
778   if (sfw->FixTailMode() == 1)
779   {
780     sfw->FixTailMode() = 0;
781     sfs->Init(ctx->Result());
782     sfs->Perform (aPS.Next());
783     sfw->FixTailMode() = 1;
784     if (aPS.UserBreak())
785     {
786       return Standard_False;
787     }
788
789     TopoDS_Shape result = sfs->Shape();
790     if (result != ctx->Result() ||
791       (!msg.IsNull() && !msg->MapShape().IsEmpty()))
792     {
793       ctx->RecordModification(sfs->Context(), msg);
794       ctx->SetResult(result);
795     }
796   }
797
798   sfs->Init(ctx->Result());
799   sfs->Perform (aPS.Next());
800   if (aPS.UserBreak())
801   {
802     return Standard_False;
803   }
804
805   TopoDS_Shape result = sfs->Shape();
806   if (( result != ctx->Result() ) ||
807       ( !msg.IsNull() && !msg->MapShape().IsEmpty()))
808   {
809     ctx->RecordModification ( sfs->Context(), msg );
810     ctx->SetResult ( result );
811   }
812   return Standard_True;
813 }
814
815
816 //=======================================================================
817 //function : spltclosededges
818 //purpose  : 
819 //=======================================================================
820
821 static Standard_Boolean spltclosededges (const Handle(ShapeProcess_Context)& context,
822                                          const Message_ProgressRange&)
823 {
824   Handle(ShapeProcess_ShapeContext) ctx =
825     Handle(ShapeProcess_ShapeContext)::DownCast ( context );
826   if ( ctx.IsNull() ) return Standard_False;
827
828   // activate message mechanism if it is supported by context
829   Handle(ShapeExtend_MsgRegistrator) msg;
830   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
831
832   Standard_Integer nbSplits = ctx->IntegerVal ( "NbSplitPoints", 1 );
833
834   ShapeUpgrade_ShapeDivideClosedEdges tool (ctx->Result());
835   tool.SetNbSplitPoints(nbSplits);
836   tool.SetMsgRegistrator( msg );
837   
838   if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) { 
839 #ifdef OCCT_DEBUG
840     std::cout<<"Splitting of closed edges failed"<<std::endl; 
841 #endif
842     return Standard_False; 
843   }
844   
845   ctx->RecordModification ( tool.GetContext(), msg );
846   ctx->SetResult ( tool.Result() );
847   return Standard_True;
848 }
849
850
851 //=======================================================================
852 //function : splitcommonvertex
853 //purpose  : Two wires have common vertex - this case is valid in BRep model
854 //           and isn't valid in STEP => before writing into STEP it is necessary
855 //           to split this vertex (each wire must has one vertex)
856 //=======================================================================
857 static Standard_Boolean splitcommonvertex (const Handle(ShapeProcess_Context)& context,
858                                            const Message_ProgressRange&)
859 {
860   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
861   if ( ctx.IsNull() ) return Standard_False;
862
863   // activate message mechanism if it is supported by context
864   Handle(ShapeExtend_MsgRegistrator) msg;
865   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
866
867   Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
868   ShapeFix_SplitCommonVertex SCV;
869   SCV.SetContext(reshape);
870   SCV.Init(ctx->Result());
871
872   SCV.SetMsgRegistrator( msg );
873
874   SCV.Perform();
875   TopoDS_Shape newsh = SCV.Shape();
876
877   if ( newsh != ctx->Result() ) {
878     ctx->RecordModification ( reshape, msg );
879     ctx->SetResult ( newsh );
880   }
881
882   return Standard_True;
883 }
884
885
886 //=======================================================================
887 //function : Init
888 //purpose  : Register standard operators
889 //=======================================================================
890
891 void ShapeProcess_OperLibrary::Init ()
892 {
893   static Standard_Boolean done = Standard_False;
894   if ( done ) return;
895   done = Standard_True;
896
897   ShapeExtend::Init();
898
899   ShapeProcess::RegisterOperator ( "DirectFaces",           new ShapeProcess_UOperator ( directfaces ) );
900   ShapeProcess::RegisterOperator ( "SameParameter",         new ShapeProcess_UOperator ( sameparam ) );
901   ShapeProcess::RegisterOperator ( "SetTolerance",          new ShapeProcess_UOperator ( settol ) );  
902   ShapeProcess::RegisterOperator ( "SplitAngle",            new ShapeProcess_UOperator ( splitangle ) );
903   ShapeProcess::RegisterOperator ( "BSplineRestriction",    new ShapeProcess_UOperator ( bsplinerestriction ) );
904   ShapeProcess::RegisterOperator ( "ElementaryToRevolution",new ShapeProcess_UOperator ( torevol ) );
905   ShapeProcess::RegisterOperator ( "SweptToElementary",     new ShapeProcess_UOperator ( swepttoelem ) );
906   ShapeProcess::RegisterOperator ( "SurfaceToBSpline",      new ShapeProcess_UOperator ( converttobspline ) );
907   ShapeProcess::RegisterOperator ( "ToBezier",              new ShapeProcess_UOperator ( shapetobezier ) );
908   ShapeProcess::RegisterOperator ( "SplitContinuity",       new ShapeProcess_UOperator ( splitcontinuity ) );
909   ShapeProcess::RegisterOperator ( "SplitClosedFaces",      new ShapeProcess_UOperator ( splitclosedfaces ) );
910   ShapeProcess::RegisterOperator ( "FixWireGaps",           new ShapeProcess_UOperator ( fixwgaps ) );
911   ShapeProcess::RegisterOperator ( "FixFaceSize",           new ShapeProcess_UOperator ( fixfacesize ) );
912   ShapeProcess::RegisterOperator ( "DropSmallSolids",       new ShapeProcess_UOperator ( dropsmallsolids ) );
913   ShapeProcess::RegisterOperator ( "DropSmallEdges",        new ShapeProcess_UOperator ( mergesmalledges ) );
914   ShapeProcess::RegisterOperator ( "FixShape",              new ShapeProcess_UOperator ( fixshape ) );
915   ShapeProcess::RegisterOperator ( "SplitClosedEdges",      new ShapeProcess_UOperator ( spltclosededges ) );
916   ShapeProcess::RegisterOperator ( "SplitCommonVertex",     new ShapeProcess_UOperator ( splitcommonvertex ) );
917 }