0024157: Parallelization of assembly part of BO
[occt.git] / src / ShapeProcess / ShapeProcess_OperLibrary.cxx
1 // Created on: 2000-08-31
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2000-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #include <ShapeProcess_OperLibrary.ixx>
22
23 #include <Precision.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopoDS_Compound.hxx>
26 #include <TopoDS_Iterator.hxx>
27 #include <BRep_Builder.hxx>
28 #include <BRepLib.hxx>
29
30 #include <Message_MsgFile.hxx>
31 #include <Message_ProgressIndicator.hxx>
32
33 #include <ShapeExtend_MsgRegistrator.hxx>
34 #include <ShapeProcess.hxx>
35 #include <ShapeProcess_UOperator.hxx>
36 #include <ShapeProcess_ShapeContext.hxx>
37
38 #include <BRepTools_Modifier.hxx>
39 #include <BRepTools_Modification.hxx>
40 #include <ShapeCustom_DirectModification.hxx>
41 #include <ShapeCustom_RestrictionParameters.hxx>
42 #include <ShapeCustom_BSplineRestriction.hxx>
43 #include <ShapeCustom_ConvertToRevolution.hxx>
44 #include <ShapeCustom_SweptToElementary.hxx>
45 #include <ShapeCustom_ConvertToBSpline.hxx>
46
47 #include <ShapeExtend.hxx>
48 #include <ShapeBuild_ReShape.hxx>
49 #include <ShapeUpgrade_ShapeDivideAngle.hxx>
50 #include <ShapeUpgrade_ShapeConvertToBezier.hxx>
51 #include <ShapeUpgrade_ShapeDivideContinuity.hxx>
52 #include <ShapeUpgrade_ShapeDivideClosed.hxx>
53 #include <ShapeUpgrade_ShapeDivideClosedEdges.hxx>
54
55 #include <ShapeFix_ShapeTolerance.hxx>
56 #include <ShapeFix_Shape.hxx>
57 #include <ShapeFix_Face.hxx>
58 #include <ShapeFix_Wire.hxx>
59 #include <ShapeFix_FixSmallFace.hxx>
60 #include <ShapeFix_Wireframe.hxx>
61 #include <ShapeFix.hxx>
62 #include <ShapeFix_SplitCommonVertex.hxx>
63
64
65 //=======================================================================
66 //function : ApplyModifier
67 //purpose  : Applies BRepTools_Modification to a shape,
68 //           taking into account sharing of components of compounds
69 //=======================================================================
70
71 TopoDS_Shape ShapeProcess_OperLibrary::ApplyModifier (const TopoDS_Shape &S, 
72                                                       const Handle(ShapeProcess_ShapeContext)& context,
73                                                       const Handle(BRepTools_Modification) &M,
74                                                       TopTools_DataMapOfShapeShape &map)
75 {
76   // protect against INTERNAL/EXTERNAL shapes
77   TopoDS_Shape SF = S.Oriented(TopAbs_FORWARD);
78
79   // Process COMPOUNDs separately in order to handle sharing in assemblies
80   if ( SF.ShapeType() == TopAbs_COMPOUND ) {
81     Standard_Boolean locModified = Standard_False;
82     TopoDS_Compound C;
83     BRep_Builder B;
84     B.MakeCompound ( C );
85     for ( TopoDS_Iterator it(SF); it.More(); it.Next() ) {
86       TopoDS_Shape shape = it.Value();
87       TopLoc_Location L = shape.Location(), nullLoc;
88       shape.Location ( nullLoc );
89       TopoDS_Shape res;
90       if(map.IsBound ( shape ))
91         res = map.Find ( shape ).Oriented ( shape.Orientation() );
92
93       else {
94         res = ApplyModifier (shape, context, M, map );
95         map.Bind ( shape, res );
96       }
97       if ( ! res.IsSame ( shape ) ) locModified = Standard_True;
98       res.Location ( L );
99       B.Add ( C, res );
100     }
101     if ( ! locModified ) return S;
102     
103     map.Bind ( SF, C );
104     return C.Oriented ( S.Orientation() );
105   }
106
107   // Modify the shape
108   BRepTools_Modifier MD(SF,M);
109   context->RecordModification ( SF, MD );
110   return MD.ModifiedShape(SF).Oriented(S.Orientation());
111 }
112
113
114 //=======================================================================
115 //function : directfaces
116 //purpose  : 
117 //=======================================================================
118
119 static Standard_Boolean directfaces (const Handle(ShapeProcess_Context)& context)
120 {
121   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
122   if ( ctx.IsNull() ) return Standard_False;
123
124   Handle(ShapeCustom_DirectModification) DM = new ShapeCustom_DirectModification;
125   TopTools_DataMapOfShapeShape map;
126   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, DM, map );
127   ctx->RecordModification ( map );
128   ctx->SetResult ( res );
129   return Standard_True;
130 }
131
132
133 //=======================================================================
134 //function : sameparam
135 //purpose  : 
136 //=======================================================================
137
138 static Standard_Boolean sameparam (const Handle(ShapeProcess_Context)& context)
139 {
140   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
141   if ( ctx.IsNull() ) return Standard_False;
142   ShapeFix::SameParameter ( ctx->Result(), 
143                             ctx->IntegerVal ( "Force", Standard_False ),
144                             ctx->RealVal ( "Tolerance3d", Precision::Confusion() /* -1 */) ); 
145   // WARNING: no update of context yet!
146   return Standard_True;
147 }
148
149
150 //=======================================================================
151 //function : settol
152 //purpose  : 
153 //=======================================================================
154
155 static Standard_Boolean settol (const Handle(ShapeProcess_Context)& context)
156 {
157   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
158   if ( ctx.IsNull() ) return Standard_False;
159
160   Standard_Real val;
161   if ( ctx->IntegerVal ( "Mode", 0 ) >0 && ctx->GetReal ( "Value", val ) ) {
162     Standard_Real rat = ctx->RealVal ( "Ratio", 1. );
163     if ( rat >= 1 ) {
164       ShapeFix_ShapeTolerance SFST;
165       SFST.LimitTolerance (ctx->Result(), val/rat, val*rat);
166     }
167   }
168
169   BRepLib::UpdateTolerances (ctx->Result(),Standard_True);
170
171   Standard_Real reg;
172   if ( ctx->GetReal ("Regularity", reg) )  
173     BRepLib::EncodeRegularity (ctx->Result(), reg);
174
175   // WARNING: no update of context yet!
176   return Standard_True;
177 }
178
179
180 //=======================================================================
181 //function : splitangle
182 //purpose  : 
183 //=======================================================================
184
185 static Standard_Boolean splitangle (const Handle(ShapeProcess_Context)& context)
186 {
187   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
188   if ( ctx.IsNull() ) return Standard_False;
189   
190   ShapeUpgrade_ShapeDivideAngle SDA ( ctx->RealVal ( "Angle", 2*M_PI ), ctx->Result() );
191   SDA.SetMaxTolerance ( ctx->RealVal ( "MaxTolerance", 1. ) );
192   
193   if ( ! SDA.Perform() && SDA.Status (ShapeExtend_FAIL) ) {
194 #ifdef DEB
195     cout<<"ShapeDivideAngle failed"<<endl;
196 #endif
197     return Standard_False;
198   }
199   
200   ctx->RecordModification ( SDA.GetContext() );
201   ctx->SetResult ( SDA.Result() );
202   return Standard_True;
203 }
204
205
206 //=======================================================================
207 //function : bsplinerestriction
208 //purpose  : 
209 //=======================================================================
210
211 static Standard_Boolean bsplinerestriction (const Handle(ShapeProcess_Context)& context)
212 {
213   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
214   if ( ctx.IsNull() ) return Standard_False;
215
216   Standard_Boolean ModeSurf  = ctx->IntegerVal ( "SurfaceMode", Standard_True );
217   Standard_Boolean ModeC3d   = ctx->IntegerVal ( "Curve3dMode", Standard_True );
218   Standard_Boolean ModeC2d   = ctx->IntegerVal ( "Curve2dMode", Standard_True );
219
220   Standard_Real aTol3d = ctx->RealVal ( "Tolerance3d", 0.01 );
221   Standard_Real aTol2d = ctx->RealVal ( "Tolerance2d", 1e-06 );
222   
223   GeomAbs_Shape aCont3d = ctx->ContinuityVal ( "Continuity3d", GeomAbs_C1 );
224   GeomAbs_Shape aCont2d = ctx->ContinuityVal ( "Continuity2d", GeomAbs_C2 );
225
226   Standard_Integer aMaxDeg = ctx->IntegerVal ( "RequiredDegree", 9 );
227   Standard_Integer aMaxSeg = ctx->IntegerVal ( "RequiredNbSegments", 10000 );
228   
229   Standard_Boolean ModeDeg  = ctx->IntegerVal ( "PreferDegree", Standard_True );
230   Standard_Boolean Rational = ctx->IntegerVal ( "RationalToPolynomial", Standard_False );
231   
232   Handle(ShapeCustom_RestrictionParameters)   aParameters = new ShapeCustom_RestrictionParameters;
233   ctx->GetInteger ( "MaxDegree",          aParameters->GMaxDegree() );
234   ctx->GetInteger ( "MaxNbSegments",      aParameters->GMaxSeg() );
235   ctx->GetBoolean ( "OffsetSurfaceMode",  aParameters->ConvertOffsetSurf() );
236   ctx->GetBoolean ( "OffsetCurve3dMode",  aParameters->ConvertOffsetCurv3d() );
237   ctx->GetBoolean ( "OffsetCurve2dMode",  aParameters->ConvertOffsetCurv2d() );
238   ctx->GetBoolean ( "LinearExtrusionMode",aParameters->ConvertExtrusionSurf() );
239   ctx->GetBoolean ( "RevolutionMode",     aParameters->ConvertRevolutionSurf() );
240   ctx->GetBoolean ( "SegmentSurfaceMode", aParameters->SegmentSurfaceMode() );
241   ctx->GetBoolean ( "ConvCurve3dMode",    aParameters->ConvertCurve3d() );
242   ctx->GetBoolean ( "ConvCurve2dMode",    aParameters->ConvertCurve2d() );
243   ctx->GetBoolean ( "BezierMode",         aParameters->ConvertBezierSurf() );
244   //modes to convert elementary surfaces
245   ctx->GetBoolean ( "PlaneMode",          aParameters->ConvertPlane() );
246   //ctx->GetBoolean ("ElementarySurfMode", aParameters->ConvertElementarySurf());
247   ctx->GetBoolean ( "ConicalSurfMode", aParameters->ConvertConicalSurf());
248   ctx->GetBoolean ( "CylindricalSurfMode", aParameters->ConvertCylindricalSurf());
249   ctx->GetBoolean ( "ToroidalSurfMode", aParameters->ConvertToroidalSurf());
250   ctx->GetBoolean ( "SphericalSurfMode", aParameters->ConvertSphericalSurf());
251   
252   Handle(ShapeCustom_BSplineRestriction) LD = 
253     new ShapeCustom_BSplineRestriction ( ModeSurf, ModeC3d, ModeC2d,
254                                          aTol3d, aTol2d, aCont3d, aCont2d,
255                                          aMaxDeg, aMaxSeg, ModeDeg, Rational, aParameters );
256   TopTools_DataMapOfShapeShape map;
257   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, LD, map );
258   ctx->RecordModification ( map );
259   ctx->SetResult ( res );
260   return Standard_True;
261 }
262
263
264 //=======================================================================
265 //function : torevol
266 //purpose  : 
267 //=======================================================================
268
269 static Standard_Boolean torevol (const Handle(ShapeProcess_Context)& context)
270 {
271   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
272   if ( ctx.IsNull() ) return Standard_False;
273
274   Handle(ShapeCustom_ConvertToRevolution) CR =
275     new ShapeCustom_ConvertToRevolution();
276   TopTools_DataMapOfShapeShape map;
277   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, CR, map );
278   ctx->RecordModification ( map );
279   ctx->SetResult ( res );
280   return Standard_True;
281 }
282
283
284 //=======================================================================
285 //function : swepttoelem
286 //purpose  : 
287 //=======================================================================
288
289 static Standard_Boolean swepttoelem (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   Handle(ShapeCustom_SweptToElementary) SE = new ShapeCustom_SweptToElementary();
295   TopTools_DataMapOfShapeShape map;
296   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, SE, map );
297   ctx->RecordModification ( map );
298   ctx->SetResult ( res );
299   return Standard_True;
300 }
301
302
303 //=======================================================================
304 //function : shapetobezier
305 //purpose  : 
306 //=======================================================================
307
308 static Standard_Boolean shapetobezier (const Handle(ShapeProcess_Context)& context)
309 {
310   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
311   if ( ctx.IsNull() ) return Standard_False;
312
313   Standard_Boolean ModeC3d        = ctx->BooleanVal ( "Curve3dMode",        Standard_False );
314   Standard_Boolean ModeC2d        = ctx->BooleanVal ( "Curve2dMode",        Standard_False );
315   Standard_Boolean ModeSurf       = ctx->BooleanVal ( "SurfaceMode",        Standard_False );
316   Standard_Boolean ModeLine3d     = ctx->BooleanVal ( "Line3dMode",         Standard_True );
317   Standard_Boolean ModeCircle3d   = ctx->BooleanVal ( "Circle3dMode",       Standard_True );
318   Standard_Boolean ModeConic3d    = ctx->BooleanVal ( "Conic3dMode",        Standard_True );
319   Standard_Boolean SegmentMode    = ctx->BooleanVal ( "SegmentSurfaceMode", Standard_True );
320   Standard_Boolean PlaneMode      = ctx->BooleanVal ( "PlaneMode",          Standard_True );
321   Standard_Boolean RevolutionMode = ctx->BooleanVal ( "RevolutionMode",     Standard_True );
322   Standard_Boolean ExtrusionMode  = ctx->BooleanVal ( "ExtrusionMode",      Standard_True );
323   Standard_Boolean BSplineMode    = ctx->BooleanVal ( "BSplineMode",        Standard_True );
324
325   ShapeUpgrade_ShapeConvertToBezier SCB (ctx->Result());
326   SCB.SetSurfaceSegmentMode(SegmentMode);
327   SCB.SetSurfaceConversion (ModeSurf);
328   SCB.Set2dConversion (ModeC2d);
329   SCB.Set3dConversion (ModeC3d);
330   if(ModeC3d) {
331     SCB.Set3dLineConversion (ModeLine3d);
332     SCB.Set3dCircleConversion (ModeCircle3d);
333     SCB.Set3dConicConversion (ModeConic3d);
334   }
335   if(ModeSurf) {
336     SCB.SetPlaneMode(PlaneMode);
337     SCB.SetRevolutionMode(RevolutionMode);
338     SCB.SetExtrusionMode(ExtrusionMode);
339     SCB.SetBSplineMode(BSplineMode);
340   }
341   
342   Standard_Real maxTol, minTol;
343   if ( ctx->GetReal ( "MaxTolerance",   maxTol ) ) SCB.SetMaxTolerance(maxTol);
344   if ( ctx->GetReal ( "MinCurveLength", minTol ) ) SCB.SetMinTolerance(minTol);
345   
346   Standard_Boolean EdgeMode;
347   if ( ctx->GetBoolean ( "EdgeMode", EdgeMode ) ) SCB.SetEdgeMode(EdgeMode);
348  
349   if ( ! SCB.Perform() && SCB.Status (ShapeExtend_FAIL) ) { 
350 #ifdef DEB
351     cout<<"Shape::ShapeConvertToBezier failed"<<endl; // !!!!
352 #endif
353     return Standard_False;
354   }
355
356   ctx->RecordModification ( SCB.GetContext() );
357   ctx->SetResult ( SCB.Result() );
358   return Standard_True;
359 }
360
361
362 //=======================================================================
363 //function : converttobspline
364 //purpose  : 
365 //=======================================================================
366
367 static Standard_Boolean converttobspline (const Handle(ShapeProcess_Context)& context)
368 {
369   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
370   if ( ctx.IsNull() ) return Standard_False;
371
372   Standard_Boolean extrMode   = ctx->BooleanVal ( "LinearExtrusionMode", Standard_True );
373   Standard_Boolean revolMode  = ctx->BooleanVal ( "RevolutionMode",      Standard_True ); 
374   Standard_Boolean offsetMode = ctx->BooleanVal ( "OffsetMode",          Standard_True );
375   
376   Handle(ShapeCustom_ConvertToBSpline) CBspl = new ShapeCustom_ConvertToBSpline();
377   CBspl->SetExtrusionMode(extrMode);
378   CBspl->SetRevolutionMode(revolMode);
379   CBspl->SetOffsetMode(offsetMode);
380     
381   TopTools_DataMapOfShapeShape map;
382   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, CBspl, map );
383   ctx->RecordModification ( map );
384   ctx->SetResult ( res );
385   return Standard_True;
386 }
387
388
389 //=======================================================================
390 //function : splitcontinuity
391 //purpose  : Split by Continuity
392 //=======================================================================
393
394 static Standard_Boolean splitcontinuity (const Handle(ShapeProcess_Context)& context)
395 {
396   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
397   if ( ctx.IsNull() ) return Standard_False;
398
399   Standard_Real aTol = ctx->RealVal ( "Tolerance3d", 1.e-7 );
400   Standard_Real aTol2D = ctx->RealVal ( "Tolerance2d", 1.e-9 );
401   GeomAbs_Shape aCrvCont = ctx->ContinuityVal ( "CurveContinuity",   GeomAbs_C1 );
402   GeomAbs_Shape aSrfCont = ctx->ContinuityVal ( "SurfaceContinuity", GeomAbs_C1 );
403   GeomAbs_Shape aCrv2dCont = ctx->ContinuityVal ( "Curve2dContinuity",   GeomAbs_C1 );
404   ShapeUpgrade_ShapeDivideContinuity tool (ctx->Result());
405   tool.SetBoundaryCriterion(aCrvCont);
406   tool.SetSurfaceCriterion(aSrfCont);
407   tool.SetPCurveCriterion(aCrv2dCont);
408   tool.SetTolerance(aTol);
409   tool.SetTolerance2d(aTol2D);
410   
411   Standard_Real maxTol;
412   if ( ctx->GetReal ( "MaxTolerance", maxTol ) ) tool.SetMaxTolerance(maxTol);
413   
414   if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) { 
415 #ifdef DEB
416     cout<<"SplitContinuity failed"<<endl; 
417 #endif
418     return Standard_False; 
419   }
420   
421   ctx->RecordModification ( tool.GetContext() );
422   ctx->SetResult ( tool.Result() );
423   return Standard_True;
424 }
425
426
427 //=======================================================================
428 //function : splitclosedfaces
429 //purpose  : 
430 //=======================================================================
431
432 static Standard_Boolean splitclosedfaces (const Handle(ShapeProcess_Context)& context)
433 {
434   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
435   if ( ctx.IsNull() ) return Standard_False;
436
437   ShapeUpgrade_ShapeDivideClosed tool ( ctx->Result() );
438
439   Standard_Real closeTol;
440   if ( ctx->GetReal ( "CloseTolerance", closeTol ) ) tool.SetPrecision(closeTol);
441   
442   Standard_Real maxTol;
443   if ( ctx->GetReal ( "MaxTolerance", maxTol ) ) tool.SetMaxTolerance(maxTol);
444   
445   Standard_Integer num = ctx->IntegerVal ( "NbSplitPoints", 1 );
446    Standard_Boolean hasSeg = Standard_True;
447    ctx->GetBoolean ( "SegmentSurfaceMode", hasSeg);
448   
449   tool.SetNbSplitPoints(num);
450   tool.SetSurfaceSegmentMode(hasSeg);
451   if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) { 
452 #ifdef DEB
453     cout<<"Splitting of closed faces failed"<<endl; 
454 #endif
455     return Standard_False; 
456   }
457   
458   ctx->RecordModification ( tool.GetContext() );
459   ctx->SetResult ( tool.Result() );
460   return Standard_True;
461 }
462
463
464 //=======================================================================
465 //function : fixfacesize
466 //purpose  : 
467 //=======================================================================
468
469 static Standard_Boolean fixfacesize (const Handle(ShapeProcess_Context)& context)
470 {
471   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
472   if ( ctx.IsNull() ) return Standard_False;
473
474   Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
475   ShapeFix_FixSmallFace FSC;
476   FSC.SetContext(reshape);
477   FSC.Init(ctx->Result());
478
479   Standard_Real aTol;
480   if ( ctx->GetReal ( "Tolerance", aTol ) ) FSC.SetPrecision (aTol);
481
482   FSC.Perform();
483   TopoDS_Shape newsh = FSC.Shape();
484
485   if ( newsh != ctx->Result() ) {
486     ctx->RecordModification ( reshape );
487     ctx->SetResult ( newsh );
488   }
489
490   return Standard_True;
491 }
492
493
494 //=======================================================================
495 //function : fixwgaps
496 //purpose  : 
497 //=======================================================================
498
499 static Standard_Boolean fixwgaps (const Handle(ShapeProcess_Context)& context)
500 {
501   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
502   if ( ctx.IsNull() ) return Standard_False;
503
504   Standard_Real aTol3d = ctx->RealVal ( "Tolerance3d", Precision::Confusion() );
505
506   Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
507   Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe(ctx->Result());
508   sfwf->SetContext(reshape);
509   sfwf->SetPrecision(aTol3d);
510   sfwf->FixWireGaps();
511   TopoDS_Shape result = sfwf->Shape();
512
513   if ( result != ctx->Result() ) {
514     ctx->RecordModification ( reshape );
515     ctx->SetResult ( result );
516   }
517   return Standard_True;
518 }
519
520 /*
521 //=======================================================================
522 //function :
523 //purpose  : 
524 //=======================================================================
525
526 static Standard_Boolean dropsmalledges (const Handle(ShapeProcess_Context)& context)
527 {
528   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
529   if ( ctx.IsNull() ) return Standard_False;
530
531   //Handle(ShapeBuild_ReShape) ctx = new ShapeBuild_ReShape;
532   Handle(MoniFrame_Element) elem = astep->Operand();
533   TopoDS_Shape Shape = MoniShape::Shape(elem);
534   Standard_Real aTol3d = Precision::Confusion();
535   Handle(MoniFrame_TypedValue) ptol3d   = aproc->StackParam("Tolerance3d",Standard_True);
536   if (ptol3d->IsSetValue()) aTol3d = ptol3d->RealValue();
537   Handle(ShapeBuild_ReShape) context; 
538   TopoDS_Shape result = ShapeFix::RemoveSmallEdges(Shape,aTol3d,context);
539   if (result == Shape) astep->AddTouched (aproc->Infos(),MoniShape::Element(Shape));
540   else 
541     MoniShapeSW::UpdateFromReShape (aproc->Infos(), astep, Shape, context, TopAbs_FACE);
542   return 0;
543 }
544 */
545
546
547 //=======================================================================
548 //function : mergesmalledges
549 //purpose  : 
550 //=======================================================================
551
552 static Standard_Boolean mergesmalledges (const Handle(ShapeProcess_Context)& context)
553 {
554   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
555   if ( ctx.IsNull() ) return Standard_False;
556
557   Standard_Real aTol3d = ctx->RealVal ( "Tolerance3d", Precision::Confusion() );
558
559   Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
560   ShapeFix_Wireframe ShapeFixWireframe(ctx->Result());
561   ShapeFixWireframe.SetContext(reshape);
562   ShapeFixWireframe.SetPrecision(aTol3d);
563   
564   if ( ShapeFixWireframe.FixSmallEdges() ) {
565     ctx->RecordModification ( reshape );
566   }
567   return Standard_True;
568 }
569
570
571 //=======================================================================
572 //function : fixshape
573 //purpose  : 
574 //=======================================================================
575
576 static Standard_Boolean fixshape (const Handle(ShapeProcess_Context)& context)
577 {
578   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
579   if ( ctx.IsNull() ) return Standard_False;
580
581   // activate message mechanism if it is supported by context
582   Handle(ShapeExtend_MsgRegistrator) msg;
583   if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
584   
585   Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
586   sfs->SetMsgRegistrator ( msg );
587   Handle(ShapeFix_Face) sff  = Handle(ShapeFix_Face)::DownCast(sfs->FixFaceTool());
588   Handle(ShapeFix_Wire) sfw  = Handle(ShapeFix_Wire)::DownCast(sfs->FixWireTool());
589   
590   sfs->SetPrecision    ( ctx->RealVal ( "Tolerance3d",    Precision::Confusion() ) );
591   sfs->SetMinTolerance ( ctx->RealVal ( "MinTolerance3d", Precision::Confusion() ) );
592   sfs->SetMaxTolerance ( ctx->RealVal ( "MaxTolerance3d", Precision::Confusion() ) );   
593
594   sfs->FixFreeShellMode()     = ctx->IntegerVal ( "FixFreeShellMode", -1 );
595   sfs->FixFreeFaceMode()      = ctx->IntegerVal ( "FixFreeFaceMode", -1 );
596   sfs->FixFreeWireMode()      = ctx->IntegerVal ( "FixFreeWireMode", -1 );
597   sfs->FixSameParameterMode() = ctx->IntegerVal ( "FixSameParameterMode", -1 );
598   sfs->FixSolidMode()         = ctx->IntegerVal ( "FixSolidMode", -1 );
599   sfs->FixVertexPositionMode() = ctx->IntegerVal ( "FixVertexPositionMode", 0 );
600
601   sfs->FixSolidTool()->FixShellMode() = ctx->IntegerVal ( "FixShellMode", -1 );
602   sfs->FixSolidTool()->CreateOpenSolidMode() = ctx->IntegerVal ( "CreateOpenSolidMode", 1 );
603
604   sfs->FixShellTool()->FixFaceMode() = ctx->IntegerVal ( "FixFaceMode", -1 );
605
606   //parameters for ShapeFix_Face
607   sff->FixWireMode()              = ctx->IntegerVal ( "FixWireMode", -1 );
608   sff->FixOrientationMode()       = ctx->IntegerVal ( "FixOrientationMode", -1 );
609   sff->FixAddNaturalBoundMode()   = ctx->IntegerVal ( "FixAddNaturalBoundMode", -1 );
610   sff->FixMissingSeamMode()       = ctx->IntegerVal ( "FixMissingSeamMode", -1 );
611   sff->FixSmallAreaWireMode()     = ctx->IntegerVal ( "FixSmallAreaWireMode", -1 );
612   sff->FixIntersectingWiresMode() = ctx->IntegerVal ( "FixIntersectingWiresMode", -1 );
613   sff->FixLoopWiresMode()         = ctx->IntegerVal ( "FixLoopWiresMode", -1 );
614   sff->FixSplitFaceMode()         = ctx->IntegerVal ( "FixSplitFaceMode", -1 );
615
616   //parameters for ShapeFix_Wire
617   sfw->ModifyTopologyMode()   = ctx->BooleanVal ( "ModifyTopologyMode",   Standard_False );
618   sfw->ModifyGeometryMode()   = ctx->BooleanVal ( "ModifyGeometryMode",   Standard_True );
619   sfw->ClosedWireMode()       = ctx->BooleanVal ( "ClosedWireMode",       Standard_True );
620   sfw->PreferencePCurveMode() = ctx->BooleanVal ( "PreferencePCurveMode", Standard_True );
621   sfw->FixReorderMode()              = ctx->IntegerVal ( "FixReorderMode", -1 );
622   sfw->FixSmallMode()                = ctx->IntegerVal ( "FixSmallMode", -1 );
623   sfw->FixConnectedMode()            = ctx->IntegerVal ( "FixConnectedMode", -1 );
624   sfw->FixEdgeCurvesMode()           = ctx->IntegerVal ( "FixEdgeCurvesMode", -1 );
625   sfw->FixDegeneratedMode()          = ctx->IntegerVal ( "FixDegeneratedMode", -1 );
626   sfw->FixLackingMode()              = ctx->IntegerVal ( "FixLackingMode", -1 );
627   sfw->FixSelfIntersectionMode()     = ctx->IntegerVal ( "FixSelfIntersectionMode", -1 );
628   sfw->ModifyRemoveLoopMode()        = ctx->IntegerVal ( "RemoveLoopMode", -1);
629   sfw->FixReversed2dMode()           = ctx->IntegerVal ( "FixReversed2dMode", -1 );
630   sfw->FixRemovePCurveMode()         = ctx->IntegerVal ( "FixRemovePCurveMode", -1 );
631   sfw->FixRemoveCurve3dMode()        = ctx->IntegerVal ( "FixRemoveCurve3dMode", -1 );
632   sfw->FixAddPCurveMode()            = ctx->IntegerVal ( "FixAddPCurveMode", -1 );
633   sfw->FixAddCurve3dMode()           = ctx->IntegerVal ( "FixAddCurve3dMode", -1 );
634   sfw->FixShiftedMode()              = ctx->IntegerVal ( "FixShiftedMode", -1 );
635   sfw->FixSeamMode()                 = ctx->IntegerVal ( "FixSeamMode", -1 );
636   sfw->FixSameParameterMode()        = ctx->IntegerVal ( "FixEdgeSameParameterMode", -1 );
637   sfw->FixNotchedEdgesMode()         = ctx->IntegerVal ( "FixNotchedEdgesMode", -1 );
638   sfw->FixSelfIntersectingEdgeMode() = ctx->IntegerVal ( "FixSelfIntersectingEdgeMode", -1 );
639   sfw->FixIntersectingEdgesMode()    = ctx->IntegerVal ( "FixIntersectingEdgesMode", -1 );
640   sfw->FixNonAdjacentIntersectingEdgesMode() = ctx->IntegerVal ( "FixNonAdjacentIntersectingEdgesMode", -1 );
641   
642   sfs->Init(ctx->Result());
643   sfs->Perform(ctx->Progress());
644
645   if ( !ctx->Progress().IsNull() && ctx->Progress()->UserBreak() )
646     return Standard_False;
647
648   TopoDS_Shape result = sfs->Shape();
649   if ( result != ctx->Result() ) {
650     ctx->RecordModification ( sfs->Context(), msg );
651     ctx->SetResult ( result );
652   }
653   return Standard_True;
654 }
655
656
657 //=======================================================================
658 //function : spltclosededges
659 //purpose  : 
660 //=======================================================================
661
662 static Standard_Boolean spltclosededges (const Handle(ShapeProcess_Context)& context)
663 {
664   Handle(ShapeProcess_ShapeContext) ctx =
665     Handle(ShapeProcess_ShapeContext)::DownCast ( context );
666   if ( ctx.IsNull() ) return Standard_False;
667
668   Standard_Integer nbSplits = ctx->IntegerVal ( "NbSplitPoints", 1 );
669
670   ShapeUpgrade_ShapeDivideClosedEdges tool (ctx->Result());
671   tool.SetNbSplitPoints(nbSplits);
672   
673   if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) { 
674 #ifdef DEB
675     cout<<"Splitting of closed edges failed"<<endl; 
676 #endif
677     return Standard_False; 
678   }
679   
680   ctx->RecordModification ( tool.GetContext() );
681   ctx->SetResult ( tool.Result() );
682   return Standard_True;
683 }
684
685
686 //=======================================================================
687 //function : splitcommonvertex
688 //purpose  : Two wires have common vertex - this case is valid in BRep model
689 //           and isn't valid in STEP => before writing into STEP it is necessary
690 //           to split this vertex (each wire must has one vertex)
691 //=======================================================================
692 static Standard_Boolean splitcommonvertex (const Handle(ShapeProcess_Context)& context)
693 {
694   Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
695   if ( ctx.IsNull() ) return Standard_False;
696
697   Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
698   ShapeFix_SplitCommonVertex SCV;
699   SCV.SetContext(reshape);
700   SCV.Init(ctx->Result());
701
702   SCV.Perform();
703   TopoDS_Shape newsh = SCV.Shape();
704
705   if ( newsh != ctx->Result() ) {
706     ctx->RecordModification ( reshape );
707     ctx->SetResult ( newsh );
708   }
709
710   return Standard_True;
711 }
712
713
714 //=======================================================================
715 //function : Init
716 //purpose  : Register standard operators
717 //=======================================================================
718
719 void ShapeProcess_OperLibrary::Init ()
720 {
721   static Standard_Boolean done = Standard_False;
722   if ( done ) return;
723   done = Standard_True;
724
725   ShapeExtend::Init();
726   
727   // load message file for Shape Processing
728   Message_MsgFile::LoadFromEnv ("CSF_SHMessage", "SHAPE");
729
730   ShapeProcess::RegisterOperator ( "DirectFaces",           new ShapeProcess_UOperator ( directfaces ) );
731   ShapeProcess::RegisterOperator ( "SameParameter",         new ShapeProcess_UOperator ( sameparam ) );
732   ShapeProcess::RegisterOperator ( "SetTolerance",          new ShapeProcess_UOperator ( settol ) );  
733   ShapeProcess::RegisterOperator ( "SplitAngle",            new ShapeProcess_UOperator ( splitangle ) );
734   ShapeProcess::RegisterOperator ( "BSplineRestriction",    new ShapeProcess_UOperator ( bsplinerestriction ) );
735   ShapeProcess::RegisterOperator ( "ElementaryToRevolution",new ShapeProcess_UOperator ( torevol ) );
736   ShapeProcess::RegisterOperator ( "SweptToElementary",     new ShapeProcess_UOperator ( swepttoelem ) );
737   ShapeProcess::RegisterOperator ( "SurfaceToBSpline",      new ShapeProcess_UOperator ( converttobspline ) );
738   ShapeProcess::RegisterOperator ( "ToBezier",              new ShapeProcess_UOperator ( shapetobezier ) );
739   ShapeProcess::RegisterOperator ( "SplitContinuity",       new ShapeProcess_UOperator ( splitcontinuity ) );
740   ShapeProcess::RegisterOperator ( "SplitClosedFaces",      new ShapeProcess_UOperator ( splitclosedfaces ) );
741   ShapeProcess::RegisterOperator ( "FixWireGaps",           new ShapeProcess_UOperator ( fixwgaps ) );
742   ShapeProcess::RegisterOperator ( "FixFaceSize",           new ShapeProcess_UOperator ( fixfacesize ) );
743   ShapeProcess::RegisterOperator ( "DropSmallEdges",        new ShapeProcess_UOperator ( mergesmalledges ) );
744   ShapeProcess::RegisterOperator ( "FixShape",              new ShapeProcess_UOperator ( fixshape ) );
745   ShapeProcess::RegisterOperator ( "SplitClosedEdges",      new ShapeProcess_UOperator ( spltclosededges ) );
746   ShapeProcess::RegisterOperator ( "SplitCommonVertex",     new ShapeProcess_UOperator ( splitcommonvertex ) );
747 }