1 // Created on: 2000-08-31
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
17 #include <BRep_Builder.hxx>
18 #include <BRepLib.hxx>
19 #include <BRepTools_Modifier.hxx>
20 #include <Message_ProgressScope.hxx>
21 #include <Precision.hxx>
22 #include <ShapeBuild_ReShape.hxx>
23 #include <ShapeCustom_BSplineRestriction.hxx>
24 #include <ShapeCustom_ConvertToBSpline.hxx>
25 #include <ShapeCustom_ConvertToRevolution.hxx>
26 #include <ShapeCustom_DirectModification.hxx>
27 #include <ShapeCustom_RestrictionParameters.hxx>
28 #include <ShapeCustom_SweptToElementary.hxx>
29 #include <ShapeExtend_MsgRegistrator.hxx>
30 #include <ShapeFix.hxx>
31 #include <ShapeFix_FixSmallFace.hxx>
32 #include <ShapeFix_FixSmallSolid.hxx>
33 #include <ShapeFix_Shape.hxx>
34 #include <ShapeFix_ShapeTolerance.hxx>
35 #include <ShapeFix_SplitCommonVertex.hxx>
36 #include <ShapeFix_Wire.hxx>
37 #include <ShapeFix_Wireframe.hxx>
38 #include <ShapeProcess.hxx>
39 #include <ShapeProcess_OperLibrary.hxx>
40 #include <ShapeProcess_ShapeContext.hxx>
41 #include <ShapeProcess_UOperator.hxx>
42 #include <ShapeUpgrade_ShapeConvertToBezier.hxx>
43 #include <ShapeUpgrade_ShapeDivideAngle.hxx>
44 #include <ShapeUpgrade_ShapeDivideClosed.hxx>
45 #include <ShapeUpgrade_ShapeDivideClosedEdges.hxx>
46 #include <ShapeUpgrade_ShapeDivideContinuity.hxx>
47 #include <TopoDS_Compound.hxx>
48 #include <TopoDS_Iterator.hxx>
49 #include <TopoDS_Shape.hxx>
51 //=======================================================================
52 //function : ApplyModifier
53 //purpose : Applies BRepTools_Modification to a shape,
54 // taking into account sharing of components of compounds
55 //=======================================================================
56 TopoDS_Shape ShapeProcess_OperLibrary::ApplyModifier (const TopoDS_Shape &S,
57 const Handle(ShapeProcess_ShapeContext)& context,
58 const Handle(BRepTools_Modification) &M,
59 TopTools_DataMapOfShapeShape &map,
60 const Handle(ShapeExtend_MsgRegistrator) &msg,
61 Standard_Boolean theMutableInput)
63 // protect against INTERNAL/EXTERNAL shapes
64 TopoDS_Shape SF = S.Oriented(TopAbs_FORWARD);
66 // Process COMPOUNDs separately in order to handle sharing in assemblies
67 if ( SF.ShapeType() == TopAbs_COMPOUND ) {
68 Standard_Boolean locModified = Standard_False;
72 for ( TopoDS_Iterator it(SF); it.More(); it.Next() ) {
73 TopoDS_Shape shape = it.Value();
74 TopLoc_Location L = shape.Location(), nullLoc;
75 shape.Location ( nullLoc );
77 if(map.IsBound ( shape ))
78 res = map.Find ( shape ).Oriented ( shape.Orientation() );
81 res = ApplyModifier (shape, context, M, map, 0, theMutableInput );
82 map.Bind ( shape, res );
84 if ( ! res.IsSame ( shape ) ) locModified = Standard_True;
85 res.Location ( L, Standard_False );
88 if ( ! locModified ) return S;
91 return C.Oriented ( S.Orientation() );
95 BRepTools_Modifier MD(SF);
96 MD.SetMutableInput(theMutableInput);
98 context->RecordModification ( SF, MD, msg );
99 return MD.ModifiedShape(SF).Oriented(S.Orientation());
103 //=======================================================================
104 //function : directfaces
106 //=======================================================================
108 static Standard_Boolean directfaces (const Handle(ShapeProcess_Context)& context,
109 const Message_ProgressRange&)
111 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
112 if ( ctx.IsNull() ) return Standard_False;
114 // activate message mechanism if it is supported by context
115 Handle(ShapeExtend_MsgRegistrator) msg;
116 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
118 Handle(ShapeCustom_DirectModification) DM = new ShapeCustom_DirectModification;
119 DM->SetMsgRegistrator( msg );
120 TopTools_DataMapOfShapeShape map;
121 TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, DM, map, msg, Standard_True );
122 ctx->RecordModification ( map, msg );
123 ctx->SetResult ( res );
124 return Standard_True;
128 //=======================================================================
129 //function : sameparam
131 //=======================================================================
133 static Standard_Boolean sameparam (const Handle(ShapeProcess_Context)& context,
134 const Message_ProgressRange&)
136 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
137 if ( ctx.IsNull() ) return Standard_False;
139 // activate message mechanism if it is supported by context
140 Handle(ShapeExtend_MsgRegistrator) msg;
141 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
143 ShapeFix::SameParameter ( ctx->Result(),
144 ctx->BooleanVal ( "Force", Standard_False ),
145 ctx->RealVal ( "Tolerance3d", Precision::Confusion() /* -1 */),
146 Message_ProgressRange(), msg );
150 // WARNING: not FULL update of context yet!
151 Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
152 ctx->RecordModification( reshape, msg );
154 return Standard_True;
158 //=======================================================================
161 //=======================================================================
163 static Standard_Boolean settol (const Handle(ShapeProcess_Context)& context,
164 const Message_ProgressRange&)
166 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
167 if ( ctx.IsNull() ) return Standard_False;
170 if ( ctx->IntegerVal ( "Mode", 0 ) >0 && ctx->GetReal ( "Value", val ) ) {
171 Standard_Real rat = ctx->RealVal ( "Ratio", 1. );
173 ShapeFix_ShapeTolerance SFST;
174 SFST.LimitTolerance (ctx->Result(), val/rat, val*rat);
178 BRepLib::UpdateTolerances (ctx->Result(),Standard_True);
181 if ( ctx->GetReal ("Regularity", reg) )
182 BRepLib::EncodeRegularity (ctx->Result(), reg);
184 // WARNING: no update of context yet!
185 return Standard_True;
189 //=======================================================================
190 //function : splitangle
192 //=======================================================================
194 static Standard_Boolean splitangle (const Handle(ShapeProcess_Context)& context,
195 const Message_ProgressRange&)
197 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
198 if ( ctx.IsNull() ) return Standard_False;
200 // activate message mechanism if it is supported by context
201 Handle(ShapeExtend_MsgRegistrator) msg;
202 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
204 ShapeUpgrade_ShapeDivideAngle SDA ( ctx->RealVal ( "Angle", 2*M_PI ), ctx->Result() );
205 SDA.SetMaxTolerance ( ctx->RealVal ( "MaxTolerance", 1. ) );
206 SDA.SetMsgRegistrator ( msg );
208 if ( ! SDA.Perform() && SDA.Status (ShapeExtend_FAIL) ) {
210 std::cout<<"ShapeDivideAngle failed"<<std::endl;
212 return Standard_False;
215 ctx->RecordModification ( SDA.GetContext(), msg );
216 ctx->SetResult ( SDA.Result() );
217 return Standard_True;
221 //=======================================================================
222 //function : bsplinerestriction
224 //=======================================================================
226 static Standard_Boolean bsplinerestriction (const Handle(ShapeProcess_Context)& context,
227 const Message_ProgressRange&)
229 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
230 if ( ctx.IsNull() ) return Standard_False;
232 // activate message mechanism if it is supported by context
233 Handle(ShapeExtend_MsgRegistrator) msg;
234 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
236 Standard_Boolean ModeSurf = ctx->BooleanVal ( "SurfaceMode", Standard_True );
237 Standard_Boolean ModeC3d = ctx->BooleanVal ( "Curve3dMode", Standard_True );
238 Standard_Boolean ModeC2d = ctx->BooleanVal ( "Curve2dMode", Standard_True );
240 Standard_Real aTol3d = ctx->RealVal ( "Tolerance3d", 0.01 );
241 Standard_Real aTol2d = ctx->RealVal ( "Tolerance2d", 1e-06 );
243 GeomAbs_Shape aCont3d = ctx->ContinuityVal ( "Continuity3d", GeomAbs_C1 );
244 GeomAbs_Shape aCont2d = ctx->ContinuityVal ( "Continuity2d", GeomAbs_C2 );
246 Standard_Integer aMaxDeg = ctx->IntegerVal ( "RequiredDegree", 9 );
247 Standard_Integer aMaxSeg = ctx->IntegerVal ( "RequiredNbSegments", 10000 );
249 Standard_Boolean ModeDeg = ctx->BooleanVal ( "PreferDegree", Standard_True );
250 Standard_Boolean Rational = ctx->BooleanVal ( "RationalToPolynomial", Standard_False );
252 Handle(ShapeCustom_RestrictionParameters) aParameters = new ShapeCustom_RestrictionParameters;
253 ctx->GetInteger ( "MaxDegree", aParameters->GMaxDegree() );
254 ctx->GetInteger ( "MaxNbSegments", aParameters->GMaxSeg() );
255 ctx->GetBoolean ( "OffsetSurfaceMode", aParameters->ConvertOffsetSurf() );
256 ctx->GetBoolean ( "OffsetCurve3dMode", aParameters->ConvertOffsetCurv3d() );
257 ctx->GetBoolean ( "OffsetCurve2dMode", aParameters->ConvertOffsetCurv2d() );
258 ctx->GetBoolean ( "LinearExtrusionMode",aParameters->ConvertExtrusionSurf() );
259 ctx->GetBoolean ( "RevolutionMode", aParameters->ConvertRevolutionSurf() );
260 ctx->GetBoolean ( "SegmentSurfaceMode", aParameters->SegmentSurfaceMode() );
261 ctx->GetBoolean ( "ConvCurve3dMode", aParameters->ConvertCurve3d() );
262 ctx->GetBoolean ( "ConvCurve2dMode", aParameters->ConvertCurve2d() );
263 ctx->GetBoolean ( "BezierMode", aParameters->ConvertBezierSurf() );
264 //modes to convert elementary surfaces
265 ctx->GetBoolean ( "PlaneMode", aParameters->ConvertPlane() );
266 //ctx->GetBoolean ("ElementarySurfMode", aParameters->ConvertElementarySurf());
267 ctx->GetBoolean ( "ConicalSurfMode", aParameters->ConvertConicalSurf());
268 ctx->GetBoolean ( "CylindricalSurfMode", aParameters->ConvertCylindricalSurf());
269 ctx->GetBoolean ( "ToroidalSurfMode", aParameters->ConvertToroidalSurf());
270 ctx->GetBoolean ( "SphericalSurfMode", aParameters->ConvertSphericalSurf());
272 Handle(ShapeCustom_BSplineRestriction) LD =
273 new ShapeCustom_BSplineRestriction ( ModeSurf, ModeC3d, ModeC2d,
274 aTol3d, aTol2d, aCont3d, aCont2d,
275 aMaxDeg, aMaxSeg, ModeDeg, Rational, aParameters );
276 LD->SetMsgRegistrator( msg );
277 TopTools_DataMapOfShapeShape map;
278 TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, LD, map, msg, Standard_True );
279 ctx->RecordModification ( map, msg );
280 ctx->SetResult ( res );
281 return Standard_True;
285 //=======================================================================
288 //=======================================================================
290 static Standard_Boolean torevol (const Handle(ShapeProcess_Context)& context,
291 const Message_ProgressRange&)
293 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
294 if ( ctx.IsNull() ) return Standard_False;
296 // activate message mechanism if it is supported by context
297 Handle(ShapeExtend_MsgRegistrator) msg;
298 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
300 Handle(ShapeCustom_ConvertToRevolution) CR = new ShapeCustom_ConvertToRevolution();
301 CR->SetMsgRegistrator( msg );
302 TopTools_DataMapOfShapeShape map;
303 TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, CR, map, msg, Standard_True );
304 ctx->RecordModification ( map, msg );
305 ctx->SetResult ( res );
306 return Standard_True;
310 //=======================================================================
311 //function : swepttoelem
313 //=======================================================================
315 static Standard_Boolean swepttoelem (const Handle(ShapeProcess_Context)& context,
316 const Message_ProgressRange&)
318 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
319 if ( ctx.IsNull() ) return Standard_False;
321 // activate message mechanism if it is supported by context
322 Handle(ShapeExtend_MsgRegistrator) msg;
323 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
325 Handle(ShapeCustom_SweptToElementary) SE = new ShapeCustom_SweptToElementary();
326 SE->SetMsgRegistrator( msg );
327 TopTools_DataMapOfShapeShape map;
328 TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, SE, map, msg, Standard_True );
329 ctx->RecordModification ( map, msg );
330 ctx->SetResult ( res );
331 return Standard_True;
335 //=======================================================================
336 //function : shapetobezier
338 //=======================================================================
340 static Standard_Boolean shapetobezier (const Handle(ShapeProcess_Context)& context,
341 const Message_ProgressRange&)
343 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
344 if ( ctx.IsNull() ) return Standard_False;
346 // activate message mechanism if it is supported by context
347 Handle(ShapeExtend_MsgRegistrator) msg;
348 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
350 Standard_Boolean ModeC3d = ctx->BooleanVal ( "Curve3dMode", Standard_False );
351 Standard_Boolean ModeC2d = ctx->BooleanVal ( "Curve2dMode", Standard_False );
352 Standard_Boolean ModeSurf = ctx->BooleanVal ( "SurfaceMode", Standard_False );
353 Standard_Boolean ModeLine3d = ctx->BooleanVal ( "Line3dMode", Standard_True );
354 Standard_Boolean ModeCircle3d = ctx->BooleanVal ( "Circle3dMode", Standard_True );
355 Standard_Boolean ModeConic3d = ctx->BooleanVal ( "Conic3dMode", Standard_True );
356 Standard_Boolean SegmentMode = ctx->BooleanVal ( "SegmentSurfaceMode", Standard_True );
357 Standard_Boolean PlaneMode = ctx->BooleanVal ( "PlaneMode", Standard_True );
358 Standard_Boolean RevolutionMode = ctx->BooleanVal ( "RevolutionMode", Standard_True );
359 Standard_Boolean ExtrusionMode = ctx->BooleanVal ( "ExtrusionMode", Standard_True );
360 Standard_Boolean BSplineMode = ctx->BooleanVal ( "BSplineMode", Standard_True );
362 ShapeUpgrade_ShapeConvertToBezier SCB (ctx->Result());
363 SCB.SetMsgRegistrator( msg );
364 SCB.SetSurfaceSegmentMode(SegmentMode);
365 SCB.SetSurfaceConversion (ModeSurf);
366 SCB.Set2dConversion (ModeC2d);
367 SCB.Set3dConversion (ModeC3d);
369 SCB.Set3dLineConversion (ModeLine3d);
370 SCB.Set3dCircleConversion (ModeCircle3d);
371 SCB.Set3dConicConversion (ModeConic3d);
374 SCB.SetPlaneMode(PlaneMode);
375 SCB.SetRevolutionMode(RevolutionMode);
376 SCB.SetExtrusionMode(ExtrusionMode);
377 SCB.SetBSplineMode(BSplineMode);
380 Standard_Real maxTol, minTol;
381 if ( ctx->GetReal ( "MaxTolerance", maxTol ) ) SCB.SetMaxTolerance(maxTol);
382 if ( ctx->GetReal ( "MinCurveLength", minTol ) ) SCB.SetMinTolerance(minTol);
384 Standard_Boolean EdgeMode;
385 if ( ctx->GetBoolean ( "EdgeMode", EdgeMode ) ) SCB.SetEdgeMode(EdgeMode);
387 if ( ! SCB.Perform() && SCB.Status (ShapeExtend_FAIL) ) {
389 std::cout<<"Shape::ShapeConvertToBezier failed"<<std::endl; // !!!!
391 return Standard_False;
394 ctx->RecordModification ( SCB.GetContext(), msg );
395 ctx->SetResult ( SCB.Result() );
396 return Standard_True;
400 //=======================================================================
401 //function : converttobspline
403 //=======================================================================
405 static Standard_Boolean converttobspline (const Handle(ShapeProcess_Context)& context,
406 const Message_ProgressRange&)
408 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
409 if ( ctx.IsNull() ) return Standard_False;
411 // activate message mechanism if it is supported by context
412 Handle(ShapeExtend_MsgRegistrator) msg;
413 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
415 Standard_Boolean extrMode = ctx->BooleanVal ( "LinearExtrusionMode", Standard_True );
416 Standard_Boolean revolMode = ctx->BooleanVal ( "RevolutionMode", Standard_True );
417 Standard_Boolean offsetMode = ctx->BooleanVal ( "OffsetMode", Standard_True );
419 Handle(ShapeCustom_ConvertToBSpline) CBspl = new ShapeCustom_ConvertToBSpline();
420 CBspl->SetExtrusionMode(extrMode);
421 CBspl->SetRevolutionMode(revolMode);
422 CBspl->SetOffsetMode(offsetMode);
423 CBspl->SetMsgRegistrator( msg );
425 TopTools_DataMapOfShapeShape map;
426 TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier( ctx->Result(), ctx, CBspl, map, msg, Standard_True );
427 ctx->RecordModification ( map, msg );
428 ctx->SetResult ( res );
429 return Standard_True;
433 //=======================================================================
434 //function : splitcontinuity
435 //purpose : Split by Continuity
436 //=======================================================================
438 static Standard_Boolean splitcontinuity (const Handle(ShapeProcess_Context)& context,
439 const Message_ProgressRange&)
441 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
442 if ( ctx.IsNull() ) return Standard_False;
444 // activate message mechanism if it is supported by context
445 Handle(ShapeExtend_MsgRegistrator) msg;
446 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
448 Standard_Real aTol = ctx->RealVal ( "Tolerance3d", 1.e-7 );
449 Standard_Real aTol2D = ctx->RealVal ( "Tolerance2d", 1.e-9 );
450 GeomAbs_Shape aCrvCont = ctx->ContinuityVal ( "CurveContinuity", GeomAbs_C1 );
451 GeomAbs_Shape aSrfCont = ctx->ContinuityVal ( "SurfaceContinuity", GeomAbs_C1 );
452 GeomAbs_Shape aCrv2dCont = ctx->ContinuityVal ( "Curve2dContinuity", GeomAbs_C1 );
453 ShapeUpgrade_ShapeDivideContinuity tool (ctx->Result());
454 tool.SetBoundaryCriterion(aCrvCont);
455 tool.SetSurfaceCriterion(aSrfCont);
456 tool.SetPCurveCriterion(aCrv2dCont);
457 tool.SetTolerance(aTol);
458 tool.SetTolerance2d(aTol2D);
460 tool.SetMsgRegistrator( msg );
462 Standard_Real maxTol;
463 if ( ctx->GetReal ( "MaxTolerance", maxTol ) ) tool.SetMaxTolerance(maxTol);
465 if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) {
467 std::cout<<"SplitContinuity failed"<<std::endl;
469 return Standard_False;
472 ctx->RecordModification ( tool.GetContext(), msg );
473 ctx->SetResult ( tool.Result() );
474 return Standard_True;
478 //=======================================================================
479 //function : splitclosedfaces
481 //=======================================================================
483 static Standard_Boolean splitclosedfaces (const Handle(ShapeProcess_Context)& context,
484 const Message_ProgressRange&)
486 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
487 if ( ctx.IsNull() ) return Standard_False;
489 // activate message mechanism if it is supported by context
490 Handle(ShapeExtend_MsgRegistrator) msg;
491 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
493 ShapeUpgrade_ShapeDivideClosed tool ( ctx->Result() );
494 tool.SetMsgRegistrator( msg );
496 Standard_Real closeTol;
497 if ( ctx->GetReal ( "CloseTolerance", closeTol ) ) tool.SetPrecision(closeTol);
499 Standard_Real maxTol;
500 if ( ctx->GetReal ( "MaxTolerance", maxTol ) ) tool.SetMaxTolerance(maxTol);
502 Standard_Integer num = ctx->IntegerVal ( "NbSplitPoints", 1 );
503 Standard_Boolean hasSeg = Standard_True;
504 ctx->GetBoolean ( "SegmentSurfaceMode", hasSeg);
506 tool.SetNbSplitPoints(num);
507 tool.SetSurfaceSegmentMode(hasSeg);
508 if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) {
510 std::cout<<"Splitting of closed faces failed"<<std::endl;
512 return Standard_False;
515 ctx->RecordModification ( tool.GetContext(), msg );
516 ctx->SetResult ( tool.Result() );
517 return Standard_True;
521 //=======================================================================
522 //function : fixfacesize
524 //=======================================================================
526 static Standard_Boolean fixfacesize (const Handle(ShapeProcess_Context)& context,
527 const Message_ProgressRange&)
529 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
530 if ( ctx.IsNull() ) return Standard_False;
532 // activate message mechanism if it is supported by context
533 Handle(ShapeExtend_MsgRegistrator) msg;
534 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
536 Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
537 ShapeFix_FixSmallFace FSC;
538 FSC.SetContext(reshape);
539 FSC.Init(ctx->Result());
540 FSC.SetMsgRegistrator ( msg );
543 if ( ctx->GetReal ( "Tolerance", aTol ) ) FSC.SetPrecision (aTol);
546 TopoDS_Shape newsh = FSC.Shape();
548 if ( newsh != ctx->Result() ) {
549 ctx->RecordModification ( reshape, msg );
550 ctx->SetResult ( newsh );
553 return Standard_True;
557 //=======================================================================
558 //function : fixwgaps
560 //=======================================================================
562 static Standard_Boolean fixwgaps (const Handle(ShapeProcess_Context)& context,
563 const Message_ProgressRange&)
565 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
566 if ( ctx.IsNull() ) return Standard_False;
568 // activate message mechanism if it is supported by context
569 Handle(ShapeExtend_MsgRegistrator) msg;
570 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
572 Standard_Real aTol3d = ctx->RealVal ( "Tolerance3d", Precision::Confusion() );
574 Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
575 Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe(ctx->Result());
576 sfwf->SetMsgRegistrator( msg );
577 sfwf->SetContext(reshape);
578 sfwf->SetPrecision(aTol3d);
580 TopoDS_Shape result = sfwf->Shape();
582 if ( result != ctx->Result() ) {
583 ctx->RecordModification ( reshape, msg );
584 ctx->SetResult ( result );
586 return Standard_True;
589 //=======================================================================
590 //function : dropsmallsolids
592 //=======================================================================
594 static Standard_Boolean dropsmallsolids (const Handle(ShapeProcess_Context)& context,
595 const Message_ProgressRange&)
597 Handle(ShapeProcess_ShapeContext) ctx =
598 Handle(ShapeProcess_ShapeContext)::DownCast (context);
599 if (ctx.IsNull()) return Standard_False;
601 // activate message mechanism if it is supported by context
602 Handle(ShapeExtend_MsgRegistrator) msg;
603 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
605 ShapeFix_FixSmallSolid FSS;
606 FSS.SetMsgRegistrator( msg );
608 Standard_Real aThreshold;
609 Standard_Integer aMode;
610 if (ctx->GetInteger ("FixMode", aMode))
611 FSS.SetFixMode (aMode);
612 if (ctx->GetReal ("VolumeThreshold", aThreshold))
613 FSS.SetVolumeThreshold (aThreshold);
614 if (ctx->GetReal ("WidthFactorThreshold", aThreshold))
615 FSS.SetWidthFactorThreshold (aThreshold);
617 Standard_Boolean aMerge = Standard_False;
618 ctx->GetBoolean ("MergeSolids", aMerge);
620 Handle(ShapeBuild_ReShape) aReShape = new ShapeBuild_ReShape;
622 TopoDS_Shape aResult;
624 aResult = FSS.Merge (ctx->Result(), aReShape);
626 aResult = FSS.Remove (ctx->Result(), aReShape);
628 if (aResult != ctx->Result())
630 ctx->RecordModification (aReShape, msg);
631 ctx->SetResult (aResult);
634 return Standard_True;
638 //=======================================================================
641 //=======================================================================
643 static Standard_Boolean dropsmalledges (const Handle(ShapeProcess_Context)& context)
645 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
646 if ( ctx.IsNull() ) return Standard_False;
648 //Handle(ShapeBuild_ReShape) ctx = new ShapeBuild_ReShape;
649 Handle(MoniFrame_Element) elem = astep->Operand();
650 TopoDS_Shape Shape = MoniShape::Shape(elem);
651 Standard_Real aTol3d = Precision::Confusion();
652 Handle(MoniFrame_TypedValue) ptol3d = aproc->StackParam("Tolerance3d",Standard_True);
653 if (ptol3d->IsSetValue()) aTol3d = ptol3d->RealValue();
654 Handle(ShapeBuild_ReShape) context;
655 TopoDS_Shape result = ShapeFix::RemoveSmallEdges(Shape,aTol3d,context);
656 if (result == Shape) astep->AddTouched (aproc->Infos(),MoniShape::Element(Shape));
658 MoniShapeSW::UpdateFromReShape (aproc->Infos(), astep, Shape, context, TopAbs_FACE);
664 //=======================================================================
665 //function : mergesmalledges
667 //=======================================================================
669 static Standard_Boolean mergesmalledges (const Handle(ShapeProcess_Context)& context,
670 const Message_ProgressRange&)
672 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
673 if ( ctx.IsNull() ) return Standard_False;
675 // activate message mechanism if it is supported by context
676 Handle(ShapeExtend_MsgRegistrator) msg;
677 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
679 Standard_Real aTol3d = ctx->RealVal ( "Tolerance3d", Precision::Confusion() );
681 Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
682 ShapeFix_Wireframe ShapeFixWireframe(ctx->Result());
683 ShapeFixWireframe.SetContext(reshape);
684 ShapeFixWireframe.SetPrecision(aTol3d);
685 ShapeFixWireframe.SetMsgRegistrator( msg );
687 if ( ShapeFixWireframe.FixSmallEdges() ) {
688 ctx->RecordModification ( reshape, msg );
690 return Standard_True;
694 //=======================================================================
695 //function : fixshape
697 //=======================================================================
699 static Standard_Boolean fixshape (const Handle(ShapeProcess_Context)& context,
700 const Message_ProgressRange& theProgress)
702 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
703 if ( ctx.IsNull() ) return Standard_False;
705 // activate message mechanism if it is supported by context
706 Handle(ShapeExtend_MsgRegistrator) msg;
707 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
709 Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
710 Handle(ShapeFix_Face) sff = sfs->FixFaceTool();
711 Handle(ShapeFix_Wire) sfw = sfs->FixWireTool();
712 sfs->SetMsgRegistrator( msg );
714 sfs->SetPrecision ( ctx->RealVal ( "Tolerance3d", Precision::Confusion() ) );
715 sfs->SetMinTolerance ( ctx->RealVal ( "MinTolerance3d", Precision::Confusion() ) );
716 sfs->SetMaxTolerance ( ctx->RealVal ( "MaxTolerance3d", Precision::Confusion() ) );
718 sfs->FixFreeShellMode() = ctx->IntegerVal ( "FixFreeShellMode", -1 );
719 sfs->FixFreeFaceMode() = ctx->IntegerVal ( "FixFreeFaceMode", -1 );
720 sfs->FixFreeWireMode() = ctx->IntegerVal ( "FixFreeWireMode", -1 );
721 sfs->FixSameParameterMode() = ctx->IntegerVal ( "FixSameParameterMode", -1 );
722 sfs->FixSolidMode() = ctx->IntegerVal ( "FixSolidMode", -1 );
723 sfs->FixVertexPositionMode() = ctx->IntegerVal ( "FixVertexPositionMode", 0 );
724 sfs->FixVertexTolMode() = ctx->IntegerVal ( "FixVertexToleranceMode", -1 );
726 sfs->FixSolidTool()->FixShellMode() = ctx->IntegerVal ( "FixShellMode", -1 );
727 sfs->FixSolidTool()->FixShellOrientationMode() = ctx->IntegerVal ( "FixShellOrientationMode", -1 );
728 sfs->FixSolidTool()->CreateOpenSolidMode() = ctx->BooleanVal ( "CreateOpenSolidMode", Standard_True );
730 sfs->FixShellTool()->FixFaceMode() = ctx->IntegerVal ( "FixFaceMode", -1 );
731 sfs->FixShellTool()->SetNonManifoldFlag(ctx->IsNonManifold());
732 sfs->FixShellTool()->FixOrientationMode() = ctx->IntegerVal("FixFaceOrientationMode", -1);
734 //parameters for ShapeFix_Face
735 sff->FixWireMode() = ctx->IntegerVal ( "FixWireMode", -1 );
736 sff->FixOrientationMode() = ctx->IntegerVal ( "FixOrientationMode", -1 );
737 sff->FixAddNaturalBoundMode() = ctx->IntegerVal ( "FixAddNaturalBoundMode", -1 );
738 sff->FixMissingSeamMode() = ctx->IntegerVal ( "FixMissingSeamMode", -1 );
739 sff->FixSmallAreaWireMode() = ctx->IntegerVal ( "FixSmallAreaWireMode", -1 );
740 sff->RemoveSmallAreaFaceMode() = ctx->IntegerVal ( "RemoveSmallAreaFaceMode", -1 );
741 sff->FixIntersectingWiresMode() = ctx->IntegerVal ( "FixIntersectingWiresMode", -1 );
742 sff->FixLoopWiresMode() = ctx->IntegerVal ( "FixLoopWiresMode", -1 );
743 sff->FixSplitFaceMode() = ctx->IntegerVal ( "FixSplitFaceMode", -1 );
745 //parameters for ShapeFix_Wire
746 sfw->ModifyTopologyMode() = ctx->BooleanVal ( "ModifyTopologyMode", Standard_False );
747 sfw->ModifyGeometryMode() = ctx->BooleanVal ( "ModifyGeometryMode", Standard_True );
748 sfw->ClosedWireMode() = ctx->BooleanVal ( "ClosedWireMode", Standard_True );
749 sfw->PreferencePCurveMode() = ctx->BooleanVal ( "PreferencePCurveMode", Standard_True );
750 sfw->FixReorderMode() = ctx->IntegerVal ( "FixReorderMode", -1 );
751 sfw->FixSmallMode() = ctx->IntegerVal ( "FixSmallMode", -1 );
752 sfw->FixConnectedMode() = ctx->IntegerVal ( "FixConnectedMode", -1 );
753 sfw->FixEdgeCurvesMode() = ctx->IntegerVal ( "FixEdgeCurvesMode", -1 );
754 sfw->FixDegeneratedMode() = ctx->IntegerVal ( "FixDegeneratedMode", -1 );
755 sfw->FixLackingMode() = ctx->IntegerVal ( "FixLackingMode", -1 );
756 sfw->FixSelfIntersectionMode() = ctx->IntegerVal ( "FixSelfIntersectionMode", -1 );
757 sfw->ModifyRemoveLoopMode() = ctx->IntegerVal ( "RemoveLoopMode", -1);
758 sfw->FixReversed2dMode() = ctx->IntegerVal ( "FixReversed2dMode", -1 );
759 sfw->FixRemovePCurveMode() = ctx->IntegerVal ( "FixRemovePCurveMode", -1 );
760 sfw->FixRemoveCurve3dMode() = ctx->IntegerVal ( "FixRemoveCurve3dMode", -1 );
761 sfw->FixAddPCurveMode() = ctx->IntegerVal ( "FixAddPCurveMode", -1 );
762 sfw->FixAddCurve3dMode() = ctx->IntegerVal ( "FixAddCurve3dMode", -1 );
763 sfw->FixShiftedMode() = ctx->IntegerVal ( "FixShiftedMode", -1 );
764 sfw->FixSeamMode() = ctx->IntegerVal ( "FixSeamMode", -1 );
765 sfw->FixSameParameterMode() = ctx->IntegerVal ( "FixEdgeSameParameterMode", -1 );
766 sfw->FixNotchedEdgesMode() = ctx->IntegerVal ( "FixNotchedEdgesMode", -1 );
767 sfw->FixTailMode() = ctx->IntegerVal("FixTailMode", 0);
768 sfw->SetMaxTailAngle(ctx->RealVal("MaxTailAngle", 0) * (M_PI / 180));
769 sfw->SetMaxTailWidth(ctx->RealVal("MaxTailWidth", -1));
770 sfw->FixSelfIntersectingEdgeMode() = ctx->IntegerVal ( "FixSelfIntersectingEdgeMode", -1 );
771 sfw->FixIntersectingEdgesMode() = ctx->IntegerVal ( "FixIntersectingEdgesMode", -1 );
772 sfw->FixNonAdjacentIntersectingEdgesMode() = ctx->IntegerVal ( "FixNonAdjacentIntersectingEdgesMode", -1 );
773 Message_ProgressScope aPS(theProgress, NULL, 2);
774 if (sfw->FixTailMode() == 1)
776 sfw->FixTailMode() = 0;
777 sfs->Init(ctx->Result());
778 sfs->Perform (aPS.Next());
779 sfw->FixTailMode() = 1;
782 return Standard_False;
785 TopoDS_Shape result = sfs->Shape();
786 if (result != ctx->Result() ||
787 (!msg.IsNull() && !msg->MapShape().IsEmpty()))
789 ctx->RecordModification(sfs->Context(), msg);
790 ctx->SetResult(result);
794 sfs->Init(ctx->Result());
795 sfs->Perform (aPS.Next());
798 return Standard_False;
801 TopoDS_Shape result = sfs->Shape();
802 if (( result != ctx->Result() ) ||
803 ( !msg.IsNull() && !msg->MapShape().IsEmpty()))
805 ctx->RecordModification ( sfs->Context(), msg );
806 ctx->SetResult ( result );
808 return Standard_True;
812 //=======================================================================
813 //function : spltclosededges
815 //=======================================================================
817 static Standard_Boolean spltclosededges (const Handle(ShapeProcess_Context)& context,
818 const Message_ProgressRange&)
820 Handle(ShapeProcess_ShapeContext) ctx =
821 Handle(ShapeProcess_ShapeContext)::DownCast ( context );
822 if ( ctx.IsNull() ) return Standard_False;
824 // activate message mechanism if it is supported by context
825 Handle(ShapeExtend_MsgRegistrator) msg;
826 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
828 Standard_Integer nbSplits = ctx->IntegerVal ( "NbSplitPoints", 1 );
830 ShapeUpgrade_ShapeDivideClosedEdges tool (ctx->Result());
831 tool.SetNbSplitPoints(nbSplits);
832 tool.SetMsgRegistrator( msg );
834 if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) {
836 std::cout<<"Splitting of closed edges failed"<<std::endl;
838 return Standard_False;
841 ctx->RecordModification ( tool.GetContext(), msg );
842 ctx->SetResult ( tool.Result() );
843 return Standard_True;
847 //=======================================================================
848 //function : splitcommonvertex
849 //purpose : Two wires have common vertex - this case is valid in BRep model
850 // and isn't valid in STEP => before writing into STEP it is necessary
851 // to split this vertex (each wire must has one vertex)
852 //=======================================================================
853 static Standard_Boolean splitcommonvertex (const Handle(ShapeProcess_Context)& context,
854 const Message_ProgressRange&)
856 Handle(ShapeProcess_ShapeContext) ctx = Handle(ShapeProcess_ShapeContext)::DownCast ( context );
857 if ( ctx.IsNull() ) return Standard_False;
859 // activate message mechanism if it is supported by context
860 Handle(ShapeExtend_MsgRegistrator) msg;
861 if ( ! ctx->Messages().IsNull() ) msg = new ShapeExtend_MsgRegistrator;
863 Handle(ShapeBuild_ReShape) reshape = new ShapeBuild_ReShape;
864 ShapeFix_SplitCommonVertex SCV;
865 SCV.SetContext(reshape);
866 SCV.Init(ctx->Result());
868 SCV.SetMsgRegistrator( msg );
871 TopoDS_Shape newsh = SCV.Shape();
873 if ( newsh != ctx->Result() ) {
874 ctx->RecordModification ( reshape, msg );
875 ctx->SetResult ( newsh );
878 return Standard_True;
882 //=======================================================================
884 //purpose : Register standard operators
885 //=======================================================================
887 void ShapeProcess_OperLibrary::Init ()
889 static Standard_Boolean done = Standard_False;
891 done = Standard_True;
895 ShapeProcess::RegisterOperator ( "DirectFaces", new ShapeProcess_UOperator ( directfaces ) );
896 ShapeProcess::RegisterOperator ( "SameParameter", new ShapeProcess_UOperator ( sameparam ) );
897 ShapeProcess::RegisterOperator ( "SetTolerance", new ShapeProcess_UOperator ( settol ) );
898 ShapeProcess::RegisterOperator ( "SplitAngle", new ShapeProcess_UOperator ( splitangle ) );
899 ShapeProcess::RegisterOperator ( "BSplineRestriction", new ShapeProcess_UOperator ( bsplinerestriction ) );
900 ShapeProcess::RegisterOperator ( "ElementaryToRevolution",new ShapeProcess_UOperator ( torevol ) );
901 ShapeProcess::RegisterOperator ( "SweptToElementary", new ShapeProcess_UOperator ( swepttoelem ) );
902 ShapeProcess::RegisterOperator ( "SurfaceToBSpline", new ShapeProcess_UOperator ( converttobspline ) );
903 ShapeProcess::RegisterOperator ( "ToBezier", new ShapeProcess_UOperator ( shapetobezier ) );
904 ShapeProcess::RegisterOperator ( "SplitContinuity", new ShapeProcess_UOperator ( splitcontinuity ) );
905 ShapeProcess::RegisterOperator ( "SplitClosedFaces", new ShapeProcess_UOperator ( splitclosedfaces ) );
906 ShapeProcess::RegisterOperator ( "FixWireGaps", new ShapeProcess_UOperator ( fixwgaps ) );
907 ShapeProcess::RegisterOperator ( "FixFaceSize", new ShapeProcess_UOperator ( fixfacesize ) );
908 ShapeProcess::RegisterOperator ( "DropSmallSolids", new ShapeProcess_UOperator ( dropsmallsolids ) );
909 ShapeProcess::RegisterOperator ( "DropSmallEdges", new ShapeProcess_UOperator ( mergesmalledges ) );
910 ShapeProcess::RegisterOperator ( "FixShape", new ShapeProcess_UOperator ( fixshape ) );
911 ShapeProcess::RegisterOperator ( "SplitClosedEdges", new ShapeProcess_UOperator ( spltclosededges ) );
912 ShapeProcess::RegisterOperator ( "SplitCommonVertex", new ShapeProcess_UOperator ( splitcommonvertex ) );