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 <Standard_Stream.hxx>
24 #include <GEOMImpl_PipeDriver.hxx>
26 #include <GEOMImpl_IShapesOperations.hxx>
27 #include <GEOMImpl_IPipeDiffSect.hxx>
28 #include <GEOMImpl_IPipeShellSect.hxx>
29 #include <GEOMImpl_IPipeBiNormal.hxx>
30 #include <GEOMImpl_IPipe.hxx>
31 #include <GEOMImpl_IPipePath.hxx>
32 #include <GEOMImpl_GlueDriver.hxx>
33 #include <GEOMImpl_Types.hxx>
34 #include <GEOM_Function.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 //=======================================================================
103 //=======================================================================
104 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
106 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
110 //=======================================================================
111 //function : GEOMImpl_PipeDriver
113 //=======================================================================
114 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
118 //=======================================================================
119 //function : FillForOtherEdges
120 //purpose : auxilary for CreatePipeForShellSections()
121 //=======================================================================
122 static bool FillForOtherEdges(const TopoDS_Shape& F1,
123 const TopoDS_Shape& E1,
124 const TopoDS_Shape& V1,
125 TopTools_IndexedDataMapOfShapeShape& FF)
127 //cout<<"FillForOtherEdges"<<endl;
128 // find other pairs for vertexes and edges
129 // creating map of vertex edges for both faces
130 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
131 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
132 if (!FF.Contains(F1))
133 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
134 if (!FF.Contains(E1))
135 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
136 if (!FF.Contains(V1))
137 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
138 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
139 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
140 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
141 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
142 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
144 TopoDS_Edge ES1 = TopoDS::Edge(E1);
145 TopoDS_Edge ES2 = TopoDS::Edge(E2);
146 TopoDS_Shape VS1 = V1;
147 TopoDS_Shape VS2 = V2;
149 ShapeAnalysis_Edge sae;
151 if (!aMapVertEdge1.Contains(VS1))
152 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
153 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
154 //TopoDS_Shape E1next;
155 TopTools_ListIteratorOfListOfShape anIter1(aList1);
156 if (anIter1.Value().IsSame(ES1)) {
159 //E1next = anIter1.Value();
160 if (!aMapVertEdge2.Contains(VS2))
161 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
162 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
163 //TopoDS_Shape E2next;
164 TopTools_ListIteratorOfListOfShape anIter2(aList2);
165 if (anIter2.Value().IsSame(ES2)) {
168 //E2next = anIter2.Value();
169 //ES1 = TopoDS::Edge(E1next);
170 //ES2 = TopoDS::Edge(E2next);
171 ES1 = TopoDS::Edge(anIter1.Value());
172 ES2 = TopoDS::Edge(anIter2.Value());
173 if (!FF.Contains(ES1)) {
176 if (VS1.IsSame(sae.FirstVertex(ES1)))
177 VS1 = sae.LastVertex(ES1);
179 VS1 = sae.FirstVertex(ES1);
180 if (VS2.IsSame(sae.FirstVertex(ES2)))
181 VS2 = sae.LastVertex(ES2);
183 VS2 = sae.FirstVertex(ES2);
186 if (!FF.Contains(VS1)) {
194 //=======================================================================
195 //function : FillCorrespondingEdges
196 //purpose : auxilary for CreatePipeForShellSections()
197 //=======================================================================
198 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
199 const TopoDS_Shape& FS2,
200 const TopoDS_Vertex& aLoc1,
201 const TopoDS_Vertex& aLoc2,
202 const TopoDS_Wire& aWirePath,
203 TopTools_IndexedDataMapOfShapeShape& FF)
205 //cout<<"FillCorrespondingEdges"<<endl;
206 // find corresponding edges
207 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
208 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
209 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
210 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
211 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
212 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
213 aBuilder.Add(aWire1, aLoc1);
214 aBuilder.Add(aWire2, aLoc2);
215 if (!aBuilder.IsReady()) {
219 TopoDS_Shape aShape = aBuilder.Shape();
227 BRepTools::Write(C,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
229 ShapeAnalysis_Edge sae;
230 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
231 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
232 TopTools_MapOfShape Vs1,Vs2;
234 exp.Init(FS1, TopAbs_EDGE);
235 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
236 TopoDS_Vertex V11 = sae.FirstVertex(E1);
237 TopoDS_Vertex V21 = sae.LastVertex(E1);
238 gp_Pnt P11 = BRep_Tool::Pnt(V11);
239 gp_Pnt P21 = BRep_Tool::Pnt(V21);
240 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
241 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
242 // find corresponding vertexes from created shape
243 TopoDS_Vertex VN11,VN21;
244 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
245 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
246 gp_Pnt P = BRep_Tool::Pnt(V);
247 if (P.Distance(P11)<tol) {
250 if (P.Distance(P21)<tol) {
254 // find edge contains VN11 and VN21 and corresponding vertexes
255 TopoDS_Vertex VN12,VN22;
256 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
257 TopoDS_Shape F = exp.Current();
258 TopExp_Explorer expe;
260 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
261 TopoDS_Edge E = TopoDS::Edge(expe.Current());
262 TopoDS_Vertex VF = sae.FirstVertex(E);
263 TopoDS_Vertex VL = sae.LastVertex(E);
264 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
270 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
271 TopoDS_Edge E = TopoDS::Edge(expe.Current());
272 TopoDS_Vertex VF = sae.FirstVertex(E);
273 TopoDS_Vertex VL = sae.LastVertex(E);
274 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
276 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
278 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
280 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
286 // find vertexes from FS2 corresponded to VN12 and VN22
287 // and find edge from FS2 contains V12 and V22,
288 // this edge will be corresponded to edge E1
289 TopoDS_Vertex V12,V22;
290 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
291 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
292 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
293 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
295 TopExp_Explorer expe;
296 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
297 TopoDS_Edge E = TopoDS::Edge(expe.Current());
298 TopoDS_Vertex VF = sae.FirstVertex(E);
299 TopoDS_Vertex VL = sae.LastVertex(E);
300 gp_Pnt PF = BRep_Tool::Pnt(VF);
301 gp_Pnt PL = BRep_Tool::Pnt(VL);
302 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
308 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
319 // find other pairs for vertexes and edges
320 // creating map of vertex edges for both faces
321 return FillForOtherEdges(FS1,E1,V21,FF);
326 //=======================================================================
327 //function : FillCorrespondingEdges
328 //purpose : auxilary for CreatePipeShellsWithoutPath()
329 //=======================================================================
330 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
331 const TopoDS_Shape& FS2,
332 const TopoDS_Vertex& aLoc1,
333 const TopoDS_Vertex& aLoc2,
334 TopTools_IndexedDataMapOfShapeShape& FF)
336 //cout<<"FillCorrespondingEdges"<<endl;
338 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
339 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
342 ShapeAnalysis_Edge sae;
343 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
344 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
345 TopTools_MapOfShape Vs1,Vs2;
347 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
350 TopExp_Explorer exp1;
351 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
352 E1 = TopoDS::Edge(exp1.Current());
353 TopoDS_Vertex V1 = sae.FirstVertex(E1);
354 TopoDS_Vertex V2 = sae.LastVertex(E1);
355 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
356 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
357 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
358 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
359 if (P1.Distance(Ptmp1)<tol) {
363 if (P1.Distance(Ptmp2)<tol) {
370 TopoDS_Vertex VE21,VE22;
372 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
373 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
374 TopoDS_Vertex V1 = sae.FirstVertex(E);
375 TopoDS_Vertex V2 = sae.LastVertex(E);
376 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
377 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
378 if (P2.Distance(Ptmp1)<tol) {
390 if (P2.Distance(Ptmp2)<tol) {
404 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
405 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
406 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
407 gp_Vec aDir1(PV21,PE21);
408 gp_Vec aDir2(PV21,PE22);
409 double ang1 = aDir.Angle(aDir1);
410 double ang2 = aDir.Angle(aDir2);
411 if (fabs(ang1)<fabs(ang2)) {
424 // find other pairs for vertexes and edges
425 return FillForOtherEdges(FS1,E1,V21,FF);
428 //=======================================================================
429 //function : FindNextPairOfFaces
430 //purpose : auxilary for CreatePipeForShellSections()
431 //=======================================================================
432 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
433 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
434 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
435 TopTools_IndexedDataMapOfShapeShape& FF,
438 //cout<<"FindNextPairOfFaces"<<endl;
439 TopExp_Explorer anExp;
440 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
441 TopoDS_Shape E1 = anExp.Current();
442 if (!FF.Contains(E1)) {
444 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
446 if (!FF.Contains(E1))
447 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
448 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
449 TopExp_Explorer anExpV;
450 anExpV.Init(E1, TopAbs_VERTEX);
451 TopoDS_Shape V1 = anExpV.Current();
452 if (!FF.Contains(V1)) {
454 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
457 if (!aMapEdgeFaces1.Contains(E1))
458 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
459 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
460 if (aList1.Extent()<2)
462 TopTools_ListIteratorOfListOfShape anIter(aList1);
463 if (anIter.Value().IsEqual(aCurFace)) {
466 TopoDS_Shape F1other = anIter.Value();
467 if (FF.Contains(F1other))
470 if (!FF.Contains(aCurFace))
471 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
472 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
473 if (!aMapEdgeFaces2.Contains(E2))
474 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
475 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
476 if (aList2.Extent()<2) {
478 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
480 TopTools_ListIteratorOfListOfShape anIter2(aList2);
481 if (anIter2.Value().IsEqual(F2)) {
484 TopoDS_Shape F2other = anIter2.Value();
485 FF.Add(F1other,F2other);
487 // add pairs of edges to FF
488 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
491 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
494 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
498 //=======================================================================
499 //function : FindFirstPairFaces
500 //purpose : auxilary for Execute()
501 //=======================================================================
502 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
503 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
504 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
506 //cout<<"FindFirstPairFaces"<<endl;
508 // check if vertexes are sub-shapes of sections
509 gp_Pnt P1 = BRep_Tool::Pnt(V1);
510 gp_Pnt P2 = BRep_Tool::Pnt(V2);
511 TopoDS_Vertex V1new,V2new;
513 double mindist = 1.e10;
514 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
515 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
516 gp_Pnt P = BRep_Tool::Pnt(V);
517 double dist = P1.Distance(P);
524 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
525 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
526 gp_Pnt P = BRep_Tool::Pnt(V);
527 double dist = P2.Distance(P);
534 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
535 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
536 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
537 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
538 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
539 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
541 // replace vertexes if it is needed
542 if (!V1.IsSame(V1new)) {
544 P1 = BRep_Tool::Pnt(V1);
545 MESSAGE (" replace V1");
548 MESSAGE (" not replace V1");
549 if (!V2.IsSame(V2new)) {
551 P2 = BRep_Tool::Pnt(V2);
552 MESSAGE (" replace V2");
555 MESSAGE (" not replace V2");
557 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
558 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
559 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
560 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
562 if (!aMapVertFaces1.Contains(V1))
563 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
564 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
565 TopTools_ListIteratorOfListOfShape anIter1(aList1);
566 FS1 = anIter1.Value();
568 double x1=0., y1=0., z1=0.;
570 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
571 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
572 gp_Pnt P = BRep_Tool::Pnt(V);
578 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
580 TColgp_SequenceOfPnt Ps;
581 TopTools_SequenceOfShape Fs;
582 if (!aMapVertFaces2.Contains(V2))
583 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
584 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
585 TopTools_ListIteratorOfListOfShape anIter2(aList2);
586 for (; anIter2.More(); anIter2.Next()) {
587 TopoDS_Shape F = anIter2.Value();
588 double x2=0., y2=0., z2=0.;
590 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
591 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
592 gp_Pnt P = BRep_Tool::Pnt(V);
598 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
605 double MinAng = M_PI;
607 for (; i<=Fs.Length(); i++) {
608 gp_Vec tmpDir(PM1,Ps(i));
609 double ang = fabs(aDir.Angle(tmpDir));
618 //=======================================================================
619 //function : CreatePipeWithDifferentSections
621 //=======================================================================
622 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
623 (const TopoDS_Wire& theWirePath,
624 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
625 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
626 const Standard_Boolean theWithContact,
627 const Standard_Boolean theWithCorrect)
631 TopoDS_Wire aWirePath = theWirePath;
633 Standard_Integer nbBases = theHSeqBases->Length();
634 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
636 if (nbLocs && nbLocs != nbBases) {
637 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
640 TopTools_SequenceOfShape aSeqBases;
641 TopTools_SequenceOfShape aSeqLocs;
642 TopTools_SequenceOfShape aSeqFaces;
644 Standard_Integer i = 1;
645 for (i = 1; i <= nbBases; i++) {
646 if (theHSeqBases->Value(i).IsNull())
649 // Make copy to prevent modifying of base object 0020766 : EDF 1320
650 TopoDS_Shape aShapeBase;
651 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
653 aShapeBase = Copy.Shape();
655 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
657 //if for section was specified face with a few wires then a few
658 // pipes were build and make solid
659 Standard_Boolean NeedCreateSolid = Standard_False;
660 if (aTypeBase == TopAbs_SHELL) {
661 // create wire as boundary contour if shell is no closed
662 // get free boundary shapes
663 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
664 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
665 TopExp_Explorer anExp;
667 Standard_Integer NbWires = 0;
668 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
670 aWire = anExp.Current();
674 Standard_ConstructionError::Raise("Bad shell is used as section ");
676 NeedCreateSolid = Standard_True;
677 aSeqFaces.Append(aShapeBase);
678 aSeqBases.Append(aWire);
680 else if (aTypeBase == TopAbs_FACE) {
681 NeedCreateSolid = Standard_True;
682 //for case one path should be used other type function
683 aSeqFaces.Append(aShapeBase);
684 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
685 for (; aExpW.More(); aExpW.Next()) {
686 TopoDS_Shape aWireProf = aExpW.Current();
687 aSeqBases.Append(aWireProf);
690 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
691 aSeqBases.Append(aShapeBase);
693 else if (aTypeBase == TopAbs_EDGE) {
694 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
695 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
696 aSeqBases.Append(aWireProf);
699 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
700 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
702 aSeqLocs.Append(aShapeLoc);
706 nbLocs = aSeqLocs.Length();
709 TopTools_SequenceOfShape Edges;
711 // we have to check that each location shape is a vertex from
712 // path and update aSeqLocs if it is needed (and possible)
713 TColgp_SequenceOfPnt PLocs;
714 for (i=1; i<=nbLocs; i++) {
715 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
716 PLocs.Append(BRep_Tool::Pnt(V));
718 //TopTools_SequenceOfShape Edges;
719 TopExp_Explorer anExp;
720 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
721 Edges.Append(anExp.Current());
723 int nbEdges = Edges.Length();
724 ShapeAnalysis_Edge sae;
725 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
726 double tol = BRep_Tool::Tolerance(edge);
727 TopoDS_Vertex VF = sae.FirstVertex(edge);
728 gp_Pnt PF = BRep_Tool::Pnt(VF);
729 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
730 if (PF.Distance(PLocs.First()) > tol) {
731 Standard_ConstructionError::Raise
732 ("First location shapes is not coincided with first vertex of aWirePath");
734 aSeqLocs.ChangeValue(1) = VF;
735 edge = TopoDS::Edge(Edges.Last());
736 tol = BRep_Tool::Tolerance(edge);
737 TopoDS_Vertex VL = sae.LastVertex(edge);
738 gp_Pnt PL = BRep_Tool::Pnt(VL);
739 if (PL.Distance(PLocs.Last()) > tol) {
740 Standard_ConstructionError::Raise
741 ("Last location shapes is not coincided with last vertex of aWirePath");
743 aSeqLocs.ChangeValue(nbLocs) = VL;
745 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
746 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
747 tol = BRep_Tool::Tolerance(edge);
748 TopoDS_Vertex V1 = sae.FirstVertex(E);
749 TopoDS_Vertex V2 = sae.LastVertex(E);
750 gp_Pnt P1 = BRep_Tool::Pnt(V1);
751 gp_Pnt P2 = BRep_Tool::Pnt(V2);
752 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
753 aSeqLocs.ChangeValue(jcurr) = V2;
757 // find distance between E and aLocs(jcurr)
759 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
760 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
761 if (PPCurve.NbPoints()>0 &&
762 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
763 double param = PPCurve.Parameter(1);
766 // split current edge
767 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
768 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
773 if (Pfp.Distance(P1)<tol) {
774 B.MakeEdge(E1,tc1,tol);
776 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
777 B.Add(E1,TopoDS::Vertex(tmpV));
778 B.MakeEdge(E2,tc2,tol);
779 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
780 B.Add(E2,TopoDS::Vertex(tmpV));
784 B.MakeEdge(E1,tc2,tol);
785 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
786 B.Add(E1,TopoDS::Vertex(tmpV));
789 B.MakeEdge(E2,tc1,tol);
791 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
792 B.Add(E2,TopoDS::Vertex(tmpV));
797 Edges.InsertAfter(i-1,E1);
798 Edges.InsertAfter(i,E2);
802 if (nbEdges<Edges.Length()) {
803 // one of edges was splitted => we have to update WirePath
807 for (i=1; i<=Edges.Length(); i++) {
808 B.Add(W,TopoDS::Edge(Edges.Value(i)));
814 // check curvature of wire for condition that
815 // max summary angle between directions along
816 // wire path must be < 4*PI. If not - split wire
817 // and seguences of shapes, perform pipe for each
818 // and make sewing after that
820 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
825 double SumAng = fabs(Vec1.Angle(Vec2));
828 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
830 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
831 for (i=2; i<=Edges.Length(); i++) {
832 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
833 double tol = BRep_Tool::Tolerance(edge);
834 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
836 double ang = fabs(Vec1.Angle(Vec2));
840 SplitEdgeNums.Append(i-1);
842 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
843 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
844 gp_Pnt P = BRep_Tool::Pnt(aVert);
845 if (P1.Distance(P) < tol) {
846 SplitLocNums.Append(j);
856 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
857 TopTools_SequenceOfShape aSeqRes;
858 int nn, num1 = 1, num2 = 1;
859 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
860 // create wirepath and sequences of shapes
864 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
865 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
867 num1 = SplitEdgeNums.Value(nn) + 1;
868 TopTools_SequenceOfShape aTmpSeqBases;
869 TopTools_SequenceOfShape aTmpSeqLocs;
870 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
871 aTmpSeqBases.Append(aSeqBases.Value(i));
872 aTmpSeqLocs.Append(aSeqLocs.Value(i));
874 num2 = SplitLocNums.Value(nn);
876 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
877 Standard_Integer nbShapes = aTmpSeqBases.Length();
878 for (i=1; i<=nbShapes; i++) {
879 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
880 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
881 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
883 if (!aBuilder.IsReady()) {
884 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
887 TopoDS_Shape resShape = aBuilder.Shape();
888 aSeqRes.Append(resShape);
890 // create wirepath and sequences of shapes for last part
894 for (i=num1; i<=Edges.Length(); i++) {
895 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
897 TopTools_SequenceOfShape aTmpSeqBases;
898 TopTools_SequenceOfShape aTmpSeqLocs;
899 for (i=num2; i<=aSeqLocs.Length(); i++) {
900 aTmpSeqBases.Append(aSeqBases.Value(i));
901 aTmpSeqLocs.Append(aSeqLocs.Value(i));
903 // make pipe for last part
904 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
905 Standard_Integer nbShapes = aTmpSeqBases.Length();
906 for (i=1; i<=nbShapes; i++) {
907 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
908 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
909 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
911 if (!aBuilder.IsReady()) {
912 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
915 TopoDS_Shape resShape = aBuilder.Shape();
916 aSeqRes.Append(resShape);
917 // make sewing for result
918 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
919 aSewing->SetTolerance(Precision::Confusion());
920 aSewing->SetFaceMode(Standard_True);
921 aSewing->SetFloatingEdgesMode(Standard_False);
922 aSewing->SetNonManifoldMode(Standard_False);
923 for (i=1; i<=aSeqRes.Length(); i++) {
924 aSewing->Add(aSeqRes.Value(i));
927 aShape = aSewing->SewedShape();
930 // old implementation without splitting
931 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
933 Standard_Integer nbShapes = aSeqBases.Length();
934 Standard_Integer step = nbShapes/nbBases;
936 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
937 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
939 Standard_Integer ind =0;
940 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
941 TopTools_SequenceOfShape usedBases;
942 Standard_Integer j = 1;
943 for (; j <= nbBases; j++) {
944 ind = i + (j-1)*step;
945 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
946 usedBases.Append(aWireProf);
948 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
949 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
950 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
953 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
955 if (!aBuilder.IsReady()) {
956 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
959 aShape = aBuilder.Shape();
960 aSeqFaces.Append(aShape);
961 for (j = 1; j <=usedBases.Length(); j++)
962 aBuilder.Delete(usedBases.Value(j));
965 //for case if section is face
966 if (aSeqFaces.Length() >1) {
968 TopoDS_Compound aComp;
969 aB.MakeCompound(aComp);
970 for (i = 1; i <= aSeqFaces.Length(); i++)
971 aB.Add(aComp,aSeqFaces.Value(i));
979 //=======================================================================
980 //function : CreatePipeForShellSections
981 //purpose : auxilary for Execute()
982 //=======================================================================
983 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
986 //cout<<"CreatePipeForShellSections"<<endl;
991 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
992 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
993 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
994 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
995 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
996 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
998 Standard_Integer nbBases = aBasesObjs->Length(),
999 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1000 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1002 if (nbLocs != nbBases) {
1003 if (aCI) delete aCI;
1004 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1006 if (nbSubBases && nbSubBases != nbBases) {
1007 if (aCI) delete aCI;
1008 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1011 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1013 TopTools_SequenceOfShape VLocs;
1014 for (i=1; i<=nbBases; i++) {
1015 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1016 if (anItemLoc.IsNull())
1018 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1019 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1020 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1022 VLocs.Append(aShapeLoc);
1024 nbLocs = VLocs.Length();
1025 if (nbLocs != nbBases) {
1026 if (aCI) delete aCI;
1027 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1029 // split wire path by location points
1030 TColgp_SequenceOfPnt PLocs;
1031 for (i=1; i<=nbLocs; i++) {
1032 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1033 PLocs.Append(BRep_Tool::Pnt(V));
1036 TopTools_SequenceOfShape Edges;
1037 TopTools_SequenceOfShape Wires;
1038 ShapeAnalysis_Edge sae;
1041 TopExp_Explorer anExp;
1042 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1043 Edges.Append(anExp.Current());
1045 Standard_Integer Num1 = 0;
1046 Standard_Integer Num2 = 0;
1047 for (i=1; i<=Edges.Length(); i++) {
1048 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1049 double tol = BRep_Tool::Tolerance(E);
1050 TopoDS_Vertex V1 = sae.FirstVertex(E);
1051 TopoDS_Vertex V2 = sae.LastVertex(E);
1052 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1053 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1054 if (P1.Distance(PLocs.First()) < tol) {
1057 if (P2.Distance(PLocs.Last()) < tol) {
1061 if (Num1>0 && Num2>0) {
1064 for (i=Num1; i<=Num2; i++) {
1065 B.Add(W,Edges.Value(i));
1070 Wires.Append(aWirePath);
1074 TopExp_Explorer anExp;
1075 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1076 Edges.Append(anExp.Current());
1078 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1079 double tol = BRep_Tool::Tolerance(edge);
1080 TopoDS_Vertex VF = sae.FirstVertex(edge);
1081 gp_Pnt PF = BRep_Tool::Pnt(VF);
1082 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1083 if (PF.Distance(PLocs.First()) > tol) {
1084 if (aCI) delete aCI;
1085 Standard_ConstructionError::Raise
1086 ("First location shapes is not coincided with first vertex of aWirePath");
1088 VLocs.ChangeValue(1) = VF;
1089 edge = TopoDS::Edge(Edges.Last());
1090 tol = BRep_Tool::Tolerance(edge);
1091 TopoDS_Vertex VL = sae.LastVertex(edge);
1092 gp_Pnt PL = BRep_Tool::Pnt(VL);
1093 if (PL.Distance(PLocs.Last()) > tol) {
1094 if (aCI) delete aCI;
1095 Standard_ConstructionError::Raise
1096 ("Last location shapes is not coincided with last vertex of aWirePath");
1098 VLocs.ChangeValue(nbLocs) = VL;
1100 TopTools_SequenceOfShape tmpEdges;
1101 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1102 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1103 tol = BRep_Tool::Tolerance(E);
1104 TopoDS_Vertex V1 = sae.FirstVertex(E);
1105 TopoDS_Vertex V2 = sae.LastVertex(E);
1106 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1107 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1108 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1109 // make wire from current edge and add created
1113 for (j=1; j<=tmpEdges.Length(); j++)
1114 B.Add(W,tmpEdges.Value(j));
1117 VLocs.ChangeValue(jcurr) = V2;
1122 // find distance between E and aLocs(jcurr)
1124 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1125 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1126 if (PPCurve.NbPoints()>0 &&
1127 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1128 double param = PPCurve.Parameter(1);
1131 // split current edge
1132 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1133 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1137 if (Pfp.Distance(P1)<tol) {
1138 B.MakeEdge(E1,tc1,tol);
1140 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1141 B.Add(E1,TopoDS::Vertex(tmpV));
1142 tmpEdges.Append(E1);
1143 B.MakeEdge(E2,tc2,tol);
1144 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1145 B.Add(E2,TopoDS::Vertex(tmpV));
1149 B.MakeEdge(E1,tc2,tol);
1150 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1151 B.Add(E1,TopoDS::Vertex(tmpV));
1154 tmpEdges.Append(E1);
1155 B.MakeEdge(E2,tc1,tol);
1157 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1158 B.Add(E2,TopoDS::Vertex(tmpV));
1161 // create wire from tmpEdges
1164 for (j=1; j<=tmpEdges.Length(); j++)
1165 B.Add(W,tmpEdges.Value(j));
1170 Edges.InsertAfter(i-1,E1);
1171 Edges.InsertAfter(i,E2);
1178 // create wire from other edges
1181 for (; i<=Edges.Length(); i++)
1182 B.Add(W,Edges.Value(i));
1184 //cout<<"Wires.Length()="<<Wires.Length()<<endl;
1187 if (Wires.Length() != nbLocs-1) {
1188 if (aCI) delete aCI;
1189 Standard_ConstructionError::Raise
1190 ("One of location shapes is not lied on the path");
1193 //TopTools_SequenceOfShape aSeqBases;
1194 //TopTools_SequenceOfShape aSeqSubBases;
1195 //TopTools_SequenceOfShape aSeqFaces;
1196 TopoDS_Compound aComp;
1197 B.MakeCompound(aComp);
1198 for (i = 1; i < nbBases; i++) {
1199 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1201 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1202 if (anItem1.IsNull())
1204 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1205 if (aRefBase1.IsNull())
1207 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1208 if (aShBase1.IsNull())
1210 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1212 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1213 if (anItem2.IsNull())
1215 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1216 if (aRefBase2.IsNull())
1218 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1219 if (aShBase2.IsNull())
1221 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1223 //BRepTools::Write(aShBase1,"/dn02/users_Linux/skl/work/Bugs/14857/base1.brep");
1225 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1226 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1228 if (aCI) delete aCI;
1229 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1232 bool CreateFewSolids = false;
1234 TopExp_Explorer anExp;
1235 Standard_Integer nbf1 = 0;
1236 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1239 Standard_Integer nbf2 = 0;
1240 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1244 CreateFewSolids = true;
1248 // check orientation of sections
1249 bool NeedReverse = false;
1252 anExp.Init(aShBase1, TopAbs_FACE);
1253 TopoDS_Shape aFace = anExp.Current();
1254 TColgp_SequenceOfPnt aPnts;
1255 double xc=0, yc=0, zc=0;
1256 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1257 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1258 aPnts.Append(BRep_Tool::Pnt(V));
1259 xc += aPnts.Last().X();
1260 yc += aPnts.Last().Y();
1261 zc += aPnts.Last().Z();
1263 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1264 gp_Vec V1(PC,aPnts.Value(1));
1265 gp_Vec V2(PC,aPnts.Value(2));
1266 gp_Vec VN = V1.Crossed(V2);
1267 for (int ip=2; ip<aPnts.Length(); ip++) {
1268 V1 = gp_Vec(PC,aPnts.Value(ip));
1269 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1270 VN.Add(V1.Crossed(V2));
1273 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i)));
1275 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1276 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1277 double tol = BRep_Tool::Tolerance(edge);
1278 TopoDS_Vertex VF = sae.FirstVertex(edge);
1279 gp_Pnt PF = BRep_Tool::Pnt(VF);
1280 if (PF.Distance(PLoc) < tol) {
1282 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1285 if (P1.Distance(PLoc) < tol) {
1286 C->D0(fp+(lp-fp)/100,P2);
1290 C->D0(lp+(fp-lp)/100,P2);
1292 PathNorm = gp_Vec(P1,P2);
1296 TopoDS_Vertex VL = sae.LastVertex(edge);
1297 gp_Pnt PL = BRep_Tool::Pnt(VL);
1298 if (PL.Distance(PLoc) < tol) {
1300 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1303 if (P1.Distance(PLoc) < tol) {
1304 C->D0(fp+(lp-fp)/100,P2);
1308 C->D0(lp+(fp-lp)/100,P2);
1310 PathNorm = gp_Vec(P2,P1);
1315 cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1316 cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1317 if (fabs(VN.Angle(PathNorm))>PI/2.) {
1324 anExp.Init(aShBase2, TopAbs_FACE);
1325 TopoDS_Shape aFace = anExp.Current();
1326 TColgp_SequenceOfPnt aPnts;
1327 double xc=0, yc=0, zc=0;
1328 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1329 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1330 aPnts.Append(BRep_Tool::Pnt(V));
1331 xc += aPnts.Last().X();
1332 yc += aPnts.Last().Y();
1333 zc += aPnts.Last().Z();
1335 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1336 gp_Vec V1(PC,aPnts.Value(1));
1337 gp_Vec V2(PC,aPnts.Value(2));
1338 gp_Vec VN = V1.Crossed(V2);
1339 for (int ip=2; ip<aPnts.Length(); ip++) {
1340 V1 = gp_Vec(PC,aPnts.Value(ip));
1341 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1342 VN.Add(V1.Crossed(V2));
1345 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i+1)));
1347 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1348 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1349 double tol = BRep_Tool::Tolerance(edge);
1350 TopoDS_Vertex VF = sae.FirstVertex(edge);
1351 gp_Pnt PF = BRep_Tool::Pnt(VF);
1352 if (PF.Distance(PLoc) < tol) {
1354 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1357 if (P1.Distance(PLoc) < tol) {
1358 C->D0(fp+(lp-fp)/100,P2);
1362 C->D0(lp+(fp-lp)/100,P2);
1364 PathNorm = gp_Vec(P2,P1);
1368 TopoDS_Vertex VL = sae.LastVertex(edge);
1369 gp_Pnt PL = BRep_Tool::Pnt(VL);
1370 if (PL.Distance(PLoc) < tol) {
1372 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1375 if (P1.Distance(PLoc) < tol) {
1376 C->D0(fp+(lp-fp)/100,P2);
1380 C->D0(lp+(fp-lp)/100,P2);
1382 PathNorm = gp_Vec(P2,P1);
1387 //cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1388 //cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1389 if (fabs(VN.Angle(PathNorm))>PI/2.)
1394 if (!CreateFewSolids) {
1395 // we can create only one solid
1396 TopoDS_Shape aWire1, aWire2;
1398 if (aType1==TopAbs_SHELL) {
1399 // create wire as boundary contour if shell is no closed
1400 // get free boundary shapes
1401 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1402 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1403 //TopExp_Explorer anExp;
1404 Standard_Integer NbWires = 0;
1405 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1407 aWire1 = anExp.Current();
1411 if (aCI) delete aCI;
1412 Standard_ConstructionError::Raise("Bad shell is used as section ");
1415 else { // aType1==TopAbs_FACE
1416 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1417 aWire1 = aExpW.Current();
1420 if (aType2==TopAbs_SHELL) {
1421 // create wire as boundary contour if shell is no closed
1422 // get free boundary shapes
1423 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1424 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1425 //TopExp_Explorer anExp;
1426 Standard_Integer NbWires = 0;
1427 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1429 aWire2 = anExp.Current();
1433 if (aCI) delete aCI;
1434 Standard_ConstructionError::Raise("Bad shell is used as section ");
1437 else { // aType2==TopAbs_FACE
1438 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1439 aWire2 = aExpW.Current();
1441 // make pipe using aWire1 and aWire2
1442 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1443 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1444 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1445 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1446 aWithContact, aWithCorrect);
1447 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1448 aWithContact, aWithCorrect);
1449 if (!aBuilder.IsReady()) {
1450 if (aCI) delete aCI;
1451 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1454 TopoDS_Shape aShape = aBuilder.Shape();
1455 TopoDS_Shell aShell;
1456 B.MakeShell(aShell);
1457 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1458 B.Add(aShell,anExp.Current());
1460 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1461 B.Add(aShell,anExp.Current());
1463 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1464 B.Add(aShell,anExp.Current());
1466 // make sewing for this shell
1467 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1468 aSewing->SetTolerance(Precision::Confusion());
1469 aSewing->SetFaceMode(Standard_True);
1470 aSewing->SetFloatingEdgesMode(Standard_False);
1471 aSewing->SetNonManifoldMode(Standard_False);
1472 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1473 aSewing->Add(anExp.Current());
1476 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1477 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1478 aShell = TopoDS::Shell(aSewShape);
1479 GProp_GProps aSystem;
1480 BRepGProp::VolumeProperties(aShell, aSystem);
1481 if (aSystem.Mass()<0) {
1484 if (BRep_Tool::IsClosed(aShell)) {
1485 TopoDS_Solid aSolid;
1486 B.MakeSolid(aSolid);
1487 B.Add(aSolid,aShell);
1488 B.Add(aComp,aSolid);
1491 B.Add(aComp,aShell);
1495 B.Add(aComp,aShell);
1500 // main block - creation few solids (for each pair of faces)
1501 TopTools_MapOfShape aFaces1,aFaces2;
1502 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1503 aFaces1.Add(anExp.Current());
1505 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1506 aFaces2.Add(anExp.Current());
1508 // creating map of edge faces
1509 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1510 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1511 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1512 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1514 // constuct map face->face
1515 TopTools_IndexedDataMapOfShapeShape FF;
1516 TopoDS_Shape FS1,FS2;
1517 if (nbSubBases==0) {
1518 // find edge the most distant from location point
1519 // (this edge is not shared by two faces)
1520 double maxdist = 0.;
1522 TopoDS_Vertex V11,V21;
1523 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1524 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1525 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1526 if (aList.Extent()>1)
1528 TopExp_Explorer expv;
1529 expv.Init(tmp, TopAbs_VERTEX);
1530 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1532 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1533 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1534 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1535 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1540 TopTools_ListIteratorOfListOfShape anIter(aList);
1541 FS1 = anIter.Value();
1545 // main direction for comparing
1546 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1547 // find corresponding edge from next section
1548 double minang = M_PI;
1549 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1550 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1552 TopoDS_Vertex V12,V22;
1553 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1554 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1555 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1556 if (aList.Extent()>1)
1558 TopExp_Explorer expv;
1559 expv.Init(tmp, TopAbs_VERTEX);
1560 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1562 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1563 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1564 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1565 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1566 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1567 TopoDS_Vertex V1,V2;
1570 V1 = V2tmp; P1 = P2tmp;
1571 V2 = V1tmp; P2 = P1tmp;
1574 V1 = V1tmp; P1 = P1tmp;
1575 V2 = V2tmp; P2 = P2tmp;
1577 gp_Vec Vec1(P11,P1);
1578 gp_Vec Vec2(P21,P2);
1579 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1584 TopTools_ListIteratorOfListOfShape anIter(aList);
1585 FS2 = anIter.Value();
1589 // put all pairs to map FF
1595 // add pairs of edges to FF
1596 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1598 if (aCI) delete aCI;
1599 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1605 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1606 if (anItem.IsNull()) {
1607 if (aCI) delete aCI;
1608 Standard_ConstructionError::Raise("Invalid subbase shape");
1610 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1611 if (aRefBase.IsNull()) {
1612 if (aCI) delete aCI;
1613 Standard_ConstructionError::Raise("Invalid subbase shape");
1615 TopoDS_Shape aSh = aRefBase->GetValue();
1617 if (aCI) delete aCI;
1618 Standard_ConstructionError::Raise("Invalid subbase shape");
1620 if (aSh.ShapeType()!=TopAbs_FACE) {
1621 if (aCI) delete aCI;
1622 Standard_ConstructionError::Raise("Invalid subbase shape");
1627 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1628 if (anItem.IsNull()) {
1629 if (aCI) delete aCI;
1630 Standard_ConstructionError::Raise("Invalid subbase shape");
1632 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1633 if (aRefBase.IsNull()) {
1634 if (aCI) delete aCI;
1635 Standard_ConstructionError::Raise("Invalid subbase shape");
1637 TopoDS_Shape aSh = aRefBase->GetValue();
1639 if (aCI) delete aCI;
1640 Standard_ConstructionError::Raise("Invalid subbase shape");
1642 if (aSh.ShapeType()!=TopAbs_FACE) {
1643 if (aCI) delete aCI;
1644 Standard_ConstructionError::Raise("Invalid subbase shape");
1649 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1650 if (aCI) delete aCI;
1651 Standard_ConstructionError::Raise("Invalid subbase shape");
1656 // add pairs of edges to FF
1657 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1658 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1660 if (aCI) delete aCI;
1661 Standard_ConstructionError::Raise("Can not create correct pipe");
1665 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1667 // make pipe for each pair of faces
1668 for (j=1; j<=FF.Extent(); j++) {
1669 TopoDS_Shape F1 = FF.FindKey(j);
1670 if (F1.ShapeType() != TopAbs_FACE)
1672 TopoDS_Shape F2 = FF.FindFromIndex(j);
1673 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1674 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1675 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1676 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1677 // make pipe using aWire1 and aWire2
1678 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1679 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1680 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1681 aWithContact, aWithCorrect);
1682 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1683 aWithContact, aWithCorrect);
1684 if (!aBuilder.IsReady()) {
1685 if (aCI) delete aCI;
1686 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1689 TopoDS_Shape aShape = aBuilder.Shape();
1690 TopoDS_Shell aShell;
1691 B.MakeShell(aShell);
1692 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1693 B.Add(aShell,anExp.Current());
1698 // make sewing for this shell
1699 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1700 aSewing->SetTolerance(Precision::Confusion());
1701 aSewing->SetFaceMode(Standard_True);
1702 aSewing->SetFloatingEdgesMode(Standard_False);
1703 aSewing->SetNonManifoldMode(Standard_False);
1704 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1705 aSewing->Add(anExp.Current());
1708 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1709 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1710 aShell = TopoDS::Shell(aSewShape);
1711 GProp_GProps aSystem;
1712 BRepGProp::VolumeProperties(aShell, aSystem);
1713 if (aSystem.Mass()<0) {
1714 //cout<<"aSewShape is reversed"<<endl;
1717 if (BRep_Tool::IsClosed(aShell)) {
1718 TopoDS_Solid aSolid;
1719 B.MakeSolid(aSolid);
1720 B.Add(aSolid,aShell);
1721 B.Add(aComp,aSolid);
1724 B.Add(aComp,aShell);
1728 B.Add(aComp,aShell);
1736 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
1740 //=======================================================================
1741 //function : CreatePipeShellsWithoutPath
1742 //purpose : auxilary for Execute()
1743 //=======================================================================
1744 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
1746 //cout<<"CreatePipeShellsWithoutPath"<<endl;
1750 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1752 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1753 // vertex for recognition
1754 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
1756 Standard_Integer nbBases = aBasesObjs->Length(),
1757 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
1759 if (nbv != nbBases) {
1760 if (aCI) delete aCI;
1761 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
1764 TopTools_SequenceOfShape SecVs,Bases;
1765 for (i=1; i<=nbBases; i++) {
1767 Handle(Standard_Transient) anItem = VObjs->Value(i);
1768 if (anItem.IsNull())
1770 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
1771 TopoDS_Shape V = aRef->GetValue();
1772 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
1776 anItem = aBasesObjs->Value(i);
1777 if (anItem.IsNull())
1779 aRef = Handle(GEOM_Function)::DownCast(anItem);
1780 TopoDS_Shape aSh = aRef->GetValue();
1785 nbv = SecVs.Length();
1786 nbBases = Bases.Length();
1787 if (nbv != nbBases) {
1788 if (aCI) delete aCI;
1789 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
1792 TopoDS_Compound aComp;
1793 B.MakeCompound(aComp);
1795 for (i = 1; i < nbBases; i++) {
1796 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
1797 TopoDS_Shape aShBase1 = Bases.Value(i);
1798 TopoDS_Shape aShBase2 = Bases.Value(i+1);
1799 TopExp_Explorer anExp;
1800 Standard_Integer nbf1 = 0;
1801 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1804 Standard_Integer nbf2 = 0;
1805 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1808 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
1810 if (aCI) delete aCI;
1811 Standard_ConstructionError::Raise("Different number of faces in the sections");
1814 TopTools_MapOfShape aFaces1,aFaces2;
1815 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1816 aFaces1.Add(anExp.Current());
1818 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1819 aFaces2.Add(anExp.Current());
1822 // creating map of edge faces
1823 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1824 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1825 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1826 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1828 // constuct map face->face (and sub-shapes)
1829 TopTools_IndexedDataMapOfShapeShape FF;
1830 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
1831 TopoDS_Shape FS1, FS2;
1832 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
1833 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
1834 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
1837 MESSAGE (" first pair of corresponding faces is found");
1839 // add pairs of edges and vertexes to FF
1840 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
1842 if (aCI) delete aCI;
1843 Standard_ConstructionError::Raise("Can not create correct pipe");
1845 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
1847 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1848 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
1850 // make pipe for each pair of faces
1851 // auxilary map vertex->edge for created pipe edges
1852 TopTools_IndexedDataMapOfShapeShape VPE;
1853 ShapeAnalysis_Edge sae;
1854 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
1856 for (j=1; j<=FF.Extent(); j++) {
1857 TopoDS_Shape F1 = FF.FindKey(j);
1858 if (F1.ShapeType() != TopAbs_FACE)
1860 TopoDS_Shape F2 = FF.FindFromIndex(j);
1863 //if (nbff!=3) continue;
1865 MESSAGE (" make pipe for "<<nbff<<" face");
1867 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
1868 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1869 Handle(Geom_RectangularTrimmedSurface) RTS =
1870 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
1871 S1 = RTS->BasisSurface();
1873 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
1874 if (Pln1.IsNull()) {
1875 if (aCI) delete aCI;
1876 Standard_ConstructionError::Raise("Surface from face is not plane");
1878 gp_Vec aDir1(Pln1->Axis().Direction());
1880 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
1881 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1882 Handle(Geom_RectangularTrimmedSurface) RTS =
1883 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
1884 S2 = RTS->BasisSurface();
1886 Handle(Geom_Plane) Pln2 =
1887 Handle(Geom_Plane)::DownCast(S2);
1888 if (Pln2.IsNull()) {
1889 if (aCI) delete aCI;
1890 Standard_ConstructionError::Raise("Surface from face is not plane");
1892 gp_Vec aDir2(Pln2->Axis().Direction());
1894 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
1895 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
1897 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
1899 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
1902 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
1903 TopTools_SequenceOfShape aNewFs;
1905 for (; anExpE.More(); anExpE.Next()) {
1906 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
1908 if (!FF.Contains(E1))
1909 MESSAGE ("map FF not contains key E1");
1911 if (VPE.Contains(E1)) {
1912 aNewFs.Append(VPE.FindFromKey(E1));
1914 MESSAGE (" using existed face");
1919 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
1920 TopoDS_Vertex V1 = sae.FirstVertex(E1);
1921 TopoDS_Vertex V2 = sae.LastVertex(E1);
1922 if (!FF.Contains(V1))
1923 MESSAGE ("map FF not contains key V1");
1924 if (!FF.Contains(V2))
1925 MESSAGE ("map FF not contains key V2");
1926 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
1927 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
1928 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
1929 if (Vtmp.IsSame(V4))
1931 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1932 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1933 gp_Pnt P3 = BRep_Tool::Pnt(V3);
1934 gp_Pnt P4 = BRep_Tool::Pnt(V4);
1937 Handle(Geom_BSplineCurve) C2;
1938 if (VPE.Contains(V2)) {
1939 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
1941 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
1944 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
1945 HAP->SetValue(1,P2);
1946 HAP->SetValue(2,P3);
1947 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
1948 anInt.Load(aDir1,aDir2);
1951 B.MakeEdge(E2,C2,1.e-7);
1952 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
1953 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
1958 Handle(Geom_BSplineCurve) C4;
1959 if (VPE.Contains(V1)) {
1960 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
1962 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
1965 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
1966 HAP->SetValue(1,P1);
1967 HAP->SetValue(2,P4);
1968 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
1969 anInt.Load(aDir1,aDir2);
1972 B.MakeEdge(E4,anInt.Curve(),1.e-7);
1973 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
1974 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
1983 B.Add(W,E4.Reversed());
1984 //cout<<" wire for edge "<<nbee<<" is created"<<endl;
1985 //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
1990 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
1991 //bool IsConicC1 = false;
1992 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
1993 // IsConicC1 = true;
1994 // cout<<"C1 - Geom_Conic"<<endl;
1996 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
1997 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2000 // double tol = BRep_Tool::Tolerance(E1);
2001 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2002 // C1 = ApxC1.Curve();
2004 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2005 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2006 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2011 Handle(Geom_BSplineCurve) CE1 =
2012 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2013 if (CE1->Degree()<3)
2014 CE1->IncreaseDegree(3);
2015 Handle(Geom_BSplineCurve) CE2 =
2016 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2017 if (CE2->Degree()<3)
2018 CE2->IncreaseDegree(3);
2019 Handle(Geom_BSplineCurve) CE3 =
2020 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2021 if (CE3->Degree()<3)
2022 CE3->IncreaseDegree(3);
2023 Handle(Geom_BSplineCurve) CE4 =
2024 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2025 if (CE4->Degree()<3)
2026 CE4->IncreaseDegree(3);
2027 //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
2028 // <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
2029 //if (fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
2030 // os<<"DrawTrSurf_BSplineCurve"<<endl;
2031 // GeomTools::Write(CE1,os);
2035 Handle(Geom_Surface) BS;
2037 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2038 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2042 MESSAGE (" can not create BSplineSurface - create Bezier");
2044 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2045 double fp1,lp1,fp2,lp2;
2046 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2047 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2056 // get points from C1
2057 if (P1.Distance(P1C1)<1.e-6) {
2065 double step = (lp-fp)/(NbP-1);
2066 Points.SetValue(1,1,P1);
2068 for (n1=2; n1<NbP; n1++) {
2072 Points.SetValue(1,n1,P);
2074 Points.SetValue(1,NbP,P2);
2075 // get points from C3
2076 if (P4.Distance(P1C3)<1.e-6) {
2084 step = (lp-fp)/(NbP-1);
2085 Points.SetValue(NbP,1,P4);
2087 for (n1=2; n1<NbP; n1++) {
2091 Points.SetValue(NbP,n1,P);
2093 Points.SetValue(NbP,NbP,P3);
2094 // create isolines and get points from them
2095 for (n1=1; n1<=NbP; n1++) {
2096 gp_Pnt PI1 = Points.Value(1,n1);
2097 gp_Pnt PI2 = Points.Value(NbP,n1);
2098 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2099 HAP->SetValue(1,PI1);
2100 HAP->SetValue(2,PI2);
2101 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2102 anInt.Load(aDir1,aDir2);
2104 Handle(Geom_Curve) iso = anInt.Curve();
2105 fp = iso->FirstParameter();
2106 lp = iso->LastParameter();
2107 step = (lp-fp)/(NbP-1);
2109 TopoDS_Compound VComp;
2110 B.MakeCompound(VComp);
2111 for (n2=2; n2<NbP; n2++) {
2115 Points.SetValue(n2,n1,P);
2118 // create surface and face
2119 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2120 BS = new Geom_BezierSurface(Points);
2123 BRepBuilderAPI_MakeFace BB(BS,W);
2124 TopoDS_Face NewF = BB.Face();
2125 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2127 sff->FixOrientation();
2128 TopoDS_Face FixedFace = sff->Face();
2129 aNewFs.Append(FixedFace);
2130 VPE.Add(E1,FixedFace);
2131 //cout<<" face for edge "<<nbee<<" is created"<<endl;
2132 //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
2135 TopoDS_Shell aShell;
2136 B.MakeShell(aShell);
2137 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2138 B.Add(aShell,aNewFs(nf));
2143 // make sewing for this shell
2144 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2145 aSewing->SetTolerance(Precision::Confusion());
2146 aSewing->SetFaceMode(Standard_True);
2147 aSewing->SetFloatingEdgesMode(Standard_False);
2148 aSewing->SetNonManifoldMode(Standard_False);
2149 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2150 aSewing->Add(anExp.Current());
2153 MESSAGE (" shell for face "<<nbff<<" is created");
2154 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2155 //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
2156 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2157 aShell = TopoDS::Shell(aSewShape);
2158 GProp_GProps aSystem;
2159 BRepGProp::VolumeProperties(aShell, aSystem);
2160 if (aSystem.Mass()<0) {
2161 //cout<<"aSewShape is reversed"<<endl;
2164 if (BRep_Tool::IsClosed(aShell)) {
2165 TopoDS_Solid aSolid;
2166 B.MakeSolid(aSolid);
2167 B.Add(aSolid,aShell);
2168 B.Add(aComp,aSolid);
2169 MESSAGE (" solid for face "<<nbff<<" is created");
2172 B.Add(aComp,aShell);
2173 MESSAGE (" solid for face "<<nbff<<" is not created");
2177 B.Add(aComp,aShell);
2178 MESSAGE (" solid for face "<<nbff<<" is not created");
2180 //cout<<" solid for face "<<nbff<<" is created"<<endl;
2182 //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
2184 //TopoDS_Shell FixedShell = sfs->Shell();
2186 GProp_GProps aSystem;
2187 BRepGProp::VolumeProperties(FixedShell, aSystem);
2188 if (aSystem.Mass()<0) {
2189 //cout<<"aSewShape is reversed"<<endl;
2190 FixedShell.Reverse();
2192 if (BRep_Tool::IsClosed(FixedShell)) {
2193 TopoDS_Solid aSolid;
2194 B.MakeSolid(aSolid);
2195 B.Add(aSolid,aShell);
2196 B.Add(aComp,aSolid);
2199 B.Add(aComp,FixedShell);
2205 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
2209 //=======================================================================
2210 //function : CreatePipeBiNormalAlongVector
2211 //purpose : auxilary for Execute()
2212 //=======================================================================
2213 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2214 GEOMImpl_IPipe* aCI)
2216 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2218 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2219 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2220 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2221 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2223 if (aShapeBase.IsNull()) {
2224 if (aCIBN) delete aCIBN;
2225 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2228 // Make copy to prevent modifying of base object: 0021525
2229 BRepBuilderAPI_Copy Copy (aShapeBase);
2231 aShapeBase = Copy.Shape();
2234 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2237 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2238 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2240 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2243 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2244 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2245 aProf = wexp.Current();
2248 Standard_TypeMismatch::Raise
2249 ("MakePipe aborted : invalid type of base");
2251 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2252 PipeBuilder.Add(aProf);
2254 if (aShapeVec.IsNull()) {
2255 if (aCIBN) delete aCIBN;
2256 Standard_NullObject::Raise
2257 ("MakePipe aborted : null vector argument");
2259 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2260 Standard_TypeMismatch::Raise
2261 ("MakePipe aborted: invalid type of vector");
2262 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2263 TopoDS_Vertex V1, V2;
2264 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2265 if (V1.IsNull() || V2.IsNull())
2266 Standard_NullObject::Raise
2267 ("MakePipe aborted: vector is not defined");
2268 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2269 gp_Dir BiNormal(aVec);
2270 PipeBuilder.SetMode(BiNormal);
2271 PipeBuilder.Build();
2272 if (aShapeBase.ShapeType() == TopAbs_FACE) {
2273 PipeBuilder.MakeSolid();
2276 return PipeBuilder.Shape();
2279 //=======================================================================
2280 //function : Execute
2282 //=======================================================================
2283 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
2285 if (Label().IsNull()) return 0;
2286 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
2287 Standard_Integer aType = aFunction->GetType();
2289 GEOMImpl_IPipe* aCI = 0;
2290 if (aType == PIPE_BASE_PATH)
2291 aCI = new GEOMImpl_IPipe (aFunction);
2292 else if (aType == PIPE_DIFFERENT_SECTIONS)
2293 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
2294 else if (aType == PIPE_SHELL_SECTIONS)
2295 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2296 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
2297 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2298 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
2299 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
2303 TopoDS_Wire aWirePath;
2304 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
2305 // working with path
2306 Handle(GEOM_Function) aRefPath = aCI->GetPath();
2307 TopoDS_Shape aShapePath = aRefPath->GetValue();
2309 if (aShapePath.IsNull()) {
2310 MESSAGE ("Driver : path is null");
2311 if (aCI) delete aCI;
2312 Standard_NullObject::Raise("MakePipe aborted : null path argument");
2317 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
2318 TopTools_SequenceOfShape anEdges;
2319 TopExp_Explorer anExp;
2323 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2324 B.Add(W, anExp.Current());
2330 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
2331 aWirePath = TopoDS::Wire(aShapePath);
2335 if (aShapePath.ShapeType() == TopAbs_EDGE) {
2336 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
2337 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
2342 if (aCI) delete aCI;
2343 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
2347 TopoDS_Shape aShape;
2349 if (aType == PIPE_BASE_PATH) {
2350 Handle(GEOM_Function) aRefBase = aCI->GetBase();
2351 TopoDS_Shape aShapeBase;
2353 // Make copy to prevent modifying of base object 0020766 : EDF 1320
2354 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
2356 aShapeBase = Copy.Shape();
2358 if (aShapeBase.IsNull()) {
2359 if (aCI) delete aCI;
2360 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2364 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
2365 aShapeBase.ShapeType() == TopAbs_WIRE)
2367 TopoDS_Wire Profile;
2368 if (aShapeBase.ShapeType() == TopAbs_WIRE)
2369 Profile = TopoDS::Wire(aShapeBase);
2373 BB.MakeWire(Profile);
2374 BB.Add(Profile, aShapeBase);
2377 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
2378 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
2379 if (FaceBuilder.IsDone())
2380 Sweep.SetMode(FaceBuilder.Face());
2384 if (!Sweep.IsDone())
2386 if (aCI) delete aCI;
2387 Standard_ConstructionError::Raise("MakePipeShell failed");
2390 aShape = Sweep.Shape(); //result is good
2394 aShape = BRepOffsetAPI_MakePipe(aWirePath, aShapeBase);
2397 //building pipe with different sections
2398 else if (aType == PIPE_DIFFERENT_SECTIONS) {
2399 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
2400 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
2401 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
2402 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
2403 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
2409 Standard_Integer nbBases = aBasesObjs->Length();
2410 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
2412 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
2413 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
2416 for (i = 1; i <= nbBases; i++) {
2417 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
2418 if (anItem.IsNull())
2420 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
2421 if (aRefBase.IsNull())
2423 if (aRefBase->GetValue().IsNull())
2426 aHSeqBases->Append(aRefBase->GetValue());
2428 for (i = 1; i <= nbLocs; i++) {
2429 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
2430 if (anItemLoc.IsNull())
2432 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
2433 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
2434 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
2437 aHSeqLocs->Append(aShapeLoc);
2440 aShape = CreatePipeWithDifferentSections(aWirePath, aHSeqBases, aHSeqLocs, aWithContact, aWithCorrect);
2443 //building pipe with shell sections
2444 else if (aType == PIPE_SHELL_SECTIONS) {
2445 aShape = CreatePipeForShellSections(aWirePath,aCI);
2448 //building pipe shell sections without path
2449 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
2450 aShape = CreatePipeShellsWithoutPath(aCI);
2453 //building a pipe with constant bi-normal along given vector
2454 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
2455 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
2463 if (aShape.IsNull()) return 0;
2465 BRepCheck_Analyzer ana (aShape, Standard_False);
2466 if (!ana.IsValid()) {
2467 ShapeFix_ShapeTolerance aSFT;
2468 aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion());
2469 Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
2470 aSfs->SetPrecision(Precision::Confusion());
2472 aShape = aSfs->Shape();
2474 ana.Init(aShape, Standard_False);
2476 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
2479 // Glue (for bug 0020207)
2480 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
2481 if (anExpV.More()) {
2482 Standard_Real aVertMaxTol = -RealLast();
2483 for (; anExpV.More(); anExpV.Next()) {
2484 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
2485 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
2486 if (aTol > aVertMaxTol)
2489 aVertMaxTol += Precision::Confusion();
2490 aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
2491 //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
2494 TopoDS_Shape aRes = GEOMImpl_IShapesOperations::CompsolidToCompound(aShape);
2495 aFunction->SetValue(aRes);
2497 log.SetTouched(Label());
2501 //=======================================================================
2502 //function : GEOMImpl_PipeDriver_Type_
2504 //=======================================================================
2505 Standard_EXPORT Handle_Standard_Type& GEOMImpl_PipeDriver_Type_()
2507 static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
2508 if (aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
2509 static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
2510 if (aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
2511 static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
2512 if (aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
2514 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
2515 static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_PipeDriver",
2516 sizeof(GEOMImpl_PipeDriver),
2518 (Standard_Address)_Ancestors,
2519 (Standard_Address)NULL);
2524 //=======================================================================
2525 //function : DownCast
2527 //=======================================================================
2528 const Handle(GEOMImpl_PipeDriver) Handle(GEOMImpl_PipeDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
2530 Handle(GEOMImpl_PipeDriver) _anOtherObject;
2532 if (!AnObject.IsNull()) {
2533 if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_PipeDriver))) {
2534 _anOtherObject = Handle(GEOMImpl_PipeDriver)((Handle(GEOMImpl_PipeDriver)&)AnObject);
2538 return _anOtherObject;