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