1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include <GEOMImpl_PipeDriver.hxx>
24 #include <GEOMImpl_IPipeDiffSect.hxx>
25 #include <GEOMImpl_IPipeShellSect.hxx>
26 #include <GEOMImpl_IPipeBiNormal.hxx>
27 #include <GEOMImpl_IPipe.hxx>
28 #include <GEOMImpl_IPipePath.hxx>
29 #include <GEOMImpl_GlueDriver.hxx>
30 #include <GEOMImpl_Types.hxx>
32 #include <GEOM_Function.hxx>
34 #include <GEOMUtils.hxx>
36 #include <ShapeAnalysis_FreeBounds.hxx>
37 #include <ShapeAnalysis_Edge.hxx>
38 #include <ShapeFix_Face.hxx>
39 #include <ShapeFix_Shell.hxx>
40 #include <ShapeFix_Shape.hxx>
41 #include <ShapeFix_ShapeTolerance.hxx>
43 #include <BRep_Tool.hxx>
44 #include <BRep_Builder.hxx>
45 #include <BRepBuilderAPI_Copy.hxx>
46 #include <BRepBuilderAPI_MakeFace.hxx>
47 #include <BRepBuilderAPI_MakeWire.hxx>
48 #include <BRepBuilderAPI_Sewing.hxx>
49 #include <BRepCheck_Analyzer.hxx>
50 #include <BRepGProp.hxx>
51 #include <BRepOffsetAPI_MakePipe.hxx>
52 #include <BRepOffsetAPI_MakePipeShell.hxx>
56 #include <TopExp_Explorer.hxx>
58 #include <TopoDS_Wire.hxx>
59 #include <TopoDS_Edge.hxx>
60 #include <TopoDS_Shape.hxx>
61 #include <TopoDS_Solid.hxx>
62 #include <TopoDS_Shell.hxx>
63 #include <TopoDS_Face.hxx>
64 #include <TopoDS_Compound.hxx>
65 #include <TopTools_SequenceOfShape.hxx>
66 #include <TopTools_HSequenceOfShape.hxx>
67 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
68 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
69 #include <TopTools_ListIteratorOfListOfShape.hxx>
71 #include <GProp_GProps.hxx>
73 #include <GeomAPI_ProjectPointOnCurve.hxx>
74 #include <GeomAPI_Interpolate.hxx>
75 #include <Geom_TrimmedCurve.hxx>
76 #include <Geom_Plane.hxx>
77 #include <Geom_RectangularTrimmedSurface.hxx>
78 #include <Geom_BezierSurface.hxx>
79 #include <Geom_Line.hxx>
80 #include <Geom_Conic.hxx>
81 #include <Geom_BSplineCurve.hxx>
82 #include <Geom_BSplineSurface.hxx>
83 #include <GeomFill_BSplineCurves.hxx>
84 #include <GeomConvert_ApproxCurve.hxx>
85 #include <GeomConvert.hxx>
87 #include <TColgp_SequenceOfPnt.hxx>
88 #include <TColgp_HArray1OfPnt.hxx>
89 #include <TColgp_Array2OfPnt.hxx>
90 #include <TColStd_HSequenceOfTransient.hxx>
92 #include <Precision.hxx>
94 #include <Standard_NullObject.hxx>
95 #include <Standard_TypeMismatch.hxx>
96 #include <Standard_ConstructionError.hxx>
98 #include "utilities.h"
100 //////////////////////////////////////////////////////////////////////////
101 // Uncomment below macro to perform gluing in the end of MakePipe operation
102 // as fix of issue 0020207.
103 //////////////////////////////////////////////////////////////////////////
104 //#define GLUE_0020207
107 //=======================================================================
110 //=======================================================================
111 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
113 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
117 //=======================================================================
118 //function : GEOMImpl_PipeDriver
120 //=======================================================================
121 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
125 //=======================================================================
126 //function : FillForOtherEdges
127 //purpose : auxilary for CreatePipeForShellSections()
128 //=======================================================================
129 static bool FillForOtherEdges(const TopoDS_Shape& F1,
130 const TopoDS_Shape& E1,
131 const TopoDS_Shape& V1,
132 TopTools_IndexedDataMapOfShapeShape& FF)
134 //cout<<"FillForOtherEdges"<<endl;
135 // find other pairs for vertexes and edges
136 // creating map of vertex edges for both faces
137 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
138 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
139 if (!FF.Contains(F1))
140 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
141 if (!FF.Contains(E1))
142 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
143 if (!FF.Contains(V1))
144 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
145 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
146 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
147 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
148 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
149 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
151 TopoDS_Edge ES1 = TopoDS::Edge(E1);
152 TopoDS_Edge ES2 = TopoDS::Edge(E2);
153 TopoDS_Shape VS1 = V1;
154 TopoDS_Shape VS2 = V2;
156 ShapeAnalysis_Edge sae;
158 if (!aMapVertEdge1.Contains(VS1))
159 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
160 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
161 //TopoDS_Shape E1next;
162 TopTools_ListIteratorOfListOfShape anIter1(aList1);
163 if (anIter1.Value().IsSame(ES1)) {
166 //E1next = anIter1.Value();
167 if (!aMapVertEdge2.Contains(VS2))
168 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
169 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
170 //TopoDS_Shape E2next;
171 TopTools_ListIteratorOfListOfShape anIter2(aList2);
172 if (anIter2.Value().IsSame(ES2)) {
175 //E2next = anIter2.Value();
176 //ES1 = TopoDS::Edge(E1next);
177 //ES2 = TopoDS::Edge(E2next);
178 ES1 = TopoDS::Edge(anIter1.Value());
179 ES2 = TopoDS::Edge(anIter2.Value());
180 if (!FF.Contains(ES1)) {
183 if (VS1.IsSame(sae.FirstVertex(ES1)))
184 VS1 = sae.LastVertex(ES1);
186 VS1 = sae.FirstVertex(ES1);
187 if (VS2.IsSame(sae.FirstVertex(ES2)))
188 VS2 = sae.LastVertex(ES2);
190 VS2 = sae.FirstVertex(ES2);
193 if (!FF.Contains(VS1)) {
201 //=======================================================================
202 //function : FillCorrespondingEdges
203 //purpose : auxilary for CreatePipeForShellSections()
204 //=======================================================================
205 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
206 const TopoDS_Shape& FS2,
207 const TopoDS_Vertex& aLoc1,
208 const TopoDS_Vertex& aLoc2,
209 const TopoDS_Wire& aWirePath,
210 TopTools_IndexedDataMapOfShapeShape& FF)
212 //cout<<"FillCorrespondingEdges"<<endl;
213 // find corresponding edges
214 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
215 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
216 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
217 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
218 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
219 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
220 aBuilder.Add(aWire1, aLoc1);
221 aBuilder.Add(aWire2, aLoc2);
222 if (!aBuilder.IsReady()) {
226 TopoDS_Shape aShape = aBuilder.Shape();
234 BRepTools::Write(C,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
236 ShapeAnalysis_Edge sae;
237 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
238 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
239 TopTools_MapOfShape Vs1,Vs2;
241 exp.Init(FS1, TopAbs_EDGE);
242 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
243 TopoDS_Vertex V11 = sae.FirstVertex(E1);
244 TopoDS_Vertex V21 = sae.LastVertex(E1);
245 gp_Pnt P11 = BRep_Tool::Pnt(V11);
246 gp_Pnt P21 = BRep_Tool::Pnt(V21);
247 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
248 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
249 // find corresponding vertexes from created shape
250 TopoDS_Vertex VN11,VN21;
251 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
252 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
253 gp_Pnt P = BRep_Tool::Pnt(V);
254 if (P.Distance(P11)<tol) {
257 if (P.Distance(P21)<tol) {
261 // find edge contains VN11 and VN21 and corresponding vertexes
262 TopoDS_Vertex VN12,VN22;
263 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
264 TopoDS_Shape F = exp.Current();
265 TopExp_Explorer expe;
267 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
268 TopoDS_Edge E = TopoDS::Edge(expe.Current());
269 TopoDS_Vertex VF = sae.FirstVertex(E);
270 TopoDS_Vertex VL = sae.LastVertex(E);
271 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
277 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
278 TopoDS_Edge E = TopoDS::Edge(expe.Current());
279 TopoDS_Vertex VF = sae.FirstVertex(E);
280 TopoDS_Vertex VL = sae.LastVertex(E);
281 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
283 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
285 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
287 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
293 // find vertexes from FS2 corresponded to VN12 and VN22
294 // and find edge from FS2 contains V12 and V22,
295 // this edge will be corresponded to edge E1
296 TopoDS_Vertex V12,V22;
297 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
298 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
299 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
300 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
302 TopExp_Explorer expe;
303 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
304 TopoDS_Edge E = TopoDS::Edge(expe.Current());
305 TopoDS_Vertex VF = sae.FirstVertex(E);
306 TopoDS_Vertex VL = sae.LastVertex(E);
307 gp_Pnt PF = BRep_Tool::Pnt(VF);
308 gp_Pnt PL = BRep_Tool::Pnt(VL);
309 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
315 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
326 // find other pairs for vertexes and edges
327 // creating map of vertex edges for both faces
328 return FillForOtherEdges(FS1,E1,V21,FF);
333 //=======================================================================
334 //function : FillCorrespondingEdges
335 //purpose : auxilary for CreatePipeShellsWithoutPath()
336 //=======================================================================
337 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
338 const TopoDS_Shape& FS2,
339 const TopoDS_Vertex& aLoc1,
340 const TopoDS_Vertex& aLoc2,
341 TopTools_IndexedDataMapOfShapeShape& FF)
343 //cout<<"FillCorrespondingEdges"<<endl;
345 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
346 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
349 ShapeAnalysis_Edge sae;
350 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
351 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
352 TopTools_MapOfShape Vs1,Vs2;
354 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
357 TopExp_Explorer exp1;
358 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
359 E1 = TopoDS::Edge(exp1.Current());
360 TopoDS_Vertex V1 = sae.FirstVertex(E1);
361 TopoDS_Vertex V2 = sae.LastVertex(E1);
362 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
363 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
364 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
365 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
366 if (P1.Distance(Ptmp1)<tol) {
370 if (P1.Distance(Ptmp2)<tol) {
377 TopoDS_Vertex VE21,VE22;
379 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
380 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
381 TopoDS_Vertex V1 = sae.FirstVertex(E);
382 TopoDS_Vertex V2 = sae.LastVertex(E);
383 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
384 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
385 if (P2.Distance(Ptmp1)<tol) {
397 if (P2.Distance(Ptmp2)<tol) {
411 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
412 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
413 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
414 gp_Vec aDir1(PV21,PE21);
415 gp_Vec aDir2(PV21,PE22);
416 double ang1 = aDir.Angle(aDir1);
417 double ang2 = aDir.Angle(aDir2);
418 if (fabs(ang1)<fabs(ang2)) {
431 // find other pairs for vertexes and edges
432 return FillForOtherEdges(FS1,E1,V21,FF);
435 //=======================================================================
436 //function : FindNextPairOfFaces
437 //purpose : auxilary for CreatePipeForShellSections()
438 //=======================================================================
439 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
440 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
441 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
442 TopTools_IndexedDataMapOfShapeShape& FF,
445 //cout<<"FindNextPairOfFaces"<<endl;
446 TopExp_Explorer anExp;
447 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
448 TopoDS_Shape E1 = anExp.Current();
449 if (!FF.Contains(E1)) {
451 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
453 if (!FF.Contains(E1))
454 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
455 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
456 TopExp_Explorer anExpV;
457 anExpV.Init(E1, TopAbs_VERTEX);
458 TopoDS_Shape V1 = anExpV.Current();
459 if (!FF.Contains(V1)) {
461 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
464 if (!aMapEdgeFaces1.Contains(E1))
465 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
466 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
467 if (aList1.Extent()<2)
469 TopTools_ListIteratorOfListOfShape anIter(aList1);
470 if (anIter.Value().IsEqual(aCurFace)) {
473 TopoDS_Shape F1other = anIter.Value();
474 if (FF.Contains(F1other))
477 if (!FF.Contains(aCurFace))
478 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
479 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
480 if (!aMapEdgeFaces2.Contains(E2))
481 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
482 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
483 if (aList2.Extent()<2) {
485 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
487 TopTools_ListIteratorOfListOfShape anIter2(aList2);
488 if (anIter2.Value().IsEqual(F2)) {
491 TopoDS_Shape F2other = anIter2.Value();
492 FF.Add(F1other,F2other);
494 // add pairs of edges to FF
495 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
498 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
501 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
505 //=======================================================================
506 //function : FindFirstPairFaces
507 //purpose : auxilary for Execute()
508 //=======================================================================
509 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
510 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
511 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
513 //cout<<"FindFirstPairFaces"<<endl;
515 // check if vertexes are sub-shapes of sections
516 gp_Pnt P1 = BRep_Tool::Pnt(V1);
517 gp_Pnt P2 = BRep_Tool::Pnt(V2);
518 TopoDS_Vertex V1new,V2new;
520 double mindist = 1.e10;
521 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
522 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
523 gp_Pnt P = BRep_Tool::Pnt(V);
524 double dist = P1.Distance(P);
531 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
532 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
533 gp_Pnt P = BRep_Tool::Pnt(V);
534 double dist = P2.Distance(P);
541 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
542 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
543 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
544 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
545 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
546 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
548 // replace vertexes if it is needed
549 if (!V1.IsSame(V1new)) {
551 P1 = BRep_Tool::Pnt(V1);
552 MESSAGE (" replace V1");
555 MESSAGE (" not replace V1");
556 if (!V2.IsSame(V2new)) {
558 P2 = BRep_Tool::Pnt(V2);
559 MESSAGE (" replace V2");
562 MESSAGE (" not replace V2");
564 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
565 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
566 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
567 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
569 if (!aMapVertFaces1.Contains(V1))
570 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
571 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
572 TopTools_ListIteratorOfListOfShape anIter1(aList1);
573 FS1 = anIter1.Value();
575 double x1=0., y1=0., z1=0.;
577 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
578 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
579 gp_Pnt P = BRep_Tool::Pnt(V);
585 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
587 TColgp_SequenceOfPnt Ps;
588 TopTools_SequenceOfShape Fs;
589 if (!aMapVertFaces2.Contains(V2))
590 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
591 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
592 TopTools_ListIteratorOfListOfShape anIter2(aList2);
593 for (; anIter2.More(); anIter2.Next()) {
594 TopoDS_Shape F = anIter2.Value();
595 double x2=0., y2=0., z2=0.;
597 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
598 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
599 gp_Pnt P = BRep_Tool::Pnt(V);
605 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
612 double MinAng = M_PI;
614 for (; i<=Fs.Length(); i++) {
615 gp_Vec tmpDir(PM1,Ps(i));
616 double ang = fabs(aDir.Angle(tmpDir));
625 //=======================================================================
626 //function : CreatePipeWithDifferentSections
628 //=======================================================================
629 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
630 (const TopoDS_Wire& theWirePath,
631 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
632 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
633 const Standard_Boolean theWithContact,
634 const Standard_Boolean theWithCorrect)
638 TopoDS_Wire aWirePath = theWirePath;
640 Standard_Integer nbBases = theHSeqBases->Length();
641 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
643 if (nbLocs && nbLocs != nbBases) {
644 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
647 TopTools_SequenceOfShape aSeqBases;
648 TopTools_SequenceOfShape aSeqLocs;
649 TopTools_SequenceOfShape aSeqFaces;
651 Standard_Integer i = 1;
652 for (i = 1; i <= nbBases; i++) {
653 if (theHSeqBases->Value(i).IsNull())
656 // Make copy to prevent modifying of base object 0020766 : EDF 1320
657 TopoDS_Shape aShapeBase;
658 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
660 aShapeBase = Copy.Shape();
662 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
664 //if for section was specified face with a few wires then a few
665 // pipes were build and make solid
666 Standard_Boolean NeedCreateSolid = Standard_False;
667 if (aTypeBase == TopAbs_SHELL) {
668 // create wire as boundary contour if shell is no closed
669 // get free boundary shapes
670 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
671 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
672 TopExp_Explorer anExp;
674 Standard_Integer NbWires = 0;
675 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
677 aWire = anExp.Current();
681 Standard_ConstructionError::Raise("Bad shell is used as section ");
683 NeedCreateSolid = Standard_True;
684 aSeqFaces.Append(aShapeBase);
685 aSeqBases.Append(aWire);
687 else if (aTypeBase == TopAbs_FACE) {
688 NeedCreateSolid = Standard_True;
689 //for case one path should be used other type function
690 aSeqFaces.Append(aShapeBase);
691 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
692 for (; aExpW.More(); aExpW.Next()) {
693 TopoDS_Shape aWireProf = aExpW.Current();
694 aSeqBases.Append(aWireProf);
697 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
698 aSeqBases.Append(aShapeBase);
700 else if (aTypeBase == TopAbs_EDGE) {
701 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
702 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
703 aSeqBases.Append(aWireProf);
706 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
707 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
709 aSeqLocs.Append(aShapeLoc);
713 nbLocs = aSeqLocs.Length();
716 TopTools_SequenceOfShape Edges;
718 // we have to check that each location shape is a vertex from
719 // path and update aSeqLocs if it is needed (and possible)
720 TColgp_SequenceOfPnt PLocs;
721 for (i=1; i<=nbLocs; i++) {
722 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
723 PLocs.Append(BRep_Tool::Pnt(V));
725 //TopTools_SequenceOfShape Edges;
726 TopExp_Explorer anExp;
727 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
728 Edges.Append(anExp.Current());
730 int nbEdges = Edges.Length();
731 ShapeAnalysis_Edge sae;
732 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
733 double tol = BRep_Tool::Tolerance(edge);
734 TopoDS_Vertex VF = sae.FirstVertex(edge);
735 gp_Pnt PF = BRep_Tool::Pnt(VF);
736 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
737 if (PF.Distance(PLocs.First()) > tol) {
738 Standard_ConstructionError::Raise
739 ("First location shapes is not coincided with first vertex of aWirePath");
741 aSeqLocs.ChangeValue(1) = VF;
742 edge = TopoDS::Edge(Edges.Last());
743 tol = BRep_Tool::Tolerance(edge);
744 TopoDS_Vertex VL = sae.LastVertex(edge);
745 gp_Pnt PL = BRep_Tool::Pnt(VL);
746 if (PL.Distance(PLocs.Last()) > tol) {
747 Standard_ConstructionError::Raise
748 ("Last location shapes is not coincided with last vertex of aWirePath");
750 aSeqLocs.ChangeValue(nbLocs) = VL;
752 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
753 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
754 tol = BRep_Tool::Tolerance(edge);
755 TopoDS_Vertex V1 = sae.FirstVertex(E);
756 TopoDS_Vertex V2 = sae.LastVertex(E);
757 gp_Pnt P1 = BRep_Tool::Pnt(V1);
758 gp_Pnt P2 = BRep_Tool::Pnt(V2);
759 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
760 aSeqLocs.ChangeValue(jcurr) = V2;
764 // find distance between E and aLocs(jcurr)
766 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
767 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
768 if (PPCurve.NbPoints()>0 &&
769 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
770 double param = PPCurve.Parameter(1);
773 // split current edge
774 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
775 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
780 if (Pfp.Distance(P1)<tol) {
781 B.MakeEdge(E1,tc1,tol);
783 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
784 B.Add(E1,TopoDS::Vertex(tmpV));
785 B.MakeEdge(E2,tc2,tol);
786 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
787 B.Add(E2,TopoDS::Vertex(tmpV));
791 B.MakeEdge(E1,tc2,tol);
792 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
793 B.Add(E1,TopoDS::Vertex(tmpV));
796 B.MakeEdge(E2,tc1,tol);
798 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
799 B.Add(E2,TopoDS::Vertex(tmpV));
804 Edges.InsertAfter(i-1,E1);
805 Edges.InsertAfter(i,E2);
809 if (nbEdges<Edges.Length()) {
810 // one of edges was splitted => we have to update WirePath
814 for (i=1; i<=Edges.Length(); i++) {
815 B.Add(W,TopoDS::Edge(Edges.Value(i)));
821 // check curvature of wire for condition that
822 // max summary angle between directions along
823 // wire path must be < 4*PI. If not - split wire
824 // and seguences of shapes, perform pipe for each
825 // and make sewing after that
827 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
832 double SumAng = fabs(Vec1.Angle(Vec2));
835 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
837 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
838 for (i=2; i<=Edges.Length(); i++) {
839 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
840 double tol = BRep_Tool::Tolerance(edge);
841 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
843 double ang = fabs(Vec1.Angle(Vec2));
847 SplitEdgeNums.Append(i-1);
849 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
850 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
851 gp_Pnt P = BRep_Tool::Pnt(aVert);
852 if (P1.Distance(P) < tol) {
853 SplitLocNums.Append(j);
863 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
864 TopTools_SequenceOfShape aSeqRes;
865 int nn, num1 = 1, num2 = 1;
866 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
867 // create wirepath and sequences of shapes
871 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
872 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
874 num1 = SplitEdgeNums.Value(nn) + 1;
875 TopTools_SequenceOfShape aTmpSeqBases;
876 TopTools_SequenceOfShape aTmpSeqLocs;
877 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
878 aTmpSeqBases.Append(aSeqBases.Value(i));
879 aTmpSeqLocs.Append(aSeqLocs.Value(i));
881 num2 = SplitLocNums.Value(nn);
883 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
884 Standard_Integer nbShapes = aTmpSeqBases.Length();
885 for (i=1; i<=nbShapes; i++) {
886 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
887 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
888 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
890 if (!aBuilder.IsReady()) {
891 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
894 TopoDS_Shape resShape = aBuilder.Shape();
895 aSeqRes.Append(resShape);
897 // create wirepath and sequences of shapes for last part
901 for (i=num1; i<=Edges.Length(); i++) {
902 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
904 TopTools_SequenceOfShape aTmpSeqBases;
905 TopTools_SequenceOfShape aTmpSeqLocs;
906 for (i=num2; i<=aSeqLocs.Length(); i++) {
907 aTmpSeqBases.Append(aSeqBases.Value(i));
908 aTmpSeqLocs.Append(aSeqLocs.Value(i));
910 // make pipe for last part
911 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
912 Standard_Integer nbShapes = aTmpSeqBases.Length();
913 for (i=1; i<=nbShapes; i++) {
914 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
915 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
916 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
918 if (!aBuilder.IsReady()) {
919 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
922 TopoDS_Shape resShape = aBuilder.Shape();
923 aSeqRes.Append(resShape);
924 // make sewing for result
925 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
926 aSewing->SetTolerance(Precision::Confusion());
927 aSewing->SetFaceMode(Standard_True);
928 aSewing->SetFloatingEdgesMode(Standard_False);
929 aSewing->SetNonManifoldMode(Standard_False);
930 for (i=1; i<=aSeqRes.Length(); i++) {
931 aSewing->Add(aSeqRes.Value(i));
934 aShape = aSewing->SewedShape();
937 // old implementation without splitting
938 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
940 Standard_Integer nbShapes = aSeqBases.Length();
941 Standard_Integer step = nbShapes/nbBases;
943 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
944 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
946 Standard_Integer ind =0;
947 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
948 TopTools_SequenceOfShape usedBases;
949 Standard_Integer j = 1;
950 for (; j <= nbBases; j++) {
951 ind = i + (j-1)*step;
952 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
953 usedBases.Append(aWireProf);
955 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
956 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
957 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
960 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
962 if (!aBuilder.IsReady()) {
963 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
966 aShape = aBuilder.Shape();
967 aSeqFaces.Append(aShape);
968 for (j = 1; j <=usedBases.Length(); j++)
969 aBuilder.Delete(usedBases.Value(j));
972 //for case if section is face
973 if (aSeqFaces.Length() >1) {
975 TopoDS_Compound aComp;
976 aB.MakeCompound(aComp);
977 for (i = 1; i <= aSeqFaces.Length(); i++)
978 aB.Add(aComp,aSeqFaces.Value(i));
986 //=======================================================================
987 //function : CreatePipeForShellSections
988 //purpose : auxilary for Execute()
989 //=======================================================================
990 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
993 //cout<<"CreatePipeForShellSections"<<endl;
998 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
999 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1000 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1001 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1002 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1003 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1005 Standard_Integer nbBases = aBasesObjs->Length(),
1006 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1007 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1009 if (nbLocs != nbBases) {
1010 if (aCI) delete aCI;
1011 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1013 if (nbSubBases && nbSubBases != nbBases) {
1014 if (aCI) delete aCI;
1015 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1018 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1020 TopTools_SequenceOfShape VLocs;
1021 for (i=1; i<=nbBases; i++) {
1022 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1023 if (anItemLoc.IsNull())
1025 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1026 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1027 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1029 VLocs.Append(aShapeLoc);
1031 nbLocs = VLocs.Length();
1032 if (nbLocs != nbBases) {
1033 if (aCI) delete aCI;
1034 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1036 // split wire path by location points
1037 TColgp_SequenceOfPnt PLocs;
1038 for (i=1; i<=nbLocs; i++) {
1039 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1040 PLocs.Append(BRep_Tool::Pnt(V));
1043 TopTools_SequenceOfShape Edges;
1044 TopTools_SequenceOfShape Wires;
1045 ShapeAnalysis_Edge sae;
1048 TopExp_Explorer anExp;
1049 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1050 Edges.Append(anExp.Current());
1052 Standard_Integer Num1 = 0;
1053 Standard_Integer Num2 = 0;
1054 for (i=1; i<=Edges.Length(); i++) {
1055 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1056 double tol = BRep_Tool::Tolerance(E);
1057 TopoDS_Vertex V1 = sae.FirstVertex(E);
1058 TopoDS_Vertex V2 = sae.LastVertex(E);
1059 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1060 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1061 if (P1.Distance(PLocs.First()) < tol) {
1064 if (P2.Distance(PLocs.Last()) < tol) {
1068 if (Num1>0 && Num2>0) {
1071 for (i=Num1; i<=Num2; i++) {
1072 B.Add(W,Edges.Value(i));
1077 Wires.Append(aWirePath);
1081 TopExp_Explorer anExp;
1082 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1083 Edges.Append(anExp.Current());
1085 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1086 double tol = BRep_Tool::Tolerance(edge);
1087 TopoDS_Vertex VF = sae.FirstVertex(edge);
1088 gp_Pnt PF = BRep_Tool::Pnt(VF);
1089 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1090 if (PF.Distance(PLocs.First()) > tol) {
1091 if (aCI) delete aCI;
1092 Standard_ConstructionError::Raise
1093 ("First location shapes is not coincided with first vertex of aWirePath");
1095 VLocs.ChangeValue(1) = VF;
1096 edge = TopoDS::Edge(Edges.Last());
1097 tol = BRep_Tool::Tolerance(edge);
1098 TopoDS_Vertex VL = sae.LastVertex(edge);
1099 gp_Pnt PL = BRep_Tool::Pnt(VL);
1100 if (PL.Distance(PLocs.Last()) > tol) {
1101 if (aCI) delete aCI;
1102 Standard_ConstructionError::Raise
1103 ("Last location shapes is not coincided with last vertex of aWirePath");
1105 VLocs.ChangeValue(nbLocs) = VL;
1107 TopTools_SequenceOfShape tmpEdges;
1108 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1109 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1110 tol = BRep_Tool::Tolerance(E);
1111 TopoDS_Vertex V1 = sae.FirstVertex(E);
1112 TopoDS_Vertex V2 = sae.LastVertex(E);
1113 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1114 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1115 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1116 // make wire from current edge and add created
1120 for (j=1; j<=tmpEdges.Length(); j++)
1121 B.Add(W,tmpEdges.Value(j));
1124 VLocs.ChangeValue(jcurr) = V2;
1129 // find distance between E and aLocs(jcurr)
1131 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1132 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1133 if (PPCurve.NbPoints()>0 &&
1134 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1135 double param = PPCurve.Parameter(1);
1138 // split current edge
1139 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1140 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1144 if (Pfp.Distance(P1)<tol) {
1145 B.MakeEdge(E1,tc1,tol);
1147 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1148 B.Add(E1,TopoDS::Vertex(tmpV));
1149 tmpEdges.Append(E1);
1150 B.MakeEdge(E2,tc2,tol);
1151 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1152 B.Add(E2,TopoDS::Vertex(tmpV));
1156 B.MakeEdge(E1,tc2,tol);
1157 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1158 B.Add(E1,TopoDS::Vertex(tmpV));
1161 tmpEdges.Append(E1);
1162 B.MakeEdge(E2,tc1,tol);
1164 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1165 B.Add(E2,TopoDS::Vertex(tmpV));
1168 // create wire from tmpEdges
1171 for (j=1; j<=tmpEdges.Length(); j++)
1172 B.Add(W,tmpEdges.Value(j));
1177 Edges.InsertAfter(i-1,E1);
1178 Edges.InsertAfter(i,E2);
1185 // create wire from other edges
1188 for (; i<=Edges.Length(); i++)
1189 B.Add(W,Edges.Value(i));
1191 //cout<<"Wires.Length()="<<Wires.Length()<<endl;
1194 if (Wires.Length() != nbLocs-1) {
1195 if (aCI) delete aCI;
1196 Standard_ConstructionError::Raise
1197 ("One of location shapes is not lied on the path");
1200 //TopTools_SequenceOfShape aSeqBases;
1201 //TopTools_SequenceOfShape aSeqSubBases;
1202 //TopTools_SequenceOfShape aSeqFaces;
1203 TopoDS_Compound aComp;
1204 B.MakeCompound(aComp);
1205 for (i = 1; i < nbBases; i++) {
1206 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1208 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1209 if (anItem1.IsNull())
1211 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1212 if (aRefBase1.IsNull())
1214 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1215 if (aShBase1.IsNull())
1217 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1219 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1220 if (anItem2.IsNull())
1222 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1223 if (aRefBase2.IsNull())
1225 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1226 if (aShBase2.IsNull())
1228 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1230 //BRepTools::Write(aShBase1,"/dn02/users_Linux/skl/work/Bugs/14857/base1.brep");
1232 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1233 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1235 if (aCI) delete aCI;
1236 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1239 bool CreateFewSolids = false;
1241 TopExp_Explorer anExp;
1242 Standard_Integer nbf1 = 0;
1243 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1246 Standard_Integer nbf2 = 0;
1247 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1251 CreateFewSolids = true;
1255 // check orientation of sections
1256 bool NeedReverse = false;
1259 anExp.Init(aShBase1, TopAbs_FACE);
1260 TopoDS_Shape aFace = anExp.Current();
1261 TColgp_SequenceOfPnt aPnts;
1262 double xc=0, yc=0, zc=0;
1263 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1264 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1265 aPnts.Append(BRep_Tool::Pnt(V));
1266 xc += aPnts.Last().X();
1267 yc += aPnts.Last().Y();
1268 zc += aPnts.Last().Z();
1270 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1271 gp_Vec V1(PC,aPnts.Value(1));
1272 gp_Vec V2(PC,aPnts.Value(2));
1273 gp_Vec VN = V1.Crossed(V2);
1274 for (int ip=2; ip<aPnts.Length(); ip++) {
1275 V1 = gp_Vec(PC,aPnts.Value(ip));
1276 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1277 VN.Add(V1.Crossed(V2));
1280 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i)));
1282 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1283 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1284 double tol = BRep_Tool::Tolerance(edge);
1285 TopoDS_Vertex VF = sae.FirstVertex(edge);
1286 gp_Pnt PF = BRep_Tool::Pnt(VF);
1287 if (PF.Distance(PLoc) < tol) {
1289 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1292 if (P1.Distance(PLoc) < tol) {
1293 C->D0(fp+(lp-fp)/100,P2);
1297 C->D0(lp+(fp-lp)/100,P2);
1299 PathNorm = gp_Vec(P1,P2);
1303 TopoDS_Vertex VL = sae.LastVertex(edge);
1304 gp_Pnt PL = BRep_Tool::Pnt(VL);
1305 if (PL.Distance(PLoc) < tol) {
1307 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1310 if (P1.Distance(PLoc) < tol) {
1311 C->D0(fp+(lp-fp)/100,P2);
1315 C->D0(lp+(fp-lp)/100,P2);
1317 PathNorm = gp_Vec(P2,P1);
1322 cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1323 cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1324 if (fabs(VN.Angle(PathNorm))>PI/2.) {
1331 anExp.Init(aShBase2, TopAbs_FACE);
1332 TopoDS_Shape aFace = anExp.Current();
1333 TColgp_SequenceOfPnt aPnts;
1334 double xc=0, yc=0, zc=0;
1335 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1336 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1337 aPnts.Append(BRep_Tool::Pnt(V));
1338 xc += aPnts.Last().X();
1339 yc += aPnts.Last().Y();
1340 zc += aPnts.Last().Z();
1342 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1343 gp_Vec V1(PC,aPnts.Value(1));
1344 gp_Vec V2(PC,aPnts.Value(2));
1345 gp_Vec VN = V1.Crossed(V2);
1346 for (int ip=2; ip<aPnts.Length(); ip++) {
1347 V1 = gp_Vec(PC,aPnts.Value(ip));
1348 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1349 VN.Add(V1.Crossed(V2));
1352 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i+1)));
1354 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1355 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1356 double tol = BRep_Tool::Tolerance(edge);
1357 TopoDS_Vertex VF = sae.FirstVertex(edge);
1358 gp_Pnt PF = BRep_Tool::Pnt(VF);
1359 if (PF.Distance(PLoc) < tol) {
1361 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1364 if (P1.Distance(PLoc) < tol) {
1365 C->D0(fp+(lp-fp)/100,P2);
1369 C->D0(lp+(fp-lp)/100,P2);
1371 PathNorm = gp_Vec(P2,P1);
1375 TopoDS_Vertex VL = sae.LastVertex(edge);
1376 gp_Pnt PL = BRep_Tool::Pnt(VL);
1377 if (PL.Distance(PLoc) < tol) {
1379 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1382 if (P1.Distance(PLoc) < tol) {
1383 C->D0(fp+(lp-fp)/100,P2);
1387 C->D0(lp+(fp-lp)/100,P2);
1389 PathNorm = gp_Vec(P2,P1);
1394 //cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1395 //cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1396 if (fabs(VN.Angle(PathNorm))>PI/2.)
1401 if (!CreateFewSolids) {
1402 // we can create only one solid
1403 TopoDS_Shape aWire1, aWire2;
1405 if (aType1==TopAbs_SHELL) {
1406 // create wire as boundary contour if shell is no closed
1407 // get free boundary shapes
1408 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1409 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1410 //TopExp_Explorer anExp;
1411 Standard_Integer NbWires = 0;
1412 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1414 aWire1 = anExp.Current();
1418 if (aCI) delete aCI;
1419 Standard_ConstructionError::Raise("Bad shell is used as section ");
1422 else { // aType1==TopAbs_FACE
1423 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1424 aWire1 = aExpW.Current();
1427 if (aType2==TopAbs_SHELL) {
1428 // create wire as boundary contour if shell is no closed
1429 // get free boundary shapes
1430 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1431 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1432 //TopExp_Explorer anExp;
1433 Standard_Integer NbWires = 0;
1434 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1436 aWire2 = anExp.Current();
1440 if (aCI) delete aCI;
1441 Standard_ConstructionError::Raise("Bad shell is used as section ");
1444 else { // aType2==TopAbs_FACE
1445 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1446 aWire2 = aExpW.Current();
1448 // make pipe using aWire1 and aWire2
1449 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1450 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1451 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1452 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1453 aWithContact, aWithCorrect);
1454 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1455 aWithContact, aWithCorrect);
1456 if (!aBuilder.IsReady()) {
1457 if (aCI) delete aCI;
1458 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1461 TopoDS_Shape aShape = aBuilder.Shape();
1462 TopoDS_Shell aShell;
1463 B.MakeShell(aShell);
1464 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1465 B.Add(aShell,anExp.Current());
1467 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1468 B.Add(aShell,anExp.Current());
1470 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1471 B.Add(aShell,anExp.Current());
1473 // make sewing for this shell
1474 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1475 aSewing->SetTolerance(Precision::Confusion());
1476 aSewing->SetFaceMode(Standard_True);
1477 aSewing->SetFloatingEdgesMode(Standard_False);
1478 aSewing->SetNonManifoldMode(Standard_False);
1479 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1480 aSewing->Add(anExp.Current());
1483 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1484 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1485 aShell = TopoDS::Shell(aSewShape);
1486 GProp_GProps aSystem;
1487 BRepGProp::VolumeProperties(aShell, aSystem);
1488 if (aSystem.Mass()<0) {
1491 if (BRep_Tool::IsClosed(aShell)) {
1492 TopoDS_Solid aSolid;
1493 B.MakeSolid(aSolid);
1494 B.Add(aSolid,aShell);
1495 B.Add(aComp,aSolid);
1498 B.Add(aComp,aShell);
1502 B.Add(aComp,aShell);
1507 // main block - creation few solids (for each pair of faces)
1508 TopTools_MapOfShape aFaces1,aFaces2;
1509 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1510 aFaces1.Add(anExp.Current());
1512 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1513 aFaces2.Add(anExp.Current());
1515 // creating map of edge faces
1516 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1517 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1518 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1519 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1521 // constuct map face->face
1522 TopTools_IndexedDataMapOfShapeShape FF;
1523 TopoDS_Shape FS1,FS2;
1524 if (nbSubBases==0) {
1525 // find edge the most distant from location point
1526 // (this edge is not shared by two faces)
1527 double maxdist = 0.;
1529 TopoDS_Vertex V11,V21;
1530 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1531 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1532 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1533 if (aList.Extent()>1)
1535 TopExp_Explorer expv;
1536 expv.Init(tmp, TopAbs_VERTEX);
1537 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1539 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1540 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1541 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1542 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1547 TopTools_ListIteratorOfListOfShape anIter(aList);
1548 FS1 = anIter.Value();
1552 // main direction for comparing
1553 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1554 // find corresponding edge from next section
1555 double minang = M_PI;
1556 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1557 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1559 TopoDS_Vertex V12,V22;
1560 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1561 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1562 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1563 if (aList.Extent()>1)
1565 TopExp_Explorer expv;
1566 expv.Init(tmp, TopAbs_VERTEX);
1567 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1569 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1570 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1571 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1572 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1573 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1574 TopoDS_Vertex V1,V2;
1577 V1 = V2tmp; P1 = P2tmp;
1578 V2 = V1tmp; P2 = P1tmp;
1581 V1 = V1tmp; P1 = P1tmp;
1582 V2 = V2tmp; P2 = P2tmp;
1584 gp_Vec Vec1(P11,P1);
1585 gp_Vec Vec2(P21,P2);
1586 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1591 TopTools_ListIteratorOfListOfShape anIter(aList);
1592 FS2 = anIter.Value();
1596 // put all pairs to map FF
1602 // add pairs of edges to FF
1603 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1605 if (aCI) delete aCI;
1606 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1612 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1613 if (anItem.IsNull()) {
1614 if (aCI) delete aCI;
1615 Standard_ConstructionError::Raise("Invalid subbase shape");
1617 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1618 if (aRefBase.IsNull()) {
1619 if (aCI) delete aCI;
1620 Standard_ConstructionError::Raise("Invalid subbase shape");
1622 TopoDS_Shape aSh = aRefBase->GetValue();
1624 if (aCI) delete aCI;
1625 Standard_ConstructionError::Raise("Invalid subbase shape");
1627 if (aSh.ShapeType()!=TopAbs_FACE) {
1628 if (aCI) delete aCI;
1629 Standard_ConstructionError::Raise("Invalid subbase shape");
1634 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1635 if (anItem.IsNull()) {
1636 if (aCI) delete aCI;
1637 Standard_ConstructionError::Raise("Invalid subbase shape");
1639 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1640 if (aRefBase.IsNull()) {
1641 if (aCI) delete aCI;
1642 Standard_ConstructionError::Raise("Invalid subbase shape");
1644 TopoDS_Shape aSh = aRefBase->GetValue();
1646 if (aCI) delete aCI;
1647 Standard_ConstructionError::Raise("Invalid subbase shape");
1649 if (aSh.ShapeType()!=TopAbs_FACE) {
1650 if (aCI) delete aCI;
1651 Standard_ConstructionError::Raise("Invalid subbase shape");
1656 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1657 if (aCI) delete aCI;
1658 Standard_ConstructionError::Raise("Invalid subbase shape");
1663 // add pairs of edges to FF
1664 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1665 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1667 if (aCI) delete aCI;
1668 Standard_ConstructionError::Raise("Can not create correct pipe");
1672 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1674 // make pipe for each pair of faces
1675 for (j=1; j<=FF.Extent(); j++) {
1676 TopoDS_Shape F1 = FF.FindKey(j);
1677 if (F1.ShapeType() != TopAbs_FACE)
1679 TopoDS_Shape F2 = FF.FindFromIndex(j);
1680 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1681 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1682 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1683 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1684 // make pipe using aWire1 and aWire2
1685 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1686 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1687 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1688 aWithContact, aWithCorrect);
1689 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1690 aWithContact, aWithCorrect);
1691 if (!aBuilder.IsReady()) {
1692 if (aCI) delete aCI;
1693 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1696 TopoDS_Shape aShape = aBuilder.Shape();
1697 TopoDS_Shell aShell;
1698 B.MakeShell(aShell);
1699 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1700 B.Add(aShell,anExp.Current());
1705 // make sewing for this shell
1706 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1707 aSewing->SetTolerance(Precision::Confusion());
1708 aSewing->SetFaceMode(Standard_True);
1709 aSewing->SetFloatingEdgesMode(Standard_False);
1710 aSewing->SetNonManifoldMode(Standard_False);
1711 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1712 aSewing->Add(anExp.Current());
1715 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1716 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1717 aShell = TopoDS::Shell(aSewShape);
1718 GProp_GProps aSystem;
1719 BRepGProp::VolumeProperties(aShell, aSystem);
1720 if (aSystem.Mass()<0) {
1721 //cout<<"aSewShape is reversed"<<endl;
1724 if (BRep_Tool::IsClosed(aShell)) {
1725 TopoDS_Solid aSolid;
1726 B.MakeSolid(aSolid);
1727 B.Add(aSolid,aShell);
1728 B.Add(aComp,aSolid);
1731 B.Add(aComp,aShell);
1735 B.Add(aComp,aShell);
1743 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
1747 //=======================================================================
1748 //function : CreatePipeShellsWithoutPath
1749 //purpose : auxilary for Execute()
1750 //=======================================================================
1751 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
1753 //cout<<"CreatePipeShellsWithoutPath"<<endl;
1757 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1759 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1760 // vertex for recognition
1761 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
1763 Standard_Integer nbBases = aBasesObjs->Length(),
1764 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
1766 if (nbv != nbBases) {
1767 if (aCI) delete aCI;
1768 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
1771 TopTools_SequenceOfShape SecVs,Bases;
1772 for (i=1; i<=nbBases; i++) {
1774 Handle(Standard_Transient) anItem = VObjs->Value(i);
1775 if (anItem.IsNull())
1777 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
1778 TopoDS_Shape V = aRef->GetValue();
1779 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
1783 anItem = aBasesObjs->Value(i);
1784 if (anItem.IsNull())
1786 aRef = Handle(GEOM_Function)::DownCast(anItem);
1787 TopoDS_Shape aSh = aRef->GetValue();
1792 nbv = SecVs.Length();
1793 nbBases = Bases.Length();
1794 if (nbv != nbBases) {
1795 if (aCI) delete aCI;
1796 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
1799 TopoDS_Compound aComp;
1800 B.MakeCompound(aComp);
1802 for (i = 1; i < nbBases; i++) {
1803 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
1804 TopoDS_Shape aShBase1 = Bases.Value(i);
1805 TopoDS_Shape aShBase2 = Bases.Value(i+1);
1806 TopExp_Explorer anExp;
1807 Standard_Integer nbf1 = 0;
1808 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1811 Standard_Integer nbf2 = 0;
1812 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1815 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
1817 if (aCI) delete aCI;
1818 Standard_ConstructionError::Raise("Different number of faces in the sections");
1821 TopTools_MapOfShape aFaces1,aFaces2;
1822 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1823 aFaces1.Add(anExp.Current());
1825 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1826 aFaces2.Add(anExp.Current());
1829 // creating map of edge faces
1830 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1831 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1832 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1833 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1835 // constuct map face->face (and sub-shapes)
1836 TopTools_IndexedDataMapOfShapeShape FF;
1837 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
1838 TopoDS_Shape FS1, FS2;
1839 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
1840 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
1841 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
1844 MESSAGE (" first pair of corresponding faces is found");
1846 // add pairs of edges and vertexes to FF
1847 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
1849 if (aCI) delete aCI;
1850 Standard_ConstructionError::Raise("Can not create correct pipe");
1852 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
1854 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1855 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
1857 // make pipe for each pair of faces
1858 // auxilary map vertex->edge for created pipe edges
1859 TopTools_IndexedDataMapOfShapeShape VPE;
1860 ShapeAnalysis_Edge sae;
1861 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
1863 for (j=1; j<=FF.Extent(); j++) {
1864 TopoDS_Shape F1 = FF.FindKey(j);
1865 if (F1.ShapeType() != TopAbs_FACE)
1867 TopoDS_Shape F2 = FF.FindFromIndex(j);
1870 //if (nbff!=3) continue;
1872 MESSAGE (" make pipe for "<<nbff<<" face");
1874 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
1875 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1876 Handle(Geom_RectangularTrimmedSurface) RTS =
1877 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
1878 S1 = RTS->BasisSurface();
1880 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
1881 if (Pln1.IsNull()) {
1882 if (aCI) delete aCI;
1883 Standard_ConstructionError::Raise("Surface from face is not plane");
1885 gp_Vec aDir1(Pln1->Axis().Direction());
1887 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
1888 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1889 Handle(Geom_RectangularTrimmedSurface) RTS =
1890 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
1891 S2 = RTS->BasisSurface();
1893 Handle(Geom_Plane) Pln2 =
1894 Handle(Geom_Plane)::DownCast(S2);
1895 if (Pln2.IsNull()) {
1896 if (aCI) delete aCI;
1897 Standard_ConstructionError::Raise("Surface from face is not plane");
1899 gp_Vec aDir2(Pln2->Axis().Direction());
1901 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
1902 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
1904 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
1906 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
1909 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
1910 TopTools_SequenceOfShape aNewFs;
1912 for (; anExpE.More(); anExpE.Next()) {
1913 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
1915 if (!FF.Contains(E1))
1916 MESSAGE ("map FF not contains key E1");
1918 if (VPE.Contains(E1)) {
1919 aNewFs.Append(VPE.FindFromKey(E1));
1921 MESSAGE (" using existed face");
1926 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
1927 TopoDS_Vertex V1 = sae.FirstVertex(E1);
1928 TopoDS_Vertex V2 = sae.LastVertex(E1);
1929 if (!FF.Contains(V1))
1930 MESSAGE ("map FF not contains key V1");
1931 if (!FF.Contains(V2))
1932 MESSAGE ("map FF not contains key V2");
1933 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
1934 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
1935 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
1936 if (Vtmp.IsSame(V4))
1938 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1939 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1940 gp_Pnt P3 = BRep_Tool::Pnt(V3);
1941 gp_Pnt P4 = BRep_Tool::Pnt(V4);
1944 Handle(Geom_BSplineCurve) C2;
1945 if (VPE.Contains(V2)) {
1946 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
1948 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
1951 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
1952 HAP->SetValue(1,P2);
1953 HAP->SetValue(2,P3);
1954 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
1955 anInt.Load(aDir1,aDir2);
1958 B.MakeEdge(E2,C2,1.e-7);
1959 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
1960 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
1965 Handle(Geom_BSplineCurve) C4;
1966 if (VPE.Contains(V1)) {
1967 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
1969 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
1972 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
1973 HAP->SetValue(1,P1);
1974 HAP->SetValue(2,P4);
1975 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
1976 anInt.Load(aDir1,aDir2);
1979 B.MakeEdge(E4,anInt.Curve(),1.e-7);
1980 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
1981 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
1990 B.Add(W,E4.Reversed());
1991 //cout<<" wire for edge "<<nbee<<" is created"<<endl;
1992 //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
1997 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
1998 //bool IsConicC1 = false;
1999 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2000 // IsConicC1 = true;
2001 // cout<<"C1 - Geom_Conic"<<endl;
2003 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2004 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2007 // double tol = BRep_Tool::Tolerance(E1);
2008 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2009 // C1 = ApxC1.Curve();
2011 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2012 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2013 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2018 Handle(Geom_BSplineCurve) CE1 =
2019 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2020 if (CE1->Degree()<3)
2021 CE1->IncreaseDegree(3);
2022 Handle(Geom_BSplineCurve) CE2 =
2023 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2024 if (CE2->Degree()<3)
2025 CE2->IncreaseDegree(3);
2026 Handle(Geom_BSplineCurve) CE3 =
2027 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2028 if (CE3->Degree()<3)
2029 CE3->IncreaseDegree(3);
2030 Handle(Geom_BSplineCurve) CE4 =
2031 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2032 if (CE4->Degree()<3)
2033 CE4->IncreaseDegree(3);
2034 //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
2035 // <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
2036 //if (fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
2037 // os<<"DrawTrSurf_BSplineCurve"<<endl;
2038 // GeomTools::Write(CE1,os);
2042 Handle(Geom_Surface) BS;
2044 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2045 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2049 MESSAGE (" can not create BSplineSurface - create Bezier");
2051 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2052 double fp1,lp1,fp2,lp2;
2053 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2054 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2063 // get points from C1
2064 if (P1.Distance(P1C1)<1.e-6) {
2072 double step = (lp-fp)/(NbP-1);
2073 Points.SetValue(1,1,P1);
2075 for (n1=2; n1<NbP; n1++) {
2079 Points.SetValue(1,n1,P);
2081 Points.SetValue(1,NbP,P2);
2082 // get points from C3
2083 if (P4.Distance(P1C3)<1.e-6) {
2091 step = (lp-fp)/(NbP-1);
2092 Points.SetValue(NbP,1,P4);
2094 for (n1=2; n1<NbP; n1++) {
2098 Points.SetValue(NbP,n1,P);
2100 Points.SetValue(NbP,NbP,P3);
2101 // create isolines and get points from them
2102 for (n1=1; n1<=NbP; n1++) {
2103 gp_Pnt PI1 = Points.Value(1,n1);
2104 gp_Pnt PI2 = Points.Value(NbP,n1);
2105 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2106 HAP->SetValue(1,PI1);
2107 HAP->SetValue(2,PI2);
2108 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2109 anInt.Load(aDir1,aDir2);
2111 Handle(Geom_Curve) iso = anInt.Curve();
2112 fp = iso->FirstParameter();
2113 lp = iso->LastParameter();
2114 step = (lp-fp)/(NbP-1);
2116 TopoDS_Compound VComp;
2117 B.MakeCompound(VComp);
2118 for (n2=2; n2<NbP; n2++) {
2122 Points.SetValue(n2,n1,P);
2125 // create surface and face
2126 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2127 BS = new Geom_BezierSurface(Points);
2130 BRepBuilderAPI_MakeFace BB(BS,W);
2131 TopoDS_Face NewF = BB.Face();
2132 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2134 sff->FixOrientation();
2135 TopoDS_Face FixedFace = sff->Face();
2136 aNewFs.Append(FixedFace);
2137 VPE.Add(E1,FixedFace);
2138 //cout<<" face for edge "<<nbee<<" is created"<<endl;
2139 //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
2142 TopoDS_Shell aShell;
2143 B.MakeShell(aShell);
2144 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2145 B.Add(aShell,aNewFs(nf));
2150 // make sewing for this shell
2151 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2152 aSewing->SetTolerance(Precision::Confusion());
2153 aSewing->SetFaceMode(Standard_True);
2154 aSewing->SetFloatingEdgesMode(Standard_False);
2155 aSewing->SetNonManifoldMode(Standard_False);
2156 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2157 aSewing->Add(anExp.Current());
2160 MESSAGE (" shell for face "<<nbff<<" is created");
2161 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2162 //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
2163 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2164 aShell = TopoDS::Shell(aSewShape);
2165 GProp_GProps aSystem;
2166 BRepGProp::VolumeProperties(aShell, aSystem);
2167 if (aSystem.Mass()<0) {
2168 //cout<<"aSewShape is reversed"<<endl;
2171 if (BRep_Tool::IsClosed(aShell)) {
2172 TopoDS_Solid aSolid;
2173 B.MakeSolid(aSolid);
2174 B.Add(aSolid,aShell);
2175 B.Add(aComp,aSolid);
2176 MESSAGE (" solid for face "<<nbff<<" is created");
2179 B.Add(aComp,aShell);
2180 MESSAGE (" solid for face "<<nbff<<" is not created");
2184 B.Add(aComp,aShell);
2185 MESSAGE (" solid for face "<<nbff<<" is not created");
2187 //cout<<" solid for face "<<nbff<<" is created"<<endl;
2189 //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
2191 //TopoDS_Shell FixedShell = sfs->Shell();
2193 GProp_GProps aSystem;
2194 BRepGProp::VolumeProperties(FixedShell, aSystem);
2195 if (aSystem.Mass()<0) {
2196 //cout<<"aSewShape is reversed"<<endl;
2197 FixedShell.Reverse();
2199 if (BRep_Tool::IsClosed(FixedShell)) {
2200 TopoDS_Solid aSolid;
2201 B.MakeSolid(aSolid);
2202 B.Add(aSolid,aShell);
2203 B.Add(aComp,aSolid);
2206 B.Add(aComp,FixedShell);
2212 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
2216 //=======================================================================
2217 //function : CreatePipeBiNormalAlongVector
2218 //purpose : auxilary for Execute()
2219 //=======================================================================
2220 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2221 GEOMImpl_IPipe* aCI)
2223 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2225 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2226 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2227 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2228 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2230 if (aShapeBase.IsNull()) {
2231 if (aCIBN) delete aCIBN;
2232 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2235 // Make copy to prevent modifying of base object: 0021525
2236 BRepBuilderAPI_Copy Copy (aShapeBase);
2238 aShapeBase = Copy.Shape();
2241 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2244 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2245 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2247 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2250 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2251 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2252 aProf = wexp.Current();
2255 Standard_TypeMismatch::Raise
2256 ("MakePipe aborted : invalid type of base");
2258 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2259 PipeBuilder.Add(aProf);
2261 if (aShapeVec.IsNull()) {
2262 if (aCIBN) delete aCIBN;
2263 Standard_NullObject::Raise
2264 ("MakePipe aborted : null vector argument");
2266 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2267 Standard_TypeMismatch::Raise
2268 ("MakePipe aborted: invalid type of vector");
2269 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2270 TopoDS_Vertex V1, V2;
2271 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2272 if (V1.IsNull() || V2.IsNull())
2273 Standard_NullObject::Raise
2274 ("MakePipe aborted: vector is not defined");
2275 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2276 gp_Dir BiNormal(aVec);
2277 PipeBuilder.SetMode(BiNormal);
2278 PipeBuilder.Build();
2279 if (aShapeBase.ShapeType() == TopAbs_FACE) {
2280 PipeBuilder.MakeSolid();
2283 return PipeBuilder.Shape();
2286 //=======================================================================
2287 //function : Execute
2289 //=======================================================================
2290 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
2292 if (Label().IsNull()) return 0;
2293 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
2294 Standard_Integer aType = aFunction->GetType();
2296 GEOMImpl_IPipe* aCI = 0;
2297 if (aType == PIPE_BASE_PATH)
2298 aCI = new GEOMImpl_IPipe (aFunction);
2299 else if (aType == PIPE_DIFFERENT_SECTIONS)
2300 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
2301 else if (aType == PIPE_SHELL_SECTIONS)
2302 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2303 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
2304 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2305 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
2306 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
2310 TopoDS_Wire aWirePath;
2311 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
2312 // working with path
2313 Handle(GEOM_Function) aRefPath = aCI->GetPath();
2314 TopoDS_Shape aShapePath = aRefPath->GetValue();
2316 if (aShapePath.IsNull()) {
2317 MESSAGE ("Driver : path is null");
2318 if (aCI) delete aCI;
2319 Standard_NullObject::Raise("MakePipe aborted : null path argument");
2324 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
2325 TopTools_SequenceOfShape anEdges;
2326 TopExp_Explorer anExp;
2330 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2331 B.Add(W, anExp.Current());
2337 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
2338 aWirePath = TopoDS::Wire(aShapePath);
2342 if (aShapePath.ShapeType() == TopAbs_EDGE) {
2343 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
2344 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
2349 if (aCI) delete aCI;
2350 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
2354 TopoDS_Shape aShape;
2356 if (aType == PIPE_BASE_PATH) {
2357 Handle(GEOM_Function) aRefBase = aCI->GetBase();
2358 TopoDS_Shape aShapeBase;
2360 // Make copy to prevent modifying of base object 0020766 : EDF 1320
2361 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
2363 aShapeBase = Copy.Shape();
2365 if (aShapeBase.IsNull()) {
2366 if (aCI) delete aCI;
2367 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2371 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
2372 aShapeBase.ShapeType() == TopAbs_WIRE)
2374 TopoDS_Wire Profile;
2375 if (aShapeBase.ShapeType() == TopAbs_WIRE)
2376 Profile = TopoDS::Wire(aShapeBase);
2380 BB.MakeWire(Profile);
2381 BB.Add(Profile, aShapeBase);
2384 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
2385 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
2386 if (FaceBuilder.IsDone())
2387 Sweep.SetMode(FaceBuilder.Face());
2391 if (!Sweep.IsDone())
2393 if (aCI) delete aCI;
2394 Standard_ConstructionError::Raise("MakePipeShell failed");
2397 aShape = Sweep.Shape(); //result is good
2401 aShape = BRepOffsetAPI_MakePipe(aWirePath, aShapeBase);
2404 //building pipe with different sections
2405 else if (aType == PIPE_DIFFERENT_SECTIONS) {
2406 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
2407 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
2408 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
2409 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
2410 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
2416 Standard_Integer nbBases = aBasesObjs->Length();
2417 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
2419 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
2420 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
2423 for (i = 1; i <= nbBases; i++) {
2424 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
2425 if (anItem.IsNull())
2427 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
2428 if (aRefBase.IsNull())
2430 if (aRefBase->GetValue().IsNull())
2433 aHSeqBases->Append(aRefBase->GetValue());
2435 for (i = 1; i <= nbLocs; i++) {
2436 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
2437 if (anItemLoc.IsNull())
2439 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
2440 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
2441 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
2444 aHSeqLocs->Append(aShapeLoc);
2447 aShape = CreatePipeWithDifferentSections(aWirePath, aHSeqBases, aHSeqLocs, aWithContact, aWithCorrect);
2450 //building pipe with shell sections
2451 else if (aType == PIPE_SHELL_SECTIONS) {
2452 aShape = CreatePipeForShellSections(aWirePath,aCI);
2455 //building pipe shell sections without path
2456 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
2457 aShape = CreatePipeShellsWithoutPath(aCI);
2460 //building a pipe with constant bi-normal along given vector
2461 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
2462 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
2470 if (aShape.IsNull()) return 0;
2472 BRepCheck_Analyzer ana (aShape, Standard_False);
2473 if (!ana.IsValid()) {
2474 ShapeFix_ShapeTolerance aSFT;
2475 aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion());
2476 Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
2477 aSfs->SetPrecision(Precision::Confusion());
2479 aShape = aSfs->Shape();
2481 ana.Init(aShape, Standard_False);
2483 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
2486 // Glue (for bug 0020207)
2487 // No gluing is needed as the bug 0020207 is fixed in OCCT.
2489 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
2490 if (anExpV.More()) {
2491 Standard_Real aVertMaxTol = -RealLast();
2492 for (; anExpV.More(); anExpV.Next()) {
2493 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
2494 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
2495 if (aTol > aVertMaxTol)
2498 aVertMaxTol += Precision::Confusion();
2499 aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
2500 //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
2504 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
2505 aFunction->SetValue(aRes);
2507 log.SetTouched(Label());
2511 //=======================================================================
2512 //function : GEOMImpl_PipeDriver_Type_
2514 //=======================================================================
2515 Standard_EXPORT Handle_Standard_Type& GEOMImpl_PipeDriver_Type_()
2517 static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
2518 if (aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
2519 static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
2520 if (aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
2521 static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
2522 if (aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
2524 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
2525 static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_PipeDriver",
2526 sizeof(GEOMImpl_PipeDriver),
2528 (Standard_Address)_Ancestors,
2529 (Standard_Address)NULL);
2534 //=======================================================================
2535 //function : DownCast
2537 //=======================================================================
2538 const Handle(GEOMImpl_PipeDriver) Handle(GEOMImpl_PipeDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
2540 Handle(GEOMImpl_PipeDriver) _anOtherObject;
2542 if (!AnObject.IsNull()) {
2543 if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_PipeDriver))) {
2544 _anOtherObject = Handle(GEOMImpl_PipeDriver)((Handle(GEOMImpl_PipeDriver)&)AnObject);
2548 return _anOtherObject;