]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_ShapeDriver.cxx
Salome HOME
0022354: EDF GEOM: Create edge by getting iso-line of surface
[modules/geom.git] / src / GEOMImpl / GEOMImpl_ShapeDriver.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include <GEOMImpl_ShapeDriver.hxx>
24
25 #include <GEOMImpl_IIsoline.hxx>
26 #include <GEOMImpl_IShapes.hxx>
27 #include <GEOMImpl_IVector.hxx>
28 #include <GEOMImpl_Types.hxx>
29 #include <GEOMImpl_Block6Explorer.hxx>
30
31 #include <GEOM_Function.hxx>
32 #include <GEOMUtils_Hatcher.hxx>
33
34 // OCCT Includes
35 #include <ShapeFix_Wire.hxx>
36 #include <ShapeFix_Edge.hxx>
37 #include <ShapeFix_Shape.hxx>
38
39 #include <BRep_Builder.hxx>
40 #include <BRep_Tool.hxx>
41 #include <BRepAdaptor_Curve.hxx>
42 #include <BRepAlgo_FaceRestrictor.hxx>
43 #include <BRepBuilderAPI_Copy.hxx>
44 #include <BRepBuilderAPI_Sewing.hxx>
45 #include <BRepBuilderAPI_MakeWire.hxx>
46 #include <BRepBuilderAPI_MakeEdge.hxx>
47 #include <BRepCheck.hxx>
48 #include <BRepCheck_Analyzer.hxx>
49 #include <BRepCheck_Shell.hxx>
50 #include <BRepClass3d_SolidClassifier.hxx>
51 #include <BRepLib.hxx>
52 #include <BRepLib_MakeEdge.hxx>
53 #include <BRepTools_WireExplorer.hxx>
54
55 #include <ShapeAnalysis.hxx>
56 #include <ShapeAnalysis_FreeBounds.hxx>
57
58 #include <TopAbs.hxx>
59 #include <TopExp.hxx>
60 #include <TopExp_Explorer.hxx>
61 #include <TopoDS.hxx>
62 #include <TopoDS_Shape.hxx>
63 #include <TopoDS_Edge.hxx>
64 #include <TopoDS_Wire.hxx>
65 #include <TopoDS_Shell.hxx>
66 #include <TopoDS_Solid.hxx>
67 #include <TopoDS_Compound.hxx>
68 #include <TopoDS_Iterator.hxx>
69
70 #include <TopTools_MapOfShape.hxx>
71 #include <TopTools_HSequenceOfShape.hxx>
72
73 #include <ElCLib.hxx>
74
75 #include <GCPnts_AbscissaPoint.hxx>
76
77 #include <Geom_TrimmedCurve.hxx>
78 #include <Geom_Surface.hxx>
79 #include <GeomAbs_CurveType.hxx>
80 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
81 #include <GeomConvert.hxx>
82 #include <GeomLProp.hxx>
83
84 #include <TColStd_SequenceOfReal.hxx>
85 #include <TColStd_HSequenceOfTransient.hxx>
86 #include <TColStd_Array1OfReal.hxx>
87 #include <TColGeom_SequenceOfCurve.hxx>
88 #include <TColGeom_Array1OfBSplineCurve.hxx>
89 #include <TColGeom_HArray1OfBSplineCurve.hxx>
90
91 #include <Precision.hxx>
92
93 #include <Standard_NullObject.hxx>
94 #include <Standard_TypeMismatch.hxx>
95 #include <Standard_ConstructionError.hxx>
96
97 //modified by NIZNHY-PKV Wed Dec 28 13:48:20 2011f
98 //static
99 //  void KeepEdgesOrder(const Handle(TopTools_HSequenceOfShape)& aEdges,
100 //                    const Handle(TopTools_HSequenceOfShape)& aWires);
101 //modified by NIZNHY-PKV Wed Dec 28 13:48:23 2011t
102
103 //=======================================================================
104 //function : GetID
105 //purpose  :
106 //=======================================================================
107 const Standard_GUID& GEOMImpl_ShapeDriver::GetID()
108 {
109   static Standard_GUID aShapeDriver("FF1BBB54-5D14-4df2-980B-3A668264EA16");
110   return aShapeDriver;
111 }
112
113
114 //=======================================================================
115 //function : GEOMImpl_ShapeDriver
116 //purpose  :
117 //=======================================================================
118 GEOMImpl_ShapeDriver::GEOMImpl_ShapeDriver()
119 {
120 }
121
122 //=======================================================================
123 //function : Execute
124 //purpose  :
125 //=======================================================================
126 Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
127 {
128   if (Label().IsNull()) return 0;
129   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
130
131   GEOMImpl_IShapes aCI (aFunction);
132   Standard_Integer aType = aFunction->GetType();
133
134   TopoDS_Shape aShape;
135   TCollection_AsciiString aWarning;
136
137   BRep_Builder B;
138
139   if (aType == WIRE_EDGES) {
140     Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
141
142     Standard_Real aTolerance = aCI.GetTolerance();
143     if (aTolerance < Precision::Confusion())
144       aTolerance = Precision::Confusion();
145
146     aShape = MakeWireFromEdges(aShapes, aTolerance);
147   }
148   else if (aType == FACE_WIRE) {
149     Handle(GEOM_Function) aRefBase = aCI.GetBase();
150     TopoDS_Shape aShapeBase = aRefBase->GetValue();
151     if (aShapeBase.IsNull()) Standard_NullObject::Raise("Argument Shape is null");
152     TopoDS_Wire W;
153     if (aShapeBase.ShapeType() == TopAbs_WIRE) {
154       W = TopoDS::Wire(aShapeBase);
155       // check the wire is closed
156       TopoDS_Vertex aV1, aV2;
157       TopExp::Vertices(W, aV1, aV2);
158       if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) )
159         aShapeBase.Closed(true);
160       else
161         Standard_NullObject::Raise
162           ("Shape for face construction is not closed");
163     }
164     else if (aShapeBase.ShapeType() == TopAbs_EDGE && aShapeBase.Closed()) {
165       BRepBuilderAPI_MakeWire MW;
166       MW.Add(TopoDS::Edge(aShapeBase));
167       if (!MW.IsDone()) {
168         Standard_ConstructionError::Raise("Wire construction failed");
169       }
170       W = MW;
171     }
172     else {
173       Standard_NullObject::Raise
174         ("Shape for face construction is neither a wire nor a closed edge");
175     }
176     aWarning = GEOMImpl_Block6Explorer::MakeFace(W, aCI.GetIsPlanar(), aShape);
177     if (aShape.IsNull()) {
178       Standard_ConstructionError::Raise("Face construction failed");
179     }
180   }
181   else if (aType == FACE_WIRES) {
182     // Try to build a face from a set of wires and edges
183     int ind;
184
185     Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
186     int nbshapes = aShapes->Length();
187     if (nbshapes < 1) {
188       Standard_ConstructionError::Raise("No wires or edges given");
189     }
190
191     // 1. Extract all edges from the given arguments
192     TopTools_MapOfShape aMapEdges;
193     Handle(TopTools_HSequenceOfShape) aSeqEdgesIn = new TopTools_HSequenceOfShape;
194
195     for (ind = 1; ind <= nbshapes; ind++) {
196       Handle(GEOM_Function) aRefSh_i = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
197       TopoDS_Shape aSh_i = aRefSh_i->GetValue();
198
199       TopExp_Explorer anExpE_i (aSh_i, TopAbs_EDGE);
200       for (; anExpE_i.More(); anExpE_i.Next()) {
201         if (aMapEdges.Add(anExpE_i.Current())) {
202           aSeqEdgesIn->Append(anExpE_i.Current());
203         }
204       }
205     }
206
207     // 2. Connect edges to wires of maximum length
208     Handle(TopTools_HSequenceOfShape) aSeqWiresOut;
209     ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdgesIn, Precision::Confusion(),
210                                                   /*shared*/Standard_False, aSeqWiresOut);
211     //modified by NIZNHY-PKV Wed Dec 28 13:46:55 2011f
212     //KeepEdgesOrder(aSeqEdgesIn, aSeqWiresOut);
213     //modified by NIZNHY-PKV Wed Dec 28 13:46:59 2011t
214
215     // 3. Separate closed wires
216     Handle(TopTools_HSequenceOfShape) aSeqClosedWires = new TopTools_HSequenceOfShape;
217     Handle(TopTools_HSequenceOfShape) aSeqOpenWires = new TopTools_HSequenceOfShape;
218     for (ind = 1; ind <= aSeqWiresOut->Length(); ind++) {
219       if (aSeqWiresOut->Value(ind).Closed())
220         aSeqClosedWires->Append(aSeqWiresOut->Value(ind));
221       else
222         aSeqOpenWires->Append(aSeqWiresOut->Value(ind));
223     }
224
225     if (aSeqClosedWires->Length() < 1) {
226       Standard_ConstructionError::Raise
227         ("There is no closed contour can be built from the given arguments");
228     }
229
230     // 4. Build a face / list of faces from all the obtained closed wires
231
232     // 4.a. Basic face
233     TopoDS_Shape aFFace;
234     TopoDS_Wire aW1 = TopoDS::Wire(aSeqClosedWires->Value(1));
235     aWarning = GEOMImpl_Block6Explorer::MakeFace(aW1, aCI.GetIsPlanar(), aFFace);
236     if (aFFace.IsNull()) {
237       Standard_ConstructionError::Raise("Face construction failed");
238     }
239
240     // 4.b. Add other wires
241     if (aSeqClosedWires->Length() == 1) {
242       aShape = aFFace;
243     }
244     else {
245       TopoDS_Compound C;
246       BRep_Builder aBuilder;
247       aBuilder.MakeCompound(C);
248       BRepAlgo_FaceRestrictor FR;
249
250       TopAbs_Orientation OriF = aFFace.Orientation();
251       TopoDS_Shape aLocalS = aFFace.Oriented(TopAbs_FORWARD);
252       FR.Init(TopoDS::Face(aLocalS), Standard_False, Standard_True);
253
254       for (ind = 1; ind <= aSeqClosedWires->Length(); ind++) {
255         TopoDS_Wire aW = TopoDS::Wire(aSeqClosedWires->Value(ind));
256         FR.Add(aW);
257       }
258
259       FR.Perform();
260
261       if (FR.IsDone()) {
262         int k = 0;
263         TopoDS_Shape aFace;
264         for (; FR.More(); FR.Next()) {
265           aFace = FR.Current().Oriented(OriF);
266           aBuilder.Add(C, aFace);
267           k++;
268         }
269         if (k == 1) {
270           aShape = aFace;
271         } else {
272           aShape = C;
273         }
274       }
275     }
276
277     // 5. Add all open wires to the result
278     if (aSeqOpenWires->Length() > 0) {
279       //Standard_ConstructionError::Raise("There are some open wires");
280       TopoDS_Compound C;
281       BRep_Builder aBuilder;
282       if (aSeqClosedWires->Length() == 1) {
283         aBuilder.MakeCompound(C);
284         aBuilder.Add(C, aShape);
285       }
286       else {
287         C = TopoDS::Compound(aShape);
288       }
289
290       for (ind = 1; ind <= aSeqOpenWires->Length(); ind++) {
291         aBuilder.Add(C, aSeqOpenWires->Value(ind));
292       }
293
294       aShape = C;
295     }
296   }
297   else if (aType == SHELL_FACES) {
298     Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
299     unsigned int ind, nbshapes = aShapes->Length();
300
301     // add faces
302     BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0);
303     for (ind = 1; ind <= nbshapes; ind++) {
304       Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
305       TopoDS_Shape aShape_i = aRefShape->GetValue();
306       if (aShape_i.IsNull()) {
307         Standard_NullObject::Raise("Face for shell construction is null");
308       }
309       aSewing.Add(aShape_i);
310     }
311
312     aSewing.Perform();
313
314     TopoDS_Shape sh = aSewing.SewedShape();
315
316     if (sh.ShapeType()==TopAbs_FACE && nbshapes==1) {
317       // case for creation of shell from one face - PAL12722 (skl 26.06.2006)
318       TopoDS_Shell ss;
319       B.MakeShell(ss);
320       B.Add(ss,sh);
321       aShape = ss;
322     }
323     else {
324       //TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL);
325       TopExp_Explorer exp (sh, TopAbs_SHELL);
326       Standard_Integer ish = 0;
327       for (; exp.More(); exp.Next()) {
328         aShape = exp.Current();
329         ish++;
330       }
331
332       if (ish != 1) {
333         // try the case of one face (Mantis issue 0021809)
334         TopExp_Explorer expF (sh, TopAbs_FACE);
335         Standard_Integer ifa = 0;
336         for (; expF.More(); expF.Next()) {
337           aShape = expF.Current();
338           ifa++;
339         }
340
341         if (ifa == 1) {
342           TopoDS_Shell ss;
343           B.MakeShell(ss);
344           B.Add(ss,aShape);
345           aShape = ss;
346         }
347         else {
348           aShape = aSewing.SewedShape();
349         }
350       }
351     }
352
353   }
354   else if (aType == SOLID_SHELL) {
355     Handle(GEOM_Function) aRefShell = aCI.GetBase();
356     TopoDS_Shape aShapeShell = aRefShell->GetValue();
357     if (!aShapeShell.IsNull() && aShapeShell.ShapeType() == TopAbs_COMPOUND) {
358       TopoDS_Iterator It (aShapeShell, Standard_True, Standard_True);
359       if (It.More()) aShapeShell = It.Value();
360     }
361     if (aShapeShell.IsNull() || aShapeShell.ShapeType() != TopAbs_SHELL) {
362       Standard_NullObject::Raise("Shape for solid construction is null or not a shell");
363     }
364
365     BRepCheck_Shell chkShell(TopoDS::Shell(aShapeShell));
366     if (chkShell.Closed() == BRepCheck_NotClosed) return 0;
367
368     TopoDS_Solid Sol;
369     B.MakeSolid(Sol);
370     B.Add(Sol, aShapeShell);
371     BRepClass3d_SolidClassifier SC (Sol);
372     SC.PerformInfinitePoint(Precision::Confusion());
373     if (SC.State() == TopAbs_IN) {
374       B.MakeSolid(Sol);
375       B.Add(Sol, aShapeShell.Reversed());
376     }
377
378     aShape = Sol;
379
380   }
381   else if (aType == SOLID_SHELLS) {
382     Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
383     unsigned int ind, nbshapes = aShapes->Length();
384     Standard_Integer ish = 0;
385     TopoDS_Solid Sol;
386     B.MakeSolid(Sol);
387
388     // add shapes
389     for (ind = 1; ind <= nbshapes; ind++) {
390       Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
391       TopoDS_Shape aShapeShell = aRefShape->GetValue();
392       if (aShapeShell.IsNull()) {
393         Standard_NullObject::Raise("Shell for solid construction is null");
394       }
395       if (aShapeShell.ShapeType() == TopAbs_COMPOUND) {
396         TopoDS_Iterator It (aShapeShell, Standard_True, Standard_True);
397         if (It.More()) aShapeShell = It.Value();
398       }
399       if (aShapeShell.ShapeType() == TopAbs_SHELL) {
400         B.Add(Sol, aShapeShell);
401         ish++;
402       }
403     }
404     if (ish == 0) return 0;
405     BRepClass3d_SolidClassifier SC (Sol);
406     SC.PerformInfinitePoint(Precision::Confusion());
407     if (SC.State() == TopAbs_IN)
408       aShape = Sol.Reversed();
409     else
410       aShape = Sol;
411   }
412   else if (aType == COMPOUND_SHAPES) {
413     Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
414     unsigned int ind, nbshapes = aShapes->Length();
415
416     // add shapes
417     TopoDS_Compound C;
418     B.MakeCompound(C);
419     for (ind = 1; ind <= nbshapes; ind++) {
420       Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
421       TopoDS_Shape aShape_i = aRefShape->GetValue();
422       if (aShape_i.IsNull()) {
423         Standard_NullObject::Raise("Shape for compound construction is null");
424       }
425       B.Add(C, aShape_i);
426     }
427
428     aShape = C;
429
430   }
431   /*
432   else if (aType == REVERSE_ORIENTATION) {
433     Handle(GEOM_Function) aRefShape = aCI.GetBase();
434     TopoDS_Shape aShape_i = aRefShape->GetValue();
435     if (aShape_i.IsNull()) {
436        Standard_NullObject::Raise("Shape for reverse is null");
437     }
438
439     BRepBuilderAPI_Copy Copy(aShape_i);
440     if( Copy.IsDone() ) {
441       TopoDS_Shape tds = Copy.Shape();
442       if( tds.IsNull() ) {
443         Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape");
444       }
445
446       if( tds.Orientation() == TopAbs_FORWARD)
447         tds.Orientation(TopAbs_REVERSED);
448       else
449         tds.Orientation(TopAbs_FORWARD);
450
451       aShape = tds;
452     }
453   }
454   */
455   else if (aType == EDGE_WIRE) {
456     Handle(GEOM_Function) aRefBase = aCI.GetBase();
457     TopoDS_Shape aWire = aRefBase->GetValue();
458     Standard_Real LinTol = aCI.GetTolerance();
459     Standard_Real AngTol = aCI.GetAngularTolerance();
460     if (aWire.IsNull()) Standard_NullObject::Raise("Argument Wire is null");
461
462     aShape = MakeEdgeFromWire(aWire, LinTol, AngTol);
463   }
464   else if (aType == EDGE_CURVE_LENGTH) {
465     GEOMImpl_IVector aVI (aFunction);
466
467     // RefCurve
468     Handle(GEOM_Function) aRefCurve = aVI.GetPoint1();
469     if (aRefCurve.IsNull()) Standard_NullObject::Raise("Argument Curve is null");
470     TopoDS_Shape aRefShape1 = aRefCurve->GetValue();
471     if (aRefShape1.ShapeType() != TopAbs_EDGE) {
472       Standard_TypeMismatch::Raise
473         ("Edge On Curve creation aborted : curve shape is not an edge");
474     }
475     TopoDS_Edge aRefEdge = TopoDS::Edge(aRefShape1);
476     TopoDS_Vertex V1, V2;
477     TopExp::Vertices(aRefEdge, V1, V2, Standard_True);
478
479     // RefPoint
480     TopoDS_Vertex aRefVertex;
481     Handle(GEOM_Function) aRefPoint = aVI.GetPoint2();
482     if (aRefPoint.IsNull()) {
483       aRefVertex = V1;
484     }
485     else {
486       TopoDS_Shape aRefShape2 = aRefPoint->GetValue();
487       if (aRefShape2.ShapeType() != TopAbs_VERTEX) {
488         Standard_TypeMismatch::Raise
489           ("Edge On Curve creation aborted : start point shape is not a vertex");
490       }
491       aRefVertex = TopoDS::Vertex(aRefShape2);
492     }
493     gp_Pnt aRefPnt = BRep_Tool::Pnt(aRefVertex);
494
495     // Length
496     Standard_Real aLength = aVI.GetParameter();
497     //Standard_Real aCurveLength = IntTools::Length(aRefEdge);
498     //if (aLength > aCurveLength) {
499     //  Standard_ConstructionError::Raise
500     //    ("Edge On Curve creation aborted : given length is greater than edges length");
501     //}
502     if (fabs(aLength) < Precision::Confusion()) {
503       Standard_ConstructionError::Raise
504         ("Edge On Curve creation aborted : given length is smaller than Precision::Confusion()");
505     }
506
507     // Check orientation
508     Standard_Real UFirst, ULast;
509     Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(aRefEdge, UFirst, ULast);
510     Handle(Geom_Curve) ReOrientedCurve = EdgeCurve;
511
512     Standard_Real dU = ULast - UFirst;
513     Standard_Real par1 = UFirst + 0.1 * dU;
514     Standard_Real par2 = ULast  - 0.1 * dU;
515
516     gp_Pnt P1 = EdgeCurve->Value(par1);
517     gp_Pnt P2 = EdgeCurve->Value(par2);
518
519     if (aRefPnt.SquareDistance(P2) < aRefPnt.SquareDistance(P1)) {
520       ReOrientedCurve = EdgeCurve->Reversed();
521       UFirst = EdgeCurve->ReversedParameter(ULast);
522     }
523
524     // Get the point by length
525     GeomAdaptor_Curve AdapCurve = GeomAdaptor_Curve(ReOrientedCurve);
526     GCPnts_AbscissaPoint anAbsPnt (AdapCurve, aLength, UFirst);
527     Standard_Real aParam = anAbsPnt.Parameter();
528
529     if (AdapCurve.IsClosed() && aLength < 0.0) {
530       Standard_Real aTmp = aParam;
531       aParam = UFirst;
532       UFirst = aTmp;
533     }
534
535     BRepBuilderAPI_MakeEdge aME (ReOrientedCurve, UFirst, aParam);
536     if (aME.IsDone())
537       aShape = aME.Shape();
538   } else if (aType == SHAPE_ISOLINE) {
539     GEOMImpl_IIsoline     aII (aFunction);
540     Handle(GEOM_Function) aRefFace = aII.GetFace();
541     TopoDS_Shape          aShapeFace = aRefFace->GetValue();
542
543     if (aShapeFace.ShapeType() == TopAbs_FACE) {
544       TopoDS_Face   aFace  = TopoDS::Face(aShapeFace);
545       bool          isUIso = aII.GetIsUIso();
546       Standard_Real aParam = aII.GetParameter();
547       Standard_Real U1,U2,V1,V2;
548
549       // Construct a real geometric parameter.
550       aFace.Orientation(TopAbs_FORWARD);
551       ShapeAnalysis::GetFaceUVBounds(aFace,U1,U2,V1,V2);
552
553       if (isUIso) {
554         aParam = U1 + (U2 - U1)*aParam;
555       } else {
556         aParam = V1 + (V2 - V1)*aParam;
557       }
558
559       aShape = MakeIsoline(aFace, isUIso, aParam);
560     } else {
561       Standard_NullObject::Raise
562         ("Shape for isoline construction is not a face");
563     }
564   }
565   else {
566   }
567
568   if (aShape.IsNull()) return 0;
569
570   // Check shape validity
571   BRepCheck_Analyzer ana (aShape, false);
572   if (!ana.IsValid()) {
573     //Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
574     // For Mantis issue 0021772: EDF 2336 GEOM: Non valid face created from two circles
575     Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape (aShape);
576     aSfs->Perform();
577     aShape = aSfs->Shape();
578   }
579
580   aFunction->SetValue(aShape);
581
582   log.SetTouched(Label());
583
584   if (!aWarning.IsEmpty())
585     Standard_Failure::Raise(aWarning.ToCString());
586
587   return 1;
588 }
589
590 TopoDS_Wire GEOMImpl_ShapeDriver::MakeWireFromEdges(const Handle(TColStd_HSequenceOfTransient)& theEdgesFuncs,
591                                                     const Standard_Real theTolerance)
592 {
593   BRep_Builder B;
594
595   TopoDS_Wire aWire;
596   B.MakeWire(aWire);
597
598   // add edges
599   for (unsigned int ind = 1; ind <= theEdgesFuncs->Length(); ind++) {
600     Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(theEdgesFuncs->Value(ind));
601     TopoDS_Shape aShape_i = aRefShape->GetValue();
602     if (aShape_i.IsNull()) {
603       Standard_NullObject::Raise("Shape for wire construction is null");
604     }
605     if (aShape_i.ShapeType() == TopAbs_EDGE || aShape_i.ShapeType() == TopAbs_WIRE) {
606       TopExp_Explorer exp (aShape_i, TopAbs_EDGE);
607       for (; exp.More(); exp.Next())
608         B.Add(aWire, TopoDS::Edge(exp.Current()));
609     } else {
610       Standard_TypeMismatch::Raise
611         ("Shape for wire construction is neither an edge nor a wire");
612     }
613   }
614
615   // fix edges order
616   Handle(ShapeFix_Wire) aFW = new ShapeFix_Wire;
617   aFW->Load(aWire);
618   aFW->FixReorder();
619
620   if (aFW->StatusReorder(ShapeExtend_FAIL1)) {
621     Standard_ConstructionError::Raise("Wire construction failed: several loops detected");
622   }
623   else if (aFW->StatusReorder(ShapeExtend_FAIL)) {
624     Standard_ConstructionError::Raise("Wire construction failed");
625   }
626   else {
627   }
628
629   // IMP 0019766: Building a Wire from unconnected edges by introducing a tolerance
630   aFW->ClosedWireMode() = Standard_False;
631   aFW->FixConnected(theTolerance);
632   if (aFW->StatusConnected(ShapeExtend_FAIL)) {
633     Standard_ConstructionError::Raise("Wire construction failed: cannot build connected wire");
634   }
635   // IMP 0019766
636   if (aFW->StatusConnected(ShapeExtend_DONE3)) {
637     // Confused with <prec> but not Analyzer.Precision(), set the same
638     aFW->FixGapsByRangesMode() = Standard_True;
639     if (aFW->FixGaps3d()) {
640       Handle(ShapeExtend_WireData) sbwd = aFW->WireData();
641       Handle(ShapeFix_Edge) aFe = new ShapeFix_Edge;
642       for (Standard_Integer iedge = 1; iedge <= sbwd->NbEdges(); iedge++) {
643         TopoDS_Edge aEdge = TopoDS::Edge(sbwd->Edge(iedge));
644         aFe->FixVertexTolerance(aEdge);
645         aFe->FixSameParameter(aEdge);
646       }
647     }
648     else if (aFW->StatusGaps3d(ShapeExtend_FAIL)) {
649       Standard_ConstructionError::Raise("Wire construction failed: cannot fix 3d gaps");
650     }
651   }
652   aWire = aFW->WireAPIMake();
653
654   return aWire;
655 }
656
657 TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire,
658                                                    const Standard_Real LinTol,
659                                                    const Standard_Real AngTol)
660 {
661     TopoDS_Edge ResEdge;
662
663     BRepLib::BuildCurves3d(aWire);
664     Handle(ShapeFix_Shape) Fixer = new ShapeFix_Shape(aWire);
665     Fixer->SetPrecision(LinTol);
666     Fixer->SetMaxTolerance(LinTol);
667     Fixer->Perform();
668     TopoDS_Wire theWire = TopoDS::Wire(Fixer->Shape());
669
670     TColGeom_SequenceOfCurve CurveSeq;
671     TopTools_SequenceOfShape LocSeq;
672     TColStd_SequenceOfReal FparSeq;
673     TColStd_SequenceOfReal LparSeq;
674     TColStd_SequenceOfReal TolSeq;
675     GeomAbs_CurveType CurType;
676     TopoDS_Vertex FirstVertex, LastVertex;
677     Standard_Boolean FinalReverse = Standard_False;
678
679     BRepTools_WireExplorer wexp(theWire) ;
680     for (; wexp.More(); wexp.Next())
681     {
682       TopoDS_Edge anEdge = wexp.Current();
683       Standard_Real fpar, lpar;
684       TopLoc_Location aLoc;
685       Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aLoc, fpar, lpar);
686       if (aCurve.IsNull())
687         continue;
688
689       BRepAdaptor_Curve BAcurve(anEdge);
690       GeomAbs_CurveType aType = BAcurve.GetType();
691
692       Handle(Geom_Curve) aBasisCurve = BAcurve.Curve().Curve();
693
694       if (aBasisCurve->IsPeriodic())
695         ElCLib::AdjustPeriodic(aBasisCurve->FirstParameter(), aBasisCurve->LastParameter(),
696                                Precision::PConfusion(), fpar, lpar);
697
698       if (CurveSeq.IsEmpty())
699       {
700         CurveSeq.Append(aCurve);
701         TopoDS_Shape aLocShape;
702         aLocShape.Location(aLoc);
703         aLocShape.Orientation(wexp.Orientation());
704         LocSeq.Append(aLocShape);
705         FparSeq.Append(fpar);
706         LparSeq.Append(lpar);
707         CurType = aType;
708         FirstVertex = wexp.CurrentVertex();
709         if (anEdge.Orientation() == TopAbs_REVERSED)
710           FinalReverse = Standard_True;
711       }
712       else
713       {
714         Standard_Boolean Done = Standard_False;
715         Standard_Real NewFpar, NewLpar;
716         GeomAdaptor_Curve GAprevcurve(CurveSeq.Last());
717         TopoDS_Vertex CurVertex = wexp.CurrentVertex();
718         TopoDS_Vertex CurFirstVer = TopExp::FirstVertex(anEdge);
719         TopAbs_Orientation ConnectByOrigin = (CurVertex.IsSame(CurFirstVer))? TopAbs_FORWARD : TopAbs_REVERSED;
720         if (aCurve == CurveSeq.Last())
721         {
722           NewFpar = fpar;
723           NewLpar = lpar;
724           if (aBasisCurve->IsPeriodic())
725           {
726             if (NewLpar < NewFpar)
727               NewLpar += aBasisCurve->Period();
728             if (ConnectByOrigin == TopAbs_FORWARD)
729               ElCLib::AdjustPeriodic(FparSeq.Last(),
730                                      FparSeq.Last() + aBasisCurve->Period(),
731                                      Precision::PConfusion(), NewFpar, NewLpar);
732             else
733               ElCLib::AdjustPeriodic(FparSeq.Last() - aBasisCurve->Period(),
734                                      FparSeq.Last(),
735                                      Precision::PConfusion(), NewFpar, NewLpar);
736           }
737           Done = Standard_True;
738         }
739         else if (aType == CurType &&
740                  aType != GeomAbs_BezierCurve &&
741                  aType != GeomAbs_BSplineCurve &&
742                  aType != GeomAbs_OtherCurve)
743         {
744           switch (aType)
745           {
746           case GeomAbs_Line:
747             {
748               gp_Lin aLine    = BAcurve.Line();
749               gp_Lin PrevLine = GAprevcurve.Line();
750               if (aLine.Contains(PrevLine.Location(), LinTol) &&
751                   aLine.Direction().IsParallel(PrevLine.Direction(), AngTol))
752               {
753                 gp_Pnt P1 = ElCLib::Value(fpar, aLine);
754                 gp_Pnt P2 = ElCLib::Value(lpar, aLine);
755                 NewFpar = ElCLib::Parameter(PrevLine, P1);
756                 NewLpar = ElCLib::Parameter(PrevLine, P2);
757                 if (NewLpar < NewFpar)
758                 {
759                   Standard_Real MemNewFpar = NewFpar;
760                   NewFpar = NewLpar;
761                   NewLpar = MemNewFpar;
762                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
763                 }
764                 Done = Standard_True;
765               }
766               break;
767             }
768           case GeomAbs_Circle:
769             {
770               gp_Circ aCircle    = BAcurve.Circle();
771               gp_Circ PrevCircle = GAprevcurve.Circle();
772               if (aCircle.Location().Distance(PrevCircle.Location()) <= LinTol &&
773                   Abs(aCircle.Radius() - PrevCircle.Radius()) <= LinTol &&
774                   aCircle.Axis().IsParallel(PrevCircle.Axis(), AngTol))
775               {
776                 if (aCircle.Axis().Direction() * PrevCircle.Axis().Direction() < 0.)
777                 {
778                   Standard_Real memfpar = fpar;
779                   fpar = lpar;
780                   lpar = memfpar;
781                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
782                 }
783                 gp_Pnt P1 = ElCLib::Value(fpar, aCircle);
784                 gp_Pnt P2 = ElCLib::Value(lpar, aCircle);
785                 NewFpar = ElCLib::Parameter(PrevCircle, P1);
786                 NewLpar = ElCLib::Parameter(PrevCircle, P2);
787                 if (NewLpar < NewFpar)
788                   NewLpar += 2.*M_PI;
789                 //Standard_Real MemNewFpar = NewFpar, MemNewLpar =  NewLpar;
790                 if (ConnectByOrigin == TopAbs_FORWARD)
791                   ElCLib::AdjustPeriodic(FparSeq.Last(),
792                                          FparSeq.Last() + 2.*M_PI,
793                                          Precision::PConfusion(), NewFpar, NewLpar);
794                 else
795                   ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*M_PI,
796                                          FparSeq.Last(),
797                                          Precision::PConfusion(), NewFpar, NewLpar);
798                 Done = Standard_True;
799               }
800               break;
801             }
802           case GeomAbs_Ellipse:
803             {
804               gp_Elips anEllipse   = BAcurve.Ellipse();
805               gp_Elips PrevEllipse = GAprevcurve.Ellipse();
806               if (anEllipse.Focus1().Distance(PrevEllipse.Focus1()) <= LinTol &&
807                   anEllipse.Focus2().Distance(PrevEllipse.Focus2()) <= LinTol &&
808                   Abs(anEllipse.MajorRadius() - PrevEllipse.MajorRadius()) <= LinTol &&
809                   Abs(anEllipse.MinorRadius() - PrevEllipse.MinorRadius()) <= LinTol &&
810                   anEllipse.Axis().IsParallel(PrevEllipse.Axis(), AngTol))
811               {
812                 if (anEllipse.Axis().Direction() * PrevEllipse.Axis().Direction() < 0.)
813                 {
814                   Standard_Real memfpar = fpar;
815                   fpar = lpar;
816                   lpar = memfpar;
817                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
818                 }
819                 gp_Pnt P1 = ElCLib::Value(fpar, anEllipse);
820                 gp_Pnt P2 = ElCLib::Value(lpar, anEllipse);
821                 NewFpar = ElCLib::Parameter(PrevEllipse, P1);
822                 NewLpar = ElCLib::Parameter(PrevEllipse, P2);
823                 if (NewLpar < NewFpar)
824                   NewLpar += 2.*M_PI;
825                 if (ConnectByOrigin == TopAbs_FORWARD)
826                   ElCLib::AdjustPeriodic(FparSeq.Last(),
827                                          FparSeq.Last() + 2.*M_PI,
828                                          Precision::PConfusion(), NewFpar, NewLpar);
829                 else
830                   ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*M_PI,
831                                          FparSeq.Last(),
832                                          Precision::PConfusion(), NewFpar, NewLpar);
833                 Done = Standard_True;
834               }
835               break;
836             }
837           case GeomAbs_Hyperbola:
838             {
839               gp_Hypr aHypr    = BAcurve.Hyperbola();
840               gp_Hypr PrevHypr = GAprevcurve.Hyperbola();
841               if (aHypr.Focus1().Distance(PrevHypr.Focus1()) <= LinTol &&
842                   aHypr.Focus2().Distance(PrevHypr.Focus2()) <= LinTol &&
843                   Abs(aHypr.MajorRadius() - PrevHypr.MajorRadius()) <= LinTol &&
844                   Abs(aHypr.MinorRadius() - PrevHypr.MinorRadius()) <= LinTol &&
845                   aHypr.Axis().IsParallel(PrevHypr.Axis(), AngTol))
846               {
847                 gp_Pnt P1 = ElCLib::Value(fpar, aHypr);
848                 gp_Pnt P2 = ElCLib::Value(lpar, aHypr);
849                 NewFpar = ElCLib::Parameter(PrevHypr, P1);
850                 NewLpar = ElCLib::Parameter(PrevHypr, P2);
851                 if (NewLpar < NewFpar)
852                 {
853                   Standard_Real MemNewFpar = NewFpar;
854                   NewFpar = NewLpar;
855                   NewLpar = MemNewFpar;
856                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
857                 }
858                 Done = Standard_True;
859               }
860               break;
861             }
862           case GeomAbs_Parabola:
863             {
864               gp_Parab aParab    = BAcurve.Parabola();
865               gp_Parab PrevParab = GAprevcurve.Parabola();
866               if (aParab.Location().Distance(PrevParab.Location()) <= LinTol &&
867                   aParab.Focus().Distance(PrevParab.Focus()) <= LinTol &&
868                   Abs(aParab.Focal() - PrevParab.Focal()) <= LinTol &&
869                   aParab.Axis().IsParallel(PrevParab.Axis(), AngTol))
870               {
871                 gp_Pnt P1 = ElCLib::Value(fpar, aParab);
872                 gp_Pnt P2 = ElCLib::Value(lpar, aParab);
873                 NewFpar = ElCLib::Parameter(PrevParab, P1);
874                 NewLpar = ElCLib::Parameter(PrevParab, P2);
875                 if (NewLpar < NewFpar)
876                 {
877                   Standard_Real MemNewFpar = NewFpar;
878                   NewFpar = NewLpar;
879                   NewLpar = MemNewFpar;
880                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
881                 }
882                 Done = Standard_True;
883               }
884               break;
885             }
886           } //end of switch (aType)
887         } // end of else if (aType == CurType && ...
888         if (Done)
889         {
890           if (NewFpar < FparSeq.Last())
891             FparSeq(FparSeq.Length()) = NewFpar;
892           else
893             LparSeq(LparSeq.Length()) = NewLpar;
894         }
895         else
896         {
897           CurveSeq.Append(aCurve);
898           TopoDS_Shape aLocShape;
899           aLocShape.Location(aLoc);
900           aLocShape.Orientation(wexp.Orientation());
901           LocSeq.Append(aLocShape);
902           FparSeq.Append(fpar);
903           LparSeq.Append(lpar);
904           TolSeq.Append(BRep_Tool::Tolerance(CurVertex));
905           CurType = aType;
906         }
907       } // end of else (CurveSeq.IsEmpty()) -> not first time
908     } // end for (; wexp.More(); wexp.Next())
909
910     LastVertex = wexp.CurrentVertex();
911     TolSeq.Append(BRep_Tool::Tolerance(LastVertex));
912
913     TopoDS_Vertex FirstVtx_final = (FinalReverse)? LastVertex : FirstVertex;
914     FirstVtx_final.Orientation(TopAbs_FORWARD);
915     TopoDS_Vertex LastVtx_final = (FinalReverse)? FirstVertex : LastVertex;
916     LastVtx_final.Orientation(TopAbs_REVERSED);
917
918     if (!CurveSeq.IsEmpty())
919     {
920       Standard_Integer nb_curve = CurveSeq.Length();   //number of curves
921       TColGeom_Array1OfBSplineCurve tab(0,nb_curve-1);                    //array of the curves
922       TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2);  //array of the tolerances
923
924       Standard_Integer i;
925
926       if (nb_curve > 1)
927       {
928         for (i = 1; i <= nb_curve; i++)
929         {
930           if (CurveSeq(i)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
931             CurveSeq(i) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(i))))->BasisCurve();
932
933           Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(CurveSeq(i), FparSeq(i), LparSeq(i));
934           tab(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve);
935           tab(i-1)->Transform(LocSeq(i).Location().Transformation());
936           GeomConvert::C0BSplineToC1BSplineCurve(tab(i-1), Precision::Confusion());
937           if (LocSeq(i).Orientation() == TopAbs_REVERSED)
938             tab(i-1)->Reverse();
939
940           //Temporary
941           //char* name = new char[100];
942           //sprintf(name, "c%d", i);
943           //DrawTrSurf::Set(name, tab(i-1));
944
945           if (i > 1)
946             tabtolvertex(i-2) = TolSeq(i-1);
947         } // end for (i = 1; i <= nb_curve; i++)
948         tabtolvertex(nb_curve-1) = TolSeq(TolSeq.Length());
949
950         Standard_Boolean closed_flag = Standard_False;
951         Standard_Real closed_tolerance = 0.;
952         if (FirstVertex.IsSame(LastVertex) &&
953             GeomLProp::Continuity(tab(0), tab(nb_curve-1),
954                                   tab(0)->FirstParameter(),
955                                   tab(nb_curve-1)->LastParameter(),
956                                   Standard_False, Standard_False, LinTol, AngTol) >= GeomAbs_G1)
957         {
958           closed_flag = Standard_True ;
959           closed_tolerance = BRep_Tool::Tolerance(FirstVertex);
960         }
961
962         Handle(TColGeom_HArray1OfBSplineCurve)  concatcurve;     //array of the concatenated curves
963         Handle(TColStd_HArray1OfInteger)        ArrayOfIndices;  //array of the remining Vertex
964         GeomConvert::ConcatC1(tab,
965                               tabtolvertex,
966                               ArrayOfIndices,
967                               concatcurve,
968                               closed_flag,
969                               closed_tolerance);   //C1 concatenation
970
971         if (concatcurve->Length() > 1)
972         {
973           GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower()));
974
975           for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++)
976             Concat.Add( concatcurve->Value(i), LinTol, Standard_True );
977
978           concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve());
979         }
980         // rnc : prevents the driver from building an edge without C1 continuity
981         if (concatcurve->Value(concatcurve->Lower())->Continuity()==GeomAbs_C0){
982           Standard_ConstructionError::Raise("Construction aborted : The given Wire has sharp bends between some Edges, no valid Edge can be built");
983         }
984         ResEdge = BRepLib_MakeEdge(concatcurve->Value(concatcurve->Lower()),
985                                    FirstVtx_final, LastVtx_final,
986                                    concatcurve->Value(concatcurve->Lower())->FirstParameter(),
987                                    concatcurve->Value(concatcurve->Lower())->LastParameter());
988       }
989       else
990       {
991         if (CurveSeq(1)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
992           CurveSeq(1) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(1))))->BasisCurve();
993
994         CurveSeq(1)->Transform(LocSeq(1).Location().Transformation());
995         ResEdge = BRepLib_MakeEdge(CurveSeq(1),
996                                    FirstVtx_final, LastVtx_final,
997                                    FparSeq(1), LparSeq(1));
998       }
999     }
1000
1001     if (FinalReverse)
1002       ResEdge.Reverse();
1003
1004     return ResEdge;
1005 }
1006
1007 //=============================================================================
1008 /*!
1009  * \brief Returns an isoline for a face.
1010  */
1011 //=============================================================================
1012
1013 TopoDS_Shape GEOMImpl_ShapeDriver::MakeIsoline
1014                             (const TopoDS_Face &theFace,
1015                              const bool         IsUIso,
1016                              const double       theParameter) const
1017 {
1018   TopoDS_Shape          aResult;
1019   GEOMUtils_Hatcher     aHatcher(theFace);
1020   const GeomAbs_IsoType aType = (IsUIso ? GeomAbs_IsoU : GeomAbs_IsoV);
1021
1022   aHatcher.Init(aType, theParameter);
1023   aHatcher.Perform();
1024
1025   if (!aHatcher.IsDone()) {
1026     Standard_ConstructionError::Raise("MakeIsoline : Hatcher failure");
1027   }
1028
1029   const Handle(TColStd_HArray1OfInteger) &anIndices =
1030     (IsUIso ? aHatcher.GetUIndices() : aHatcher.GetVIndices());
1031
1032   if (anIndices.IsNull()) {
1033     Standard_ConstructionError::Raise("MakeIsoline : Null hatching indices");
1034   }
1035
1036   const Standard_Integer anIsoInd = anIndices->Lower();
1037   const Standard_Integer aHatchingIndex = anIndices->Value(anIsoInd);
1038
1039   if (aHatchingIndex == 0) {
1040     Standard_ConstructionError::Raise("MakeIsoline : Invalid hatching index");
1041   }
1042
1043   const Standard_Integer aNbDomains =
1044     aHatcher.GetNbDomains(aHatchingIndex);
1045
1046   if (aNbDomains < 0) {
1047     Standard_ConstructionError::Raise("MakeIsoline : Invalid number of domains");
1048   }
1049
1050   // The hatching is performed successfully. Create the 3d Curve.
1051   Handle(Geom_Surface) aSurface   = BRep_Tool::Surface(theFace);
1052   Handle(Geom_Curve)   anIsoCurve = (IsUIso ?
1053     aSurface->UIso(theParameter) : aSurface->VIso(theParameter));
1054   Handle(Geom2d_Curve) aPIsoCurve =
1055     aHatcher.GetHatching(aHatchingIndex);
1056   const Standard_Real  aTol = Precision::Confusion();
1057   Standard_Integer     anIDom = 1;
1058   Standard_Real        aV1;
1059   Standard_Real        aV2;
1060   BRep_Builder         aBuilder;
1061   Standard_Integer     aNbEdges = 0;
1062
1063   for (; anIDom <= aNbDomains; anIDom++) {
1064     if (aHatcher.GetDomain(aHatchingIndex, anIDom, aV1, aV2)) {
1065       // Check first and last parameters.
1066       if (!aHatcher.IsDomainInfinite(aHatchingIndex, anIDom)) {
1067         // Create an edge.
1068         TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(anIsoCurve, aV1, aV2);
1069
1070         // Update it with a parametric curve on face.
1071         aBuilder.UpdateEdge(anEdge, aPIsoCurve, theFace, aTol);
1072         aNbEdges++;
1073
1074         if (aNbEdges > 1) {
1075           // Result is a compond.
1076           if (aNbEdges == 2) {
1077             // Create a new compound.
1078             TopoDS_Compound aCompound;
1079
1080             aBuilder.MakeCompound(aCompound);
1081             aBuilder.Add(aCompound, aResult);
1082             aResult = aCompound;
1083           }
1084
1085           // Add an edge to the compound.
1086           aBuilder.Add(aResult, anEdge);
1087         } else {
1088           // Result is the edge.
1089           aResult = anEdge;
1090         }
1091       }
1092     }
1093   }
1094
1095   if (aNbEdges == 0) {
1096     Standard_ConstructionError::Raise("MakeIsoline : Empty result");
1097   }
1098
1099   return aResult;
1100 }
1101
1102 //================================================================================
1103 /*!
1104  * \brief Returns a name of creation operation and names and values of creation parameters
1105  */
1106 //================================================================================
1107
1108 bool GEOMImpl_ShapeDriver::
1109 GetCreationInformation(std::string&             theOperationName,
1110                        std::vector<GEOM_Param>& theParams)
1111 {
1112   if (Label().IsNull()) return 0;
1113   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
1114
1115   GEOMImpl_IShapes aCI( function );
1116   Standard_Integer aType = function->GetType();
1117
1118   switch ( aType ) {
1119   case WIRE_EDGES:
1120     theOperationName = "WIRE";
1121     AddParam( theParams, "Wires/edges", aCI.GetShapes() );
1122     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
1123     break;
1124   case FACE_WIRE:
1125     theOperationName = "FACE";
1126     AddParam( theParams, "Wire/edge", aCI.GetBase() );
1127     AddParam( theParams, "Is planar wanted", aCI.GetIsPlanar() );
1128     break;
1129   case FACE_WIRES:
1130     theOperationName = "FACE";
1131     AddParam( theParams, "Wires/edges", aCI.GetShapes() );
1132     AddParam( theParams, "Is planar wanted", aCI.GetIsPlanar() );
1133     break;
1134   case SHELL_FACES:
1135     theOperationName = "SHELL";
1136     AddParam( theParams, "Objects", aCI.GetShapes() );
1137     break;
1138   case SOLID_SHELL:
1139   case SOLID_SHELLS:
1140     theOperationName = "SOLID";
1141     AddParam( theParams, "Objects", aCI.GetShapes() );
1142     break;
1143   case COMPOUND_SHAPES:
1144     theOperationName = "COMPOUND";
1145     AddParam( theParams, "Objects", aCI.GetShapes() );
1146     break;
1147   case EDGE_WIRE:
1148     theOperationName = "EDGE";
1149     AddParam( theParams, "Wire", aCI.GetBase() );
1150     AddParam( theParams, "Linear Tolerance", aCI.GetTolerance() );
1151     AddParam( theParams, "Angular Tolerance", aCI.GetAngularTolerance() );
1152     break;
1153   case EDGE_CURVE_LENGTH:
1154     theOperationName = "EDGE";
1155     {
1156       GEOMImpl_IVector aCI( function );
1157       AddParam( theParams, "Edge", aCI.GetPoint1() );
1158       AddParam( theParams, "Start point", aCI.GetPoint2() );
1159       AddParam( theParams, "Length", aCI.GetParameter() );
1160     }
1161     break;
1162   case SHAPES_ON_SHAPE:
1163   {
1164     theOperationName = "GetShapesOnShapeAsCompound";
1165     Handle(TColStd_HSequenceOfTransient) shapes = aCI.GetShapes();
1166     if ( !shapes.IsNull() && shapes->Length() > 0 )
1167       AddParam( theParams, "Check shape", shapes->Value(1) );
1168     if ( !shapes.IsNull() && shapes->Length() > 1 )
1169       AddParam( theParams, "Shape", shapes->Value(2) );
1170     AddParam( theParams, "Shape type", TopAbs_ShapeEnum( aCI.GetSubShapeType() ));
1171     AddParam( theParams, "State", TopAbs_State((int) aCI.GetTolerance() ));
1172     break;
1173   }
1174   case SHAPE_ISOLINE:
1175   {
1176     GEOMImpl_IIsoline aII (function);
1177
1178     theOperationName = "ISOLINE";
1179     AddParam(theParams, "Face", aII.GetFace());
1180     AddParam(theParams, "Isoline type", (aII.GetIsUIso() ? "U" : "V"));
1181     AddParam(theParams, "Parameter", aII.GetParameter());
1182     break;
1183   }
1184   default:
1185     return false;
1186   }
1187
1188   return true;
1189 }
1190
1191 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_ShapeDriver,GEOM_BaseDriver);
1192 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_ShapeDriver,GEOM_BaseDriver);
1193
1194 //modified by NIZNHY-PKV Wed Dec 28 13:48:31 2011f
1195 #include <TopoDS_Iterator.hxx>
1196 #include <TopTools_HSequenceOfShape.hxx>
1197 #include <ShapeAnalysis_FreeBounds.hxx>
1198 #include <TopTools_MapOfShape.hxx>
1199 #include <TopTools_MapOfOrientedShape.hxx>
1200 #include <BRep_Builder.hxx>
1201 #include <TopoDS_Wire.hxx>
1202
1203 //=======================================================================
1204 //function : KeepEdgesOrder
1205 //purpose  : 
1206 //=======================================================================
1207 /*
1208 void KeepEdgesOrder(const Handle(TopTools_HSequenceOfShape)& aEdges,
1209                     const Handle(TopTools_HSequenceOfShape)& aWires)
1210 {
1211   Standard_Integer aNbWires, aNbEdges;
1212   // 
1213   if (aEdges.IsNull()) {
1214     return;
1215   }
1216   //
1217   if (aWires.IsNull()) {
1218     return;
1219   }
1220   //
1221   aNbEdges=aEdges->Length();
1222   aNbWires=aWires->Length();
1223   if (!aNbEdges || !aNbWires) {
1224     return;
1225   }
1226   //-----
1227   Standard_Boolean bClosed;
1228   Standard_Integer i, j;
1229   TopoDS_Wire aWy;
1230   TopoDS_Iterator aIt;
1231   BRep_Builder aBB;
1232   TopTools_MapOfOrientedShape aMEx;
1233   //
1234   for (i=1; i<=aNbWires; ++i) {
1235     const TopoDS_Shape& aWx=aWires->Value(i);
1236     //
1237     aMEx.Clear();
1238     aIt.Initialize (aWx);
1239     for (; aIt.More(); aIt.Next()) {
1240       const TopoDS_Shape& aEx=aIt.Value();
1241       aMEx.Add(aEx);
1242     }
1243     // aWy
1244     aBB.MakeWire (aWy);
1245     for (j=1; j<=aNbEdges; ++j) {
1246       const TopoDS_Shape& aE=aEdges->Value(j);
1247       if (aMEx.Contains(aE)) {
1248         aBB.Add(aWy, aE);
1249       }
1250     }
1251     //
1252     bClosed=aWx.Closed();
1253     aWy.Closed(bClosed);
1254     //
1255     aWires->Append(aWy);
1256   }// for (i=1; i<=aNbWires; ++i) {
1257   //
1258   aWires->Remove(1, aNbWires);
1259 }
1260 */
1261 //modified by NIZNHY-PKV Wed Dec 28 13:48:34 2011t