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