Salome HOME
360b94c83f5819a66d84817d3bc7d5cc8a23db31
[modules/geom.git] / src / GEOMImpl / GEOMImpl_ShapeDriver.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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
678     BRepTools_WireExplorer wexp(theWire) ;
679     for (; wexp.More(); wexp.Next())
680     {
681       TopoDS_Edge anEdge = wexp.Current();
682       Standard_Real fpar, lpar;
683       TopLoc_Location aLoc;
684       Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aLoc, fpar, lpar);
685       if (aCurve.IsNull())
686         continue;
687
688       BRepAdaptor_Curve BAcurve(anEdge);
689       GeomAbs_CurveType aType = BAcurve.GetType();
690
691       Handle(Geom_Curve) aBasisCurve = BAcurve.Curve().Curve();
692
693       if (aBasisCurve->IsPeriodic())
694         ElCLib::AdjustPeriodic(aBasisCurve->FirstParameter(), aBasisCurve->LastParameter(),
695                                Precision::PConfusion(), fpar, lpar);
696
697       if (CurveSeq.IsEmpty())
698       {
699         CurveSeq.Append(aCurve);
700         TopoDS_Shape aLocShape;
701         aLocShape.Location(aLoc);
702         aLocShape.Orientation(wexp.Orientation());
703         LocSeq.Append(aLocShape);
704         FparSeq.Append(fpar);
705         LparSeq.Append(lpar);
706         CurType = aType;
707         FirstVertex = wexp.CurrentVertex();
708       }
709       else
710       {
711         Standard_Boolean Done = Standard_False;
712         Standard_Real NewFpar, NewLpar;
713         GeomAdaptor_Curve GAprevcurve(CurveSeq.Last());
714         TopoDS_Vertex CurVertex = wexp.CurrentVertex();
715         TopoDS_Vertex CurFirstVer = TopExp::FirstVertex(anEdge);
716         TopAbs_Orientation ConnectByOrigin = (CurVertex.IsSame(CurFirstVer))? TopAbs_FORWARD : TopAbs_REVERSED;
717         if (aCurve == CurveSeq.Last())
718         {
719           NewFpar = fpar;
720           NewLpar = lpar;
721           if (aBasisCurve->IsPeriodic())
722           {
723             if (NewLpar < NewFpar)
724               NewLpar += aBasisCurve->Period();
725             if (ConnectByOrigin == TopAbs_FORWARD)
726               ElCLib::AdjustPeriodic(FparSeq.Last(),
727                                      FparSeq.Last() + aBasisCurve->Period(),
728                                      Precision::PConfusion(), NewFpar, NewLpar);
729             else
730               ElCLib::AdjustPeriodic(FparSeq.Last() - aBasisCurve->Period(),
731                                      FparSeq.Last(),
732                                      Precision::PConfusion(), NewFpar, NewLpar);
733           }
734           Done = Standard_True;
735         }
736         else if (aType == CurType &&
737                  aType != GeomAbs_BezierCurve &&
738                  aType != GeomAbs_BSplineCurve &&
739                  aType != GeomAbs_OtherCurve)
740         {
741           switch (aType)
742           {
743           case GeomAbs_Line:
744             {
745               gp_Lin aLine    = BAcurve.Line();
746               gp_Lin PrevLine = GAprevcurve.Line();
747               if (aLine.Contains(PrevLine.Location(), LinTol) &&
748                   aLine.Direction().IsParallel(PrevLine.Direction(), AngTol))
749               {
750                 gp_Pnt P1 = ElCLib::Value(fpar, aLine);
751                 gp_Pnt P2 = ElCLib::Value(lpar, aLine);
752                 NewFpar = ElCLib::Parameter(PrevLine, P1);
753                 NewLpar = ElCLib::Parameter(PrevLine, P2);
754                 if (NewLpar < NewFpar)
755                 {
756                   Standard_Real MemNewFpar = NewFpar;
757                   NewFpar = NewLpar;
758                   NewLpar = MemNewFpar;
759                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
760                 }
761                 Done = Standard_True;
762               }
763               break;
764             }
765           case GeomAbs_Circle:
766             {
767               gp_Circ aCircle    = BAcurve.Circle();
768               gp_Circ PrevCircle = GAprevcurve.Circle();
769               if (aCircle.Location().Distance(PrevCircle.Location()) <= LinTol &&
770                   Abs(aCircle.Radius() - PrevCircle.Radius()) <= LinTol &&
771                   aCircle.Axis().IsParallel(PrevCircle.Axis(), AngTol))
772               {
773                 if (aCircle.Axis().Direction() * PrevCircle.Axis().Direction() < 0.)
774                 {
775                   Standard_Real memfpar = fpar;
776                   fpar = lpar;
777                   lpar = memfpar;
778                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
779                 }
780                 gp_Pnt P1 = ElCLib::Value(fpar, aCircle);
781                 gp_Pnt P2 = ElCLib::Value(lpar, aCircle);
782                 NewFpar = ElCLib::Parameter(PrevCircle, P1);
783                 NewLpar = ElCLib::Parameter(PrevCircle, P2);
784                 if (NewLpar < NewFpar)
785                   NewLpar += 2.*M_PI;
786                 //Standard_Real MemNewFpar = NewFpar, MemNewLpar =  NewLpar;
787                 if (ConnectByOrigin == TopAbs_FORWARD)
788                   ElCLib::AdjustPeriodic(FparSeq.Last(),
789                                          FparSeq.Last() + 2.*M_PI,
790                                          Precision::PConfusion(), NewFpar, NewLpar);
791                 else
792                   ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*M_PI,
793                                          FparSeq.Last(),
794                                          Precision::PConfusion(), NewFpar, NewLpar);
795                 Done = Standard_True;
796               }
797               break;
798             }
799           case GeomAbs_Ellipse:
800             {
801               gp_Elips anEllipse   = BAcurve.Ellipse();
802               gp_Elips PrevEllipse = GAprevcurve.Ellipse();
803               if (anEllipse.Focus1().Distance(PrevEllipse.Focus1()) <= LinTol &&
804                   anEllipse.Focus2().Distance(PrevEllipse.Focus2()) <= LinTol &&
805                   Abs(anEllipse.MajorRadius() - PrevEllipse.MajorRadius()) <= LinTol &&
806                   Abs(anEllipse.MinorRadius() - PrevEllipse.MinorRadius()) <= LinTol &&
807                   anEllipse.Axis().IsParallel(PrevEllipse.Axis(), AngTol))
808               {
809                 if (anEllipse.Axis().Direction() * PrevEllipse.Axis().Direction() < 0.)
810                 {
811                   Standard_Real memfpar = fpar;
812                   fpar = lpar;
813                   lpar = memfpar;
814                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
815                 }
816                 gp_Pnt P1 = ElCLib::Value(fpar, anEllipse);
817                 gp_Pnt P2 = ElCLib::Value(lpar, anEllipse);
818                 NewFpar = ElCLib::Parameter(PrevEllipse, P1);
819                 NewLpar = ElCLib::Parameter(PrevEllipse, P2);
820                 if (NewLpar < NewFpar)
821                   NewLpar += 2.*M_PI;
822                 if (ConnectByOrigin == TopAbs_FORWARD)
823                   ElCLib::AdjustPeriodic(FparSeq.Last(),
824                                          FparSeq.Last() + 2.*M_PI,
825                                          Precision::PConfusion(), NewFpar, NewLpar);
826                 else
827                   ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*M_PI,
828                                          FparSeq.Last(),
829                                          Precision::PConfusion(), NewFpar, NewLpar);
830                 Done = Standard_True;
831               }
832               break;
833             }
834           case GeomAbs_Hyperbola:
835             {
836               gp_Hypr aHypr    = BAcurve.Hyperbola();
837               gp_Hypr PrevHypr = GAprevcurve.Hyperbola();
838               if (aHypr.Focus1().Distance(PrevHypr.Focus1()) <= LinTol &&
839                   aHypr.Focus2().Distance(PrevHypr.Focus2()) <= LinTol &&
840                   Abs(aHypr.MajorRadius() - PrevHypr.MajorRadius()) <= LinTol &&
841                   Abs(aHypr.MinorRadius() - PrevHypr.MinorRadius()) <= LinTol &&
842                   aHypr.Axis().IsParallel(PrevHypr.Axis(), AngTol))
843               {
844                 gp_Pnt P1 = ElCLib::Value(fpar, aHypr);
845                 gp_Pnt P2 = ElCLib::Value(lpar, aHypr);
846                 NewFpar = ElCLib::Parameter(PrevHypr, P1);
847                 NewLpar = ElCLib::Parameter(PrevHypr, P2);
848                 if (NewLpar < NewFpar)
849                 {
850                   Standard_Real MemNewFpar = NewFpar;
851                   NewFpar = NewLpar;
852                   NewLpar = MemNewFpar;
853                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
854                 }
855                 Done = Standard_True;
856               }
857               break;
858             }
859           case GeomAbs_Parabola:
860             {
861               gp_Parab aParab    = BAcurve.Parabola();
862               gp_Parab PrevParab = GAprevcurve.Parabola();
863               if (aParab.Location().Distance(PrevParab.Location()) <= LinTol &&
864                   aParab.Focus().Distance(PrevParab.Focus()) <= LinTol &&
865                   Abs(aParab.Focal() - PrevParab.Focal()) <= LinTol &&
866                   aParab.Axis().IsParallel(PrevParab.Axis(), AngTol))
867               {
868                 gp_Pnt P1 = ElCLib::Value(fpar, aParab);
869                 gp_Pnt P2 = ElCLib::Value(lpar, aParab);
870                 NewFpar = ElCLib::Parameter(PrevParab, P1);
871                 NewLpar = ElCLib::Parameter(PrevParab, P2);
872                 if (NewLpar < NewFpar)
873                 {
874                   Standard_Real MemNewFpar = NewFpar;
875                   NewFpar = NewLpar;
876                   NewLpar = MemNewFpar;
877                   ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
878                 }
879                 Done = Standard_True;
880               }
881               break;
882             }
883           } //end of switch (aType)
884         } // end of else if (aType == CurType && ...
885         if (Done)
886         {
887           if (NewFpar < FparSeq.Last())
888             FparSeq(FparSeq.Length()) = NewFpar;
889           else
890             LparSeq(LparSeq.Length()) = NewLpar;
891         }
892         else
893         {
894           CurveSeq.Append(aCurve);
895           TopoDS_Shape aLocShape;
896           aLocShape.Location(aLoc);
897           aLocShape.Orientation(wexp.Orientation());
898           LocSeq.Append(aLocShape);
899           FparSeq.Append(fpar);
900           LparSeq.Append(lpar);
901           TolSeq.Append(BRep_Tool::Tolerance(CurVertex));
902           CurType = aType;
903         }
904       } // end of else (CurveSeq.IsEmpty()) -> not first time
905     } // end for (; wexp.More(); wexp.Next())
906
907     LastVertex = wexp.CurrentVertex();
908     TolSeq.Append(BRep_Tool::Tolerance(LastVertex));
909
910     FirstVertex.Orientation(TopAbs_FORWARD);
911     LastVertex.Orientation(TopAbs_REVERSED);
912
913     if (!CurveSeq.IsEmpty())
914     {
915       Standard_Integer nb_curve = CurveSeq.Length();   //number of curves
916       TColGeom_Array1OfBSplineCurve tab(0,nb_curve-1);                    //array of the curves
917       TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2);  //array of the tolerances
918
919       Standard_Integer i;
920
921       if (nb_curve > 1)
922       {
923         for (i = 1; i <= nb_curve; i++)
924         {
925           if (CurveSeq(i)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
926             CurveSeq(i) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(i))))->BasisCurve();
927
928           Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(CurveSeq(i), FparSeq(i), LparSeq(i));
929           tab(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve);
930           tab(i-1)->Transform(LocSeq(i).Location().Transformation());
931           GeomConvert::C0BSplineToC1BSplineCurve(tab(i-1), Precision::Confusion());
932           if (LocSeq(i).Orientation() == TopAbs_REVERSED)
933             tab(i-1)->Reverse();
934
935           //Temporary
936           //char* name = new char[100];
937           //sprintf(name, "c%d", i);
938           //DrawTrSurf::Set(name, tab(i-1));
939
940           if (i > 1)
941             tabtolvertex(i-2) = TolSeq(i-1);
942         } // end for (i = 1; i <= nb_curve; i++)
943         tabtolvertex(nb_curve-1) = TolSeq(TolSeq.Length());
944
945         Standard_Boolean closed_flag = Standard_False;
946         Standard_Real closed_tolerance = 0.;
947         if (FirstVertex.IsSame(LastVertex) &&
948             GeomLProp::Continuity(tab(0), tab(nb_curve-1),
949                                   tab(0)->FirstParameter(),
950                                   tab(nb_curve-1)->LastParameter(),
951                                   Standard_False, Standard_False, LinTol, AngTol) >= GeomAbs_G1)
952         {
953           closed_flag = Standard_True ;
954           closed_tolerance = BRep_Tool::Tolerance(FirstVertex);
955         }
956
957         Handle(TColGeom_HArray1OfBSplineCurve)  concatcurve;     //array of the concatenated curves
958         Handle(TColStd_HArray1OfInteger)        ArrayOfIndices;  //array of the remining Vertex
959         GeomConvert::ConcatC1(tab,
960                               tabtolvertex,
961                               ArrayOfIndices,
962                               concatcurve,
963                               closed_flag,
964                               closed_tolerance);   //C1 concatenation
965
966         if (concatcurve->Length() > 1)
967         {
968           GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower()));
969
970           for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++)
971             Concat.Add( concatcurve->Value(i), LinTol, Standard_True );
972
973           concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve());
974         }
975         // rnc : prevents the driver from building an edge without C1 continuity
976         if (concatcurve->Value(concatcurve->Lower())->Continuity()==GeomAbs_C0){
977           Standard_ConstructionError::Raise("Construction aborted : The given Wire has sharp bends between some Edges, no valid Edge can be built");
978         }
979         ResEdge = BRepLib_MakeEdge(concatcurve->Value(concatcurve->Lower()),
980                                    FirstVertex, LastVertex,
981                                    concatcurve->Value(concatcurve->Lower())->FirstParameter(),
982                                    concatcurve->Value(concatcurve->Lower())->LastParameter());
983       }
984       else
985       {
986         if (CurveSeq(1)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
987           CurveSeq(1) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(1))))->BasisCurve();
988
989         Handle(Geom_Curve) aNewCurve =
990           Handle(Geom_Curve)::DownCast(CurveSeq(1)->Copy());
991
992         aNewCurve->Transform(LocSeq(1).Location().Transformation());
993
994         if (LocSeq(1).Orientation() == TopAbs_REVERSED) {
995           const TopoDS_Vertex aVtxTmp = FirstVertex;
996
997           FirstVertex = LastVertex;
998           LastVertex  = aVtxTmp;
999           FirstVertex.Orientation(TopAbs_FORWARD);
1000           LastVertex.Orientation(TopAbs_REVERSED);
1001         }
1002
1003         ResEdge = BRepLib_MakeEdge(aNewCurve,
1004                                    FirstVertex, LastVertex,
1005                                    FparSeq(1), LparSeq(1));
1006
1007         if (LocSeq(1).Orientation() == TopAbs_REVERSED) {
1008           ResEdge.Reverse();
1009         }
1010       }
1011     }
1012
1013     return ResEdge;
1014 }
1015
1016 //=============================================================================
1017 /*!
1018  * \brief Returns an isoline for a face.
1019  */
1020 //=============================================================================
1021
1022 TopoDS_Shape GEOMImpl_ShapeDriver::MakeIsoline
1023                             (const TopoDS_Face &theFace,
1024                              const bool         IsUIso,
1025                              const double       theParameter) const
1026 {
1027   TopoDS_Shape          aResult;
1028   GEOMUtils_Hatcher     aHatcher(theFace);
1029   const GeomAbs_IsoType aType = (IsUIso ? GeomAbs_IsoU : GeomAbs_IsoV);
1030
1031   aHatcher.Init(aType, theParameter);
1032   aHatcher.Perform();
1033
1034   if (!aHatcher.IsDone()) {
1035     Standard_ConstructionError::Raise("MakeIsoline : Hatcher failure");
1036   }
1037
1038   const Handle(TColStd_HArray1OfInteger) &anIndices =
1039     (IsUIso ? aHatcher.GetUIndices() : aHatcher.GetVIndices());
1040
1041   if (anIndices.IsNull()) {
1042     Standard_ConstructionError::Raise("MakeIsoline : Null hatching indices");
1043   }
1044
1045   const Standard_Integer anIsoInd = anIndices->Lower();
1046   const Standard_Integer aHatchingIndex = anIndices->Value(anIsoInd);
1047
1048   if (aHatchingIndex == 0) {
1049     Standard_ConstructionError::Raise("MakeIsoline : Invalid hatching index");
1050   }
1051
1052   const Standard_Integer aNbDomains =
1053     aHatcher.GetNbDomains(aHatchingIndex);
1054
1055   if (aNbDomains < 0) {
1056     Standard_ConstructionError::Raise("MakeIsoline : Invalid number of domains");
1057   }
1058
1059   // The hatching is performed successfully. Create the 3d Curve.
1060   Handle(Geom_Surface) aSurface   = BRep_Tool::Surface(theFace);
1061   Handle(Geom_Curve)   anIsoCurve = (IsUIso ?
1062     aSurface->UIso(theParameter) : aSurface->VIso(theParameter));
1063   Handle(Geom2d_Curve) aPIsoCurve =
1064     aHatcher.GetHatching(aHatchingIndex);
1065   const Standard_Real  aTol = Precision::Confusion();
1066   Standard_Integer     anIDom = 1;
1067   Standard_Real        aV1;
1068   Standard_Real        aV2;
1069   BRep_Builder         aBuilder;
1070   Standard_Integer     aNbEdges = 0;
1071
1072   for (; anIDom <= aNbDomains; anIDom++) {
1073     if (aHatcher.GetDomain(aHatchingIndex, anIDom, aV1, aV2)) {
1074       // Check first and last parameters.
1075       if (!aHatcher.IsDomainInfinite(aHatchingIndex, anIDom)) {
1076         // Create an edge.
1077         TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(anIsoCurve, aV1, aV2);
1078
1079         // Update it with a parametric curve on face.
1080         aBuilder.UpdateEdge(anEdge, aPIsoCurve, theFace, aTol);
1081         aNbEdges++;
1082
1083         if (aNbEdges > 1) {
1084           // Result is a compond.
1085           if (aNbEdges == 2) {
1086             // Create a new compound.
1087             TopoDS_Compound aCompound;
1088
1089             aBuilder.MakeCompound(aCompound);
1090             aBuilder.Add(aCompound, aResult);
1091             aResult = aCompound;
1092           }
1093
1094           // Add an edge to the compound.
1095           aBuilder.Add(aResult, anEdge);
1096         } else {
1097           // Result is the edge.
1098           aResult = anEdge;
1099         }
1100       }
1101     }
1102   }
1103
1104   if (aNbEdges == 0) {
1105     Standard_ConstructionError::Raise("MakeIsoline : Empty result");
1106   }
1107
1108   return aResult;
1109 }
1110
1111 //================================================================================
1112 /*!
1113  * \brief Returns a name of creation operation and names and values of creation parameters
1114  */
1115 //================================================================================
1116
1117 bool GEOMImpl_ShapeDriver::
1118 GetCreationInformation(std::string&             theOperationName,
1119                        std::vector<GEOM_Param>& theParams)
1120 {
1121   if (Label().IsNull()) return 0;
1122   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
1123
1124   GEOMImpl_IShapes aCI( function );
1125   Standard_Integer aType = function->GetType();
1126
1127   switch ( aType ) {
1128   case WIRE_EDGES:
1129     theOperationName = "WIRE";
1130     AddParam( theParams, "Wires/edges", aCI.GetShapes() );
1131     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
1132     break;
1133   case FACE_WIRE:
1134     theOperationName = "FACE";
1135     AddParam( theParams, "Wire/edge", aCI.GetBase() );
1136     AddParam( theParams, "Is planar wanted", aCI.GetIsPlanar() );
1137     break;
1138   case FACE_WIRES:
1139     theOperationName = "FACE";
1140     AddParam( theParams, "Wires/edges", aCI.GetShapes() );
1141     AddParam( theParams, "Is planar wanted", aCI.GetIsPlanar() );
1142     break;
1143   case SHELL_FACES:
1144     theOperationName = "SHELL";
1145     AddParam( theParams, "Objects", aCI.GetShapes() );
1146     break;
1147   case SOLID_SHELL:
1148   case SOLID_SHELLS:
1149     theOperationName = "SOLID";
1150     AddParam( theParams, "Objects", aCI.GetShapes() );
1151     break;
1152   case COMPOUND_SHAPES:
1153     theOperationName = "COMPOUND";
1154     AddParam( theParams, "Objects", aCI.GetShapes() );
1155     break;
1156   case EDGE_WIRE:
1157     theOperationName = "EDGE";
1158     AddParam( theParams, "Wire", aCI.GetBase() );
1159     AddParam( theParams, "Linear Tolerance", aCI.GetTolerance() );
1160     AddParam( theParams, "Angular Tolerance", aCI.GetAngularTolerance() );
1161     break;
1162   case EDGE_CURVE_LENGTH:
1163     theOperationName = "EDGE";
1164     {
1165       GEOMImpl_IVector aCI( function );
1166       AddParam( theParams, "Edge", aCI.GetPoint1() );
1167       AddParam( theParams, "Start point", aCI.GetPoint2() );
1168       AddParam( theParams, "Length", aCI.GetParameter() );
1169     }
1170     break;
1171   case SHAPES_ON_SHAPE:
1172   {
1173     theOperationName = "GetShapesOnShapeAsCompound";
1174     Handle(TColStd_HSequenceOfTransient) shapes = aCI.GetShapes();
1175     if ( !shapes.IsNull() && shapes->Length() > 0 )
1176       AddParam( theParams, "Check shape", shapes->Value(1) );
1177     if ( !shapes.IsNull() && shapes->Length() > 1 )
1178       AddParam( theParams, "Shape", shapes->Value(2) );
1179     AddParam( theParams, "Shape type", TopAbs_ShapeEnum( aCI.GetSubShapeType() ));
1180     AddParam( theParams, "State", TopAbs_State((int) aCI.GetTolerance() ));
1181     break;
1182   }
1183   case SHAPE_ISOLINE:
1184   {
1185     GEOMImpl_IIsoline aII (function);
1186
1187     theOperationName = "ISOLINE";
1188     AddParam(theParams, "Face", aII.GetFace());
1189     AddParam(theParams, "Isoline type", (aII.GetIsUIso() ? "U" : "V"));
1190     AddParam(theParams, "Parameter", aII.GetParameter());
1191     break;
1192   }
1193   default:
1194     return false;
1195   }
1196
1197   return true;
1198 }
1199
1200 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_ShapeDriver,GEOM_BaseDriver);
1201 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_ShapeDriver,GEOM_BaseDriver);
1202
1203 //modified by NIZNHY-PKV Wed Dec 28 13:48:31 2011f
1204 #include <TopoDS_Iterator.hxx>
1205 #include <TopTools_HSequenceOfShape.hxx>
1206 #include <ShapeAnalysis_FreeBounds.hxx>
1207 #include <TopTools_MapOfShape.hxx>
1208 #include <TopTools_MapOfOrientedShape.hxx>
1209 #include <BRep_Builder.hxx>
1210 #include <TopoDS_Wire.hxx>
1211
1212 //=======================================================================
1213 //function : KeepEdgesOrder
1214 //purpose  : 
1215 //=======================================================================
1216 /*
1217 void KeepEdgesOrder(const Handle(TopTools_HSequenceOfShape)& aEdges,
1218                     const Handle(TopTools_HSequenceOfShape)& aWires)
1219 {
1220   Standard_Integer aNbWires, aNbEdges;
1221   // 
1222   if (aEdges.IsNull()) {
1223     return;
1224   }
1225   //
1226   if (aWires.IsNull()) {
1227     return;
1228   }
1229   //
1230   aNbEdges=aEdges->Length();
1231   aNbWires=aWires->Length();
1232   if (!aNbEdges || !aNbWires) {
1233     return;
1234   }
1235   //-----
1236   Standard_Boolean bClosed;
1237   Standard_Integer i, j;
1238   TopoDS_Wire aWy;
1239   TopoDS_Iterator aIt;
1240   BRep_Builder aBB;
1241   TopTools_MapOfOrientedShape aMEx;
1242   //
1243   for (i=1; i<=aNbWires; ++i) {
1244     const TopoDS_Shape& aWx=aWires->Value(i);
1245     //
1246     aMEx.Clear();
1247     aIt.Initialize (aWx);
1248     for (; aIt.More(); aIt.Next()) {
1249       const TopoDS_Shape& aEx=aIt.Value();
1250       aMEx.Add(aEx);
1251     }
1252     // aWy
1253     aBB.MakeWire (aWy);
1254     for (j=1; j<=aNbEdges; ++j) {
1255       const TopoDS_Shape& aE=aEdges->Value(j);
1256       if (aMEx.Contains(aE)) {
1257         aBB.Add(aWy, aE);
1258       }
1259     }
1260     //
1261     bClosed=aWx.Closed();
1262     aWy.Closed(bClosed);
1263     //
1264     aWires->Append(aWy);
1265   }// for (i=1; i<=aNbWires; ++i) {
1266   //
1267   aWires->Remove(1, aNbWires);
1268 }
1269 */
1270 //modified by NIZNHY-PKV Wed Dec 28 13:48:34 2011t