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