1 // Copyright (C) 2007-2011 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_GlueDriver.hxx>
32 #include <GEOMImpl_Types.hxx>
33 #include <GEOM_Function.hxx>
35 #include <ShapeAnalysis_FreeBounds.hxx>
36 #include <ShapeAnalysis_Edge.hxx>
37 #include <ShapeFix_Face.hxx>
38 #include <ShapeFix_Shell.hxx>
39 #include <ShapeFix_Shape.hxx>
40 #include <ShapeFix_ShapeTolerance.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BRepBuilderAPI_MakeWire.hxx>
45 #include <BRepBuilderAPI_Sewing.hxx>
46 #include <BRepCheck_Analyzer.hxx>
47 #include <BRepOffsetAPI_MakePipe.hxx>
48 #include <BRepOffsetAPI_MakePipeShell.hxx>
49 #include <GProp_GProps.hxx>
50 #include <BRepGProp.hxx>
51 #include <BRepBuilderAPI_MakeFace.hxx>
52 #include <BRepBuilderAPI_Copy.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 <GeomAPI_ProjectPointOnCurve.hxx>
72 #include <GeomAPI_Interpolate.hxx>
73 #include <Geom_TrimmedCurve.hxx>
74 #include <Geom_Plane.hxx>
75 #include <Geom_RectangularTrimmedSurface.hxx>
76 #include <Geom_BezierSurface.hxx>
77 #include <Geom_Line.hxx>
78 #include <Geom_Conic.hxx>
79 #include <Geom_BSplineCurve.hxx>
80 #include <Geom_BSplineSurface.hxx>
81 #include <GeomFill_BSplineCurves.hxx>
82 #include <GeomConvert_ApproxCurve.hxx>
83 #include <GeomConvert.hxx>
85 #include <TColgp_SequenceOfPnt.hxx>
86 #include <TColgp_HArray1OfPnt.hxx>
87 #include <TColgp_Array2OfPnt.hxx>
88 #include <TColStd_HSequenceOfTransient.hxx>
90 #include <Precision.hxx>
91 #include <Standard_NullObject.hxx>
92 #include <Standard_TypeMismatch.hxx>
93 #include <Standard_ConstructionError.hxx>
95 #include "utilities.h"
97 //=======================================================================
100 //=======================================================================
101 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
103 static Standard_GUID aPipeDriver("FF1BBB19-5D14-4df2-980B-3A668264EA16");
107 //=======================================================================
108 //function : GEOMImpl_PipeDriver
110 //=======================================================================
111 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
115 //=======================================================================
116 //function : FillForOtherEdges
117 //purpose : auxilary for CreatePipeForShellSections()
118 //=======================================================================
119 static bool FillForOtherEdges(const TopoDS_Shape& F1,
120 const TopoDS_Shape& E1,
121 const TopoDS_Shape& V1,
122 TopTools_IndexedDataMapOfShapeShape& FF)
124 //cout<<"FillForOtherEdges"<<endl;
125 // find other pairs for vertexes and edges
126 // creating map of vertex edges for both faces
127 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
128 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
129 if (!FF.Contains(F1))
130 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
131 if (!FF.Contains(E1))
132 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
133 if (!FF.Contains(V1))
134 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
135 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
136 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
137 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
138 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
139 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
141 TopoDS_Edge ES1 = TopoDS::Edge(E1);
142 TopoDS_Edge ES2 = TopoDS::Edge(E2);
143 TopoDS_Shape VS1 = V1;
144 TopoDS_Shape VS2 = V2;
146 ShapeAnalysis_Edge sae;
148 if (!aMapVertEdge1.Contains(VS1))
149 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
150 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
151 //TopoDS_Shape E1next;
152 TopTools_ListIteratorOfListOfShape anIter1(aList1);
153 if (anIter1.Value().IsSame(ES1)) {
156 //E1next = anIter1.Value();
157 if (!aMapVertEdge2.Contains(VS2))
158 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
159 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
160 //TopoDS_Shape E2next;
161 TopTools_ListIteratorOfListOfShape anIter2(aList2);
162 if (anIter2.Value().IsSame(ES2)) {
165 //E2next = anIter2.Value();
166 //ES1 = TopoDS::Edge(E1next);
167 //ES2 = TopoDS::Edge(E2next);
168 ES1 = TopoDS::Edge(anIter1.Value());
169 ES2 = TopoDS::Edge(anIter2.Value());
170 if (!FF.Contains(ES1)) {
173 if (VS1.IsSame(sae.FirstVertex(ES1)))
174 VS1 = sae.LastVertex(ES1);
176 VS1 = sae.FirstVertex(ES1);
177 if (VS2.IsSame(sae.FirstVertex(ES2)))
178 VS2 = sae.LastVertex(ES2);
180 VS2 = sae.FirstVertex(ES2);
183 if (!FF.Contains(VS1)) {
191 //=======================================================================
192 //function : FillCorrespondingEdges
193 //purpose : auxilary for CreatePipeForShellSections()
194 //=======================================================================
195 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
196 const TopoDS_Shape& FS2,
197 const TopoDS_Vertex& aLoc1,
198 const TopoDS_Vertex& aLoc2,
199 const TopoDS_Wire& aWirePath,
200 TopTools_IndexedDataMapOfShapeShape& FF)
202 //cout<<"FillCorrespondingEdges"<<endl;
203 // find corresponding edges
204 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
205 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
206 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
207 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
208 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
209 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
210 aBuilder.Add(aWire1, aLoc1);
211 aBuilder.Add(aWire2, aLoc2);
212 if (!aBuilder.IsReady()) {
216 TopoDS_Shape aShape = aBuilder.Shape();
224 BRepTools::Write(C,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
226 ShapeAnalysis_Edge sae;
227 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
228 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
229 TopTools_MapOfShape Vs1,Vs2;
231 exp.Init(FS1, TopAbs_EDGE);
232 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
233 TopoDS_Vertex V11 = sae.FirstVertex(E1);
234 TopoDS_Vertex V21 = sae.LastVertex(E1);
235 gp_Pnt P11 = BRep_Tool::Pnt(V11);
236 gp_Pnt P21 = BRep_Tool::Pnt(V21);
237 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
238 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
239 // find corresponding vertexes from created shape
240 TopoDS_Vertex VN11,VN21;
241 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
242 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
243 gp_Pnt P = BRep_Tool::Pnt(V);
244 if (P.Distance(P11)<tol) {
247 if (P.Distance(P21)<tol) {
251 // find edge contains VN11 and VN21 and corresponding vertexes
252 TopoDS_Vertex VN12,VN22;
253 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
254 TopoDS_Shape F = exp.Current();
255 TopExp_Explorer expe;
257 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
258 TopoDS_Edge E = TopoDS::Edge(expe.Current());
259 TopoDS_Vertex VF = sae.FirstVertex(E);
260 TopoDS_Vertex VL = sae.LastVertex(E);
261 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
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))
273 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
275 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
277 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
283 // find vertexes from FS2 corresponded to VN12 and VN22
284 // and find edge from FS2 contains V12 and V22,
285 // this edge will be corresponded to edge E1
286 TopoDS_Vertex V12,V22;
287 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
288 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
289 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
290 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
292 TopExp_Explorer expe;
293 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
294 TopoDS_Edge E = TopoDS::Edge(expe.Current());
295 TopoDS_Vertex VF = sae.FirstVertex(E);
296 TopoDS_Vertex VL = sae.LastVertex(E);
297 gp_Pnt PF = BRep_Tool::Pnt(VF);
298 gp_Pnt PL = BRep_Tool::Pnt(VL);
299 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
305 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
316 // find other pairs for vertexes and edges
317 // creating map of vertex edges for both faces
318 return FillForOtherEdges(FS1,E1,V21,FF);
323 //=======================================================================
324 //function : FillCorrespondingEdges
325 //purpose : auxilary for CreatePipeShellsWithoutPath()
326 //=======================================================================
327 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
328 const TopoDS_Shape& FS2,
329 const TopoDS_Vertex& aLoc1,
330 const TopoDS_Vertex& aLoc2,
331 TopTools_IndexedDataMapOfShapeShape& FF)
333 //cout<<"FillCorrespondingEdges"<<endl;
335 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
336 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
339 ShapeAnalysis_Edge sae;
340 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
341 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
342 TopTools_MapOfShape Vs1,Vs2;
344 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
347 TopExp_Explorer exp1;
348 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
349 E1 = TopoDS::Edge(exp1.Current());
350 TopoDS_Vertex V1 = sae.FirstVertex(E1);
351 TopoDS_Vertex V2 = sae.LastVertex(E1);
352 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
353 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
354 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
355 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
356 if (P1.Distance(Ptmp1)<tol) {
360 if (P1.Distance(Ptmp2)<tol) {
367 TopoDS_Vertex VE21,VE22;
369 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
370 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
371 TopoDS_Vertex V1 = sae.FirstVertex(E);
372 TopoDS_Vertex V2 = sae.LastVertex(E);
373 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
374 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
375 if (P2.Distance(Ptmp1)<tol) {
387 if (P2.Distance(Ptmp2)<tol) {
401 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
402 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
403 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
404 gp_Vec aDir1(PV21,PE21);
405 gp_Vec aDir2(PV21,PE22);
406 double ang1 = aDir.Angle(aDir1);
407 double ang2 = aDir.Angle(aDir2);
408 if (fabs(ang1)<fabs(ang2)) {
421 // find other pairs for vertexes and edges
422 return FillForOtherEdges(FS1,E1,V21,FF);
425 //=======================================================================
426 //function : FindNextPairOfFaces
427 //purpose : auxilary for CreatePipeForShellSections()
428 //=======================================================================
429 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
430 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
431 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
432 TopTools_IndexedDataMapOfShapeShape& FF,
435 //cout<<"FindNextPairOfFaces"<<endl;
436 TopExp_Explorer anExp;
437 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
438 TopoDS_Shape E1 = anExp.Current();
439 if (!FF.Contains(E1)) {
441 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
443 if (!FF.Contains(E1))
444 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
445 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
446 TopExp_Explorer anExpV;
447 anExpV.Init(E1, TopAbs_VERTEX);
448 TopoDS_Shape V1 = anExpV.Current();
449 if (!FF.Contains(V1)) {
451 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
454 if (!aMapEdgeFaces1.Contains(E1))
455 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
456 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
457 if (aList1.Extent()<2)
459 TopTools_ListIteratorOfListOfShape anIter(aList1);
460 if (anIter.Value().IsEqual(aCurFace)) {
463 TopoDS_Shape F1other = anIter.Value();
464 if (FF.Contains(F1other))
467 if (!FF.Contains(aCurFace))
468 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
469 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
470 if (!aMapEdgeFaces2.Contains(E2))
471 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
472 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
473 if (aList2.Extent()<2) {
475 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
477 TopTools_ListIteratorOfListOfShape anIter2(aList2);
478 if (anIter2.Value().IsEqual(F2)) {
481 TopoDS_Shape F2other = anIter2.Value();
482 FF.Add(F1other,F2other);
484 // add pairs of edges to FF
485 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
488 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
491 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
495 //=======================================================================
496 //function : FindFirstPairFaces
497 //purpose : auxilary for Execute()
498 //=======================================================================
499 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
500 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
501 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
503 //cout<<"FindFirstPairFaces"<<endl;
505 // check if vertexes are subshapes of sections
506 gp_Pnt P1 = BRep_Tool::Pnt(V1);
507 gp_Pnt P2 = BRep_Tool::Pnt(V2);
508 TopoDS_Vertex V1new,V2new;
510 double mindist = 1.e10;
511 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
512 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
513 gp_Pnt P = BRep_Tool::Pnt(V);
514 double dist = P1.Distance(P);
521 for (exp.Init(S2, 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 = P2.Distance(P);
531 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
532 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
533 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
534 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
535 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
536 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
538 // replace vertexes if it is needed
539 if (!V1.IsSame(V1new)) {
541 P1 = BRep_Tool::Pnt(V1);
542 MESSAGE (" replace V1");
545 MESSAGE (" not replace V1");
546 if (!V2.IsSame(V2new)) {
548 P2 = BRep_Tool::Pnt(V2);
549 MESSAGE (" replace V2");
552 MESSAGE (" not replace V2");
554 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
555 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
556 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
557 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
559 if (!aMapVertFaces1.Contains(V1))
560 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
561 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
562 TopTools_ListIteratorOfListOfShape anIter1(aList1);
563 FS1 = anIter1.Value();
565 double x1=0., y1=0., z1=0.;
567 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
568 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
569 gp_Pnt P = BRep_Tool::Pnt(V);
575 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
577 TColgp_SequenceOfPnt Ps;
578 TopTools_SequenceOfShape Fs;
579 if (!aMapVertFaces2.Contains(V2))
580 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
581 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
582 TopTools_ListIteratorOfListOfShape anIter2(aList2);
583 for (; anIter2.More(); anIter2.Next()) {
584 TopoDS_Shape F = anIter2.Value();
585 double x2=0., y2=0., z2=0.;
587 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
588 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
589 gp_Pnt P = BRep_Tool::Pnt(V);
595 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
602 double MinAng = M_PI;
604 for (; i<=Fs.Length(); i++) {
605 gp_Vec tmpDir(PM1,Ps(i));
606 double ang = fabs(aDir.Angle(tmpDir));
615 //=======================================================================
616 //function : CreatePipeWithDifferentSections
618 //=======================================================================
619 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
620 (const TopoDS_Wire& theWirePath,
621 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
622 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
623 const Standard_Boolean theWithContact,
624 const Standard_Boolean theWithCorrect)
628 TopoDS_Wire aWirePath = theWirePath;
630 Standard_Integer nbBases = theHSeqBases->Length();
631 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
633 if (nbLocs && nbLocs != nbBases) {
634 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
637 TopTools_SequenceOfShape aSeqBases;
638 TopTools_SequenceOfShape aSeqLocs;
639 TopTools_SequenceOfShape aSeqFaces;
641 Standard_Integer i = 1;
642 for (i = 1; i <= nbBases; i++) {
643 if (theHSeqBases->Value(i).IsNull())
646 // Make copy to prevent modifying of base object 0020766 : EDF 1320
647 TopoDS_Shape aShapeBase;
648 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
650 aShapeBase = Copy.Shape();
652 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
654 //if for section was specified face with a few wires then a few
655 // pipes were build and make solid
656 Standard_Boolean NeedCreateSolid = Standard_False;
657 if (aTypeBase == TopAbs_SHELL) {
658 // create wire as boundary contour if shell is no closed
659 // get free boundary shapes
660 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
661 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
662 TopExp_Explorer anExp;
664 Standard_Integer NbWires = 0;
665 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
667 aWire = anExp.Current();
671 Standard_ConstructionError::Raise("Bad shell is used as section ");
673 NeedCreateSolid = Standard_True;
674 aSeqFaces.Append(aShapeBase);
675 aSeqBases.Append(aWire);
677 else if (aTypeBase == TopAbs_FACE) {
678 NeedCreateSolid = Standard_True;
679 //for case one path should be used other type function
680 aSeqFaces.Append(aShapeBase);
681 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
682 for (; aExpW.More(); aExpW.Next()) {
683 TopoDS_Shape aWireProf = aExpW.Current();
684 aSeqBases.Append(aWireProf);
687 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
688 aSeqBases.Append(aShapeBase);
690 else if (aTypeBase == TopAbs_EDGE) {
691 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
692 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
693 aSeqBases.Append(aWireProf);
696 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
697 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
699 aSeqLocs.Append(aShapeLoc);
703 nbLocs = aSeqLocs.Length();
706 TopTools_SequenceOfShape Edges;
708 // we have to check that each location shape is a vertex from
709 // path and update aSeqLocs if it is needed (and possible)
710 TColgp_SequenceOfPnt PLocs;
711 for (i=1; i<=nbLocs; i++) {
712 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
713 PLocs.Append(BRep_Tool::Pnt(V));
715 //TopTools_SequenceOfShape Edges;
716 TopExp_Explorer anExp;
717 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
718 Edges.Append(anExp.Current());
720 int nbEdges = Edges.Length();
721 ShapeAnalysis_Edge sae;
722 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
723 double tol = BRep_Tool::Tolerance(edge);
724 TopoDS_Vertex VF = sae.FirstVertex(edge);
725 gp_Pnt PF = BRep_Tool::Pnt(VF);
726 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
727 if (PF.Distance(PLocs.First()) > tol) {
728 Standard_ConstructionError::Raise
729 ("First location shapes is not coincided with first vertex of aWirePath");
731 aSeqLocs.ChangeValue(1) = VF;
732 edge = TopoDS::Edge(Edges.Last());
733 tol = BRep_Tool::Tolerance(edge);
734 TopoDS_Vertex VL = sae.LastVertex(edge);
735 gp_Pnt PL = BRep_Tool::Pnt(VL);
736 if (PL.Distance(PLocs.Last()) > tol) {
737 Standard_ConstructionError::Raise
738 ("Last location shapes is not coincided with last vertex of aWirePath");
740 aSeqLocs.ChangeValue(nbLocs) = VL;
742 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
743 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
744 tol = BRep_Tool::Tolerance(edge);
745 TopoDS_Vertex V1 = sae.FirstVertex(E);
746 TopoDS_Vertex V2 = sae.LastVertex(E);
747 gp_Pnt P1 = BRep_Tool::Pnt(V1);
748 gp_Pnt P2 = BRep_Tool::Pnt(V2);
749 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
750 aSeqLocs.ChangeValue(jcurr) = V2;
754 // find distance between E and aLocs(jcurr)
756 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
757 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
758 if (PPCurve.NbPoints()>0 &&
759 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
760 double param = PPCurve.Parameter(1);
763 // split current edge
764 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
765 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
770 if (Pfp.Distance(P1)<tol) {
771 B.MakeEdge(E1,tc1,tol);
773 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
774 B.Add(E1,TopoDS::Vertex(tmpV));
775 B.MakeEdge(E2,tc2,tol);
776 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
777 B.Add(E2,TopoDS::Vertex(tmpV));
781 B.MakeEdge(E1,tc2,tol);
782 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
783 B.Add(E1,TopoDS::Vertex(tmpV));
786 B.MakeEdge(E2,tc1,tol);
788 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
789 B.Add(E2,TopoDS::Vertex(tmpV));
794 Edges.InsertAfter(i-1,E1);
795 Edges.InsertAfter(i,E2);
799 if (nbEdges<Edges.Length()) {
800 // one of edges was splitted => we have to update WirePath
804 for (i=1; i<=Edges.Length(); i++) {
805 B.Add(W,TopoDS::Edge(Edges.Value(i)));
811 // check curvature of wire for condition that
812 // max summary angle between directions along
813 // wire path must be < 4*PI. If not - split wire
814 // and seguences of shapes, perform pipe for each
815 // and make sewing after that
817 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
822 double SumAng = fabs(Vec1.Angle(Vec2));
825 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
827 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
828 for (i=2; i<=Edges.Length(); i++) {
829 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
830 double tol = BRep_Tool::Tolerance(edge);
831 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
833 double ang = fabs(Vec1.Angle(Vec2));
837 SplitEdgeNums.Append(i-1);
839 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
840 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
841 gp_Pnt P = BRep_Tool::Pnt(aVert);
842 if (P1.Distance(P) < tol) {
843 SplitLocNums.Append(j);
853 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
854 TopTools_SequenceOfShape aSeqRes;
855 int nn, num1 = 1, num2 = 1;
856 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
857 // create wirepath and sequences of shapes
861 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
862 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
864 num1 = SplitEdgeNums.Value(nn) + 1;
865 TopTools_SequenceOfShape aTmpSeqBases;
866 TopTools_SequenceOfShape aTmpSeqLocs;
867 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
868 aTmpSeqBases.Append(aSeqBases.Value(i));
869 aTmpSeqLocs.Append(aSeqLocs.Value(i));
871 num2 = SplitLocNums.Value(nn);
873 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
874 Standard_Integer nbShapes = aTmpSeqBases.Length();
875 for (i=1; i<=nbShapes; i++) {
876 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
877 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
878 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
880 if (!aBuilder.IsReady()) {
881 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
884 TopoDS_Shape resShape = aBuilder.Shape();
885 aSeqRes.Append(resShape);
887 // create wirepath and sequences of shapes for last part
891 for (i=num1; i<=Edges.Length(); i++) {
892 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
894 TopTools_SequenceOfShape aTmpSeqBases;
895 TopTools_SequenceOfShape aTmpSeqLocs;
896 for (i=num2; i<=aSeqLocs.Length(); i++) {
897 aTmpSeqBases.Append(aSeqBases.Value(i));
898 aTmpSeqLocs.Append(aSeqLocs.Value(i));
900 // make pipe for last part
901 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
902 Standard_Integer nbShapes = aTmpSeqBases.Length();
903 for (i=1; i<=nbShapes; i++) {
904 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
905 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
906 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
908 if (!aBuilder.IsReady()) {
909 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
912 TopoDS_Shape resShape = aBuilder.Shape();
913 aSeqRes.Append(resShape);
914 // make sewing for result
915 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
916 aSewing->SetTolerance(Precision::Confusion());
917 aSewing->SetFaceMode(Standard_True);
918 aSewing->SetFloatingEdgesMode(Standard_False);
919 aSewing->SetNonManifoldMode(Standard_False);
920 for (i=1; i<=aSeqRes.Length(); i++) {
921 aSewing->Add(aSeqRes.Value(i));
924 aShape = aSewing->SewedShape();
927 // old implementation without splitting
928 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
930 Standard_Integer nbShapes = aSeqBases.Length();
931 Standard_Integer step = nbShapes/nbBases;
933 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
934 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
936 Standard_Integer ind =0;
937 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
938 TopTools_SequenceOfShape usedBases;
939 Standard_Integer j = 1;
940 for (; j <= nbBases; j++) {
941 ind = i + (j-1)*step;
942 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
943 usedBases.Append(aWireProf);
945 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
946 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
947 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
950 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
952 if (!aBuilder.IsReady()) {
953 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
956 aShape = aBuilder.Shape();
957 aSeqFaces.Append(aShape);
958 for (j = 1; j <=usedBases.Length(); j++)
959 aBuilder.Delete(usedBases.Value(j));
962 //for case if section is face
963 if (aSeqFaces.Length() >1) {
965 TopoDS_Compound aComp;
966 aB.MakeCompound(aComp);
967 for (i = 1; i <= aSeqFaces.Length(); i++)
968 aB.Add(aComp,aSeqFaces.Value(i));
976 //=======================================================================
977 //function : CreatePipeForShellSections
978 //purpose : auxilary for Execute()
979 //=======================================================================
980 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
983 //cout<<"CreatePipeForShellSections"<<endl;
988 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
989 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
990 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
991 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
992 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
993 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
995 Standard_Integer nbBases = aBasesObjs->Length(),
996 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
997 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
999 if (nbLocs != nbBases) {
1000 if (aCI) delete aCI;
1001 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1003 if (nbSubBases && nbSubBases != nbBases) {
1004 if (aCI) delete aCI;
1005 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1008 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1010 TopTools_SequenceOfShape VLocs;
1011 for (i=1; i<=nbBases; i++) {
1012 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1013 if (anItemLoc.IsNull())
1015 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1016 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1017 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1019 VLocs.Append(aShapeLoc);
1021 nbLocs = VLocs.Length();
1022 if (nbLocs != nbBases) {
1023 if (aCI) delete aCI;
1024 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1026 // split wire path by location points
1027 TColgp_SequenceOfPnt PLocs;
1028 for (i=1; i<=nbLocs; i++) {
1029 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1030 PLocs.Append(BRep_Tool::Pnt(V));
1033 TopTools_SequenceOfShape Edges;
1034 TopTools_SequenceOfShape Wires;
1035 ShapeAnalysis_Edge sae;
1038 TopExp_Explorer anExp;
1039 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1040 Edges.Append(anExp.Current());
1042 Standard_Integer Num1 = 0;
1043 Standard_Integer Num2 = 0;
1044 for (i=1; i<=Edges.Length(); i++) {
1045 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1046 double tol = BRep_Tool::Tolerance(E);
1047 TopoDS_Vertex V1 = sae.FirstVertex(E);
1048 TopoDS_Vertex V2 = sae.LastVertex(E);
1049 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1050 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1051 if (P1.Distance(PLocs.First()) < tol) {
1054 if (P2.Distance(PLocs.Last()) < tol) {
1058 if (Num1>0 && Num2>0) {
1061 for (i=Num1; i<=Num2; i++) {
1062 B.Add(W,Edges.Value(i));
1067 Wires.Append(aWirePath);
1071 TopExp_Explorer anExp;
1072 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1073 Edges.Append(anExp.Current());
1075 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1076 double tol = BRep_Tool::Tolerance(edge);
1077 TopoDS_Vertex VF = sae.FirstVertex(edge);
1078 gp_Pnt PF = BRep_Tool::Pnt(VF);
1079 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1080 if (PF.Distance(PLocs.First()) > tol) {
1081 if (aCI) delete aCI;
1082 Standard_ConstructionError::Raise
1083 ("First location shapes is not coincided with first vertex of aWirePath");
1085 VLocs.ChangeValue(1) = VF;
1086 edge = TopoDS::Edge(Edges.Last());
1087 tol = BRep_Tool::Tolerance(edge);
1088 TopoDS_Vertex VL = sae.LastVertex(edge);
1089 gp_Pnt PL = BRep_Tool::Pnt(VL);
1090 if (PL.Distance(PLocs.Last()) > tol) {
1091 if (aCI) delete aCI;
1092 Standard_ConstructionError::Raise
1093 ("Last location shapes is not coincided with last vertex of aWirePath");
1095 VLocs.ChangeValue(nbLocs) = VL;
1097 TopTools_SequenceOfShape tmpEdges;
1098 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1099 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1100 tol = BRep_Tool::Tolerance(E);
1101 TopoDS_Vertex V1 = sae.FirstVertex(E);
1102 TopoDS_Vertex V2 = sae.LastVertex(E);
1103 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1104 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1105 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1106 // make wire from current edge and add created
1110 for (j=1; j<=tmpEdges.Length(); j++)
1111 B.Add(W,tmpEdges.Value(j));
1114 VLocs.ChangeValue(jcurr) = V2;
1119 // find distance between E and aLocs(jcurr)
1121 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1122 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1123 if (PPCurve.NbPoints()>0 &&
1124 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1125 double param = PPCurve.Parameter(1);
1128 // split current edge
1129 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1130 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1134 if (Pfp.Distance(P1)<tol) {
1135 B.MakeEdge(E1,tc1,tol);
1137 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1138 B.Add(E1,TopoDS::Vertex(tmpV));
1139 tmpEdges.Append(E1);
1140 B.MakeEdge(E2,tc2,tol);
1141 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1142 B.Add(E2,TopoDS::Vertex(tmpV));
1146 B.MakeEdge(E1,tc2,tol);
1147 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1148 B.Add(E1,TopoDS::Vertex(tmpV));
1151 tmpEdges.Append(E1);
1152 B.MakeEdge(E2,tc1,tol);
1154 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1155 B.Add(E2,TopoDS::Vertex(tmpV));
1158 // create wire from tmpEdges
1161 for (j=1; j<=tmpEdges.Length(); j++)
1162 B.Add(W,tmpEdges.Value(j));
1167 Edges.InsertAfter(i-1,E1);
1168 Edges.InsertAfter(i,E2);
1175 // create wire from other edges
1178 for (; i<=Edges.Length(); i++)
1179 B.Add(W,Edges.Value(i));
1181 //cout<<"Wires.Length()="<<Wires.Length()<<endl;
1184 if (Wires.Length() != nbLocs-1) {
1185 if (aCI) delete aCI;
1186 Standard_ConstructionError::Raise
1187 ("One of location shapes is not lied on the path");
1190 //TopTools_SequenceOfShape aSeqBases;
1191 //TopTools_SequenceOfShape aSeqSubBases;
1192 //TopTools_SequenceOfShape aSeqFaces;
1193 TopoDS_Compound aComp;
1194 B.MakeCompound(aComp);
1195 for (i = 1; i < nbBases; i++) {
1196 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1198 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1199 if (anItem1.IsNull())
1201 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1202 if (aRefBase1.IsNull())
1204 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1205 if (aShBase1.IsNull())
1207 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1209 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1210 if (anItem2.IsNull())
1212 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1213 if (aRefBase2.IsNull())
1215 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1216 if (aShBase2.IsNull())
1218 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1220 //BRepTools::Write(aShBase1,"/dn02/users_Linux/skl/work/Bugs/14857/base1.brep");
1222 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1223 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1225 if (aCI) delete aCI;
1226 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1229 bool CreateFewSolids = false;
1231 TopExp_Explorer anExp;
1232 Standard_Integer nbf1 = 0;
1233 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1236 Standard_Integer nbf2 = 0;
1237 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1241 CreateFewSolids = true;
1245 // check orientation of sections
1246 bool NeedReverse = false;
1249 anExp.Init(aShBase1, TopAbs_FACE);
1250 TopoDS_Shape aFace = anExp.Current();
1251 TColgp_SequenceOfPnt aPnts;
1252 double xc=0, yc=0, zc=0;
1253 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1254 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1255 aPnts.Append(BRep_Tool::Pnt(V));
1256 xc += aPnts.Last().X();
1257 yc += aPnts.Last().Y();
1258 zc += aPnts.Last().Z();
1260 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1261 gp_Vec V1(PC,aPnts.Value(1));
1262 gp_Vec V2(PC,aPnts.Value(2));
1263 gp_Vec VN = V1.Crossed(V2);
1264 for (int ip=2; ip<aPnts.Length(); ip++) {
1265 V1 = gp_Vec(PC,aPnts.Value(ip));
1266 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1267 VN.Add(V1.Crossed(V2));
1270 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i)));
1272 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1273 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1274 double tol = BRep_Tool::Tolerance(edge);
1275 TopoDS_Vertex VF = sae.FirstVertex(edge);
1276 gp_Pnt PF = BRep_Tool::Pnt(VF);
1277 if (PF.Distance(PLoc) < tol) {
1279 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1282 if (P1.Distance(PLoc) < tol) {
1283 C->D0(fp+(lp-fp)/100,P2);
1287 C->D0(lp+(fp-lp)/100,P2);
1289 PathNorm = gp_Vec(P1,P2);
1293 TopoDS_Vertex VL = sae.LastVertex(edge);
1294 gp_Pnt PL = BRep_Tool::Pnt(VL);
1295 if (PL.Distance(PLoc) < tol) {
1297 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1300 if (P1.Distance(PLoc) < tol) {
1301 C->D0(fp+(lp-fp)/100,P2);
1305 C->D0(lp+(fp-lp)/100,P2);
1307 PathNorm = gp_Vec(P2,P1);
1312 cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1313 cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1314 if (fabs(VN.Angle(PathNorm))>PI/2.) {
1321 anExp.Init(aShBase2, TopAbs_FACE);
1322 TopoDS_Shape aFace = anExp.Current();
1323 TColgp_SequenceOfPnt aPnts;
1324 double xc=0, yc=0, zc=0;
1325 for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
1326 TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
1327 aPnts.Append(BRep_Tool::Pnt(V));
1328 xc += aPnts.Last().X();
1329 yc += aPnts.Last().Y();
1330 zc += aPnts.Last().Z();
1332 gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
1333 gp_Vec V1(PC,aPnts.Value(1));
1334 gp_Vec V2(PC,aPnts.Value(2));
1335 gp_Vec VN = V1.Crossed(V2);
1336 for (int ip=2; ip<aPnts.Length(); ip++) {
1337 V1 = gp_Vec(PC,aPnts.Value(ip));
1338 V2 = gp_Vec(PC,aPnts.Value(ip+1));
1339 VN.Add(V1.Crossed(V2));
1342 gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i+1)));
1344 for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
1345 TopoDS_Edge edge = TopoDS::Edge(WE.Current());
1346 double tol = BRep_Tool::Tolerance(edge);
1347 TopoDS_Vertex VF = sae.FirstVertex(edge);
1348 gp_Pnt PF = BRep_Tool::Pnt(VF);
1349 if (PF.Distance(PLoc) < tol) {
1351 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1354 if (P1.Distance(PLoc) < tol) {
1355 C->D0(fp+(lp-fp)/100,P2);
1359 C->D0(lp+(fp-lp)/100,P2);
1361 PathNorm = gp_Vec(P2,P1);
1365 TopoDS_Vertex VL = sae.LastVertex(edge);
1366 gp_Pnt PL = BRep_Tool::Pnt(VL);
1367 if (PL.Distance(PLoc) < tol) {
1369 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1372 if (P1.Distance(PLoc) < tol) {
1373 C->D0(fp+(lp-fp)/100,P2);
1377 C->D0(lp+(fp-lp)/100,P2);
1379 PathNorm = gp_Vec(P2,P1);
1384 //cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
1385 //cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
1386 if (fabs(VN.Angle(PathNorm))>PI/2.)
1391 if (!CreateFewSolids) {
1392 // we can create only one solid
1393 TopoDS_Shape aWire1, aWire2;
1395 if (aType1==TopAbs_SHELL) {
1396 // create wire as boundary contour if shell is no closed
1397 // get free boundary shapes
1398 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1399 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1400 //TopExp_Explorer anExp;
1401 Standard_Integer NbWires = 0;
1402 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1404 aWire1 = anExp.Current();
1408 if (aCI) delete aCI;
1409 Standard_ConstructionError::Raise("Bad shell is used as section ");
1412 else { // aType1==TopAbs_FACE
1413 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1414 aWire1 = aExpW.Current();
1417 if (aType2==TopAbs_SHELL) {
1418 // create wire as boundary contour if shell is no closed
1419 // get free boundary shapes
1420 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1421 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1422 //TopExp_Explorer anExp;
1423 Standard_Integer NbWires = 0;
1424 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1426 aWire2 = anExp.Current();
1430 if (aCI) delete aCI;
1431 Standard_ConstructionError::Raise("Bad shell is used as section ");
1434 else { // aType2==TopAbs_FACE
1435 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1436 aWire2 = aExpW.Current();
1438 // make pipe using aWire1 and aWire2
1439 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1440 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1441 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1442 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1443 aWithContact, aWithCorrect);
1444 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1445 aWithContact, aWithCorrect);
1446 if (!aBuilder.IsReady()) {
1447 if (aCI) delete aCI;
1448 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1451 TopoDS_Shape aShape = aBuilder.Shape();
1452 TopoDS_Shell aShell;
1453 B.MakeShell(aShell);
1454 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1455 B.Add(aShell,anExp.Current());
1457 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1458 B.Add(aShell,anExp.Current());
1460 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1461 B.Add(aShell,anExp.Current());
1463 // make sewing for this shell
1464 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1465 aSewing->SetTolerance(Precision::Confusion());
1466 aSewing->SetFaceMode(Standard_True);
1467 aSewing->SetFloatingEdgesMode(Standard_False);
1468 aSewing->SetNonManifoldMode(Standard_False);
1469 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1470 aSewing->Add(anExp.Current());
1473 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1474 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1475 aShell = TopoDS::Shell(aSewShape);
1476 GProp_GProps aSystem;
1477 BRepGProp::VolumeProperties(aShell, aSystem);
1478 if (aSystem.Mass()<0) {
1481 if (BRep_Tool::IsClosed(aShell)) {
1482 TopoDS_Solid aSolid;
1483 B.MakeSolid(aSolid);
1484 B.Add(aSolid,aShell);
1485 B.Add(aComp,aSolid);
1488 B.Add(aComp,aShell);
1492 B.Add(aComp,aShell);
1497 // main block - creation few solids (for each pair of faces)
1498 TopTools_MapOfShape aFaces1,aFaces2;
1499 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1500 aFaces1.Add(anExp.Current());
1502 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1503 aFaces2.Add(anExp.Current());
1505 // creating map of edge faces
1506 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1507 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1508 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1509 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1511 // constuct map face->face
1512 TopTools_IndexedDataMapOfShapeShape FF;
1513 TopoDS_Shape FS1,FS2;
1514 if (nbSubBases==0) {
1515 // find edge the most distant from location point
1516 // (this edge is not shared by two faces)
1517 double maxdist = 0.;
1519 TopoDS_Vertex V11,V21;
1520 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1521 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1522 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1523 if (aList.Extent()>1)
1525 TopExp_Explorer expv;
1526 expv.Init(tmp, TopAbs_VERTEX);
1527 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1529 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1530 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1531 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1532 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1537 TopTools_ListIteratorOfListOfShape anIter(aList);
1538 FS1 = anIter.Value();
1542 // main direction for comparing
1543 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1544 // find corresponding edge from next section
1545 double minang = M_PI;
1546 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1547 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1549 TopoDS_Vertex V12,V22;
1550 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1551 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1552 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1553 if (aList.Extent()>1)
1555 TopExp_Explorer expv;
1556 expv.Init(tmp, TopAbs_VERTEX);
1557 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1559 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1560 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1561 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1562 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1563 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1564 TopoDS_Vertex V1,V2;
1567 V1 = V2tmp; P1 = P2tmp;
1568 V2 = V1tmp; P2 = P1tmp;
1571 V1 = V1tmp; P1 = P1tmp;
1572 V2 = V2tmp; P2 = P2tmp;
1574 gp_Vec Vec1(P11,P1);
1575 gp_Vec Vec2(P21,P2);
1576 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1581 TopTools_ListIteratorOfListOfShape anIter(aList);
1582 FS2 = anIter.Value();
1586 // put all pairs to map FF
1592 // add pairs of edges to FF
1593 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1595 if (aCI) delete aCI;
1596 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1602 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1603 if (anItem.IsNull()) {
1604 if (aCI) delete aCI;
1605 Standard_ConstructionError::Raise("Invalid subbase shape");
1607 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1608 if (aRefBase.IsNull()) {
1609 if (aCI) delete aCI;
1610 Standard_ConstructionError::Raise("Invalid subbase shape");
1612 TopoDS_Shape aSh = aRefBase->GetValue();
1614 if (aCI) delete aCI;
1615 Standard_ConstructionError::Raise("Invalid subbase shape");
1617 if (aSh.ShapeType()!=TopAbs_FACE) {
1618 if (aCI) delete aCI;
1619 Standard_ConstructionError::Raise("Invalid subbase shape");
1624 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1625 if (anItem.IsNull()) {
1626 if (aCI) delete aCI;
1627 Standard_ConstructionError::Raise("Invalid subbase shape");
1629 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1630 if (aRefBase.IsNull()) {
1631 if (aCI) delete aCI;
1632 Standard_ConstructionError::Raise("Invalid subbase shape");
1634 TopoDS_Shape aSh = aRefBase->GetValue();
1636 if (aCI) delete aCI;
1637 Standard_ConstructionError::Raise("Invalid subbase shape");
1639 if (aSh.ShapeType()!=TopAbs_FACE) {
1640 if (aCI) delete aCI;
1641 Standard_ConstructionError::Raise("Invalid subbase shape");
1646 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1647 if (aCI) delete aCI;
1648 Standard_ConstructionError::Raise("Invalid subbase shape");
1653 // add pairs of edges to FF
1654 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1655 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1657 if (aCI) delete aCI;
1658 Standard_ConstructionError::Raise("Can not create correct pipe");
1662 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1664 // make pipe for each pair of faces
1665 for (j=1; j<=FF.Extent(); j++) {
1666 TopoDS_Shape F1 = FF.FindKey(j);
1667 if (F1.ShapeType() != TopAbs_FACE)
1669 TopoDS_Shape F2 = FF.FindFromIndex(j);
1670 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1671 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1672 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1673 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1674 // make pipe using aWire1 and aWire2
1675 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1676 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1677 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1678 aWithContact, aWithCorrect);
1679 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1680 aWithContact, aWithCorrect);
1681 if (!aBuilder.IsReady()) {
1682 if (aCI) delete aCI;
1683 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1686 TopoDS_Shape aShape = aBuilder.Shape();
1687 TopoDS_Shell aShell;
1688 B.MakeShell(aShell);
1689 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1690 B.Add(aShell,anExp.Current());
1695 // make sewing for this shell
1696 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1697 aSewing->SetTolerance(Precision::Confusion());
1698 aSewing->SetFaceMode(Standard_True);
1699 aSewing->SetFloatingEdgesMode(Standard_False);
1700 aSewing->SetNonManifoldMode(Standard_False);
1701 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1702 aSewing->Add(anExp.Current());
1705 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1706 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1707 aShell = TopoDS::Shell(aSewShape);
1708 GProp_GProps aSystem;
1709 BRepGProp::VolumeProperties(aShell, aSystem);
1710 if (aSystem.Mass()<0) {
1711 //cout<<"aSewShape is reversed"<<endl;
1714 if (BRep_Tool::IsClosed(aShell)) {
1715 TopoDS_Solid aSolid;
1716 B.MakeSolid(aSolid);
1717 B.Add(aSolid,aShell);
1718 B.Add(aComp,aSolid);
1721 B.Add(aComp,aShell);
1725 B.Add(aComp,aShell);
1733 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
1737 //=======================================================================
1738 //function : CreatePipeShellsWithoutPath
1739 //purpose : auxilary for Execute()
1740 //=======================================================================
1741 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
1743 //cout<<"CreatePipeShellsWithoutPath"<<endl;
1747 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1749 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1750 // vertex for recognition
1751 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
1753 Standard_Integer nbBases = aBasesObjs->Length(),
1754 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
1756 if (nbv != nbBases) {
1757 if (aCI) delete aCI;
1758 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
1761 TopTools_SequenceOfShape SecVs,Bases;
1762 for (i=1; i<=nbBases; i++) {
1764 Handle(Standard_Transient) anItem = VObjs->Value(i);
1765 if (anItem.IsNull())
1767 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
1768 TopoDS_Shape V = aRef->GetValue();
1769 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
1773 anItem = aBasesObjs->Value(i);
1774 if (anItem.IsNull())
1776 aRef = Handle(GEOM_Function)::DownCast(anItem);
1777 TopoDS_Shape aSh = aRef->GetValue();
1782 nbv = SecVs.Length();
1783 nbBases = Bases.Length();
1784 if (nbv != nbBases) {
1785 if (aCI) delete aCI;
1786 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
1789 TopoDS_Compound aComp;
1790 B.MakeCompound(aComp);
1792 for (i = 1; i < nbBases; i++) {
1793 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
1794 TopoDS_Shape aShBase1 = Bases.Value(i);
1795 TopoDS_Shape aShBase2 = Bases.Value(i+1);
1796 TopExp_Explorer anExp;
1797 Standard_Integer nbf1 = 0;
1798 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1801 Standard_Integer nbf2 = 0;
1802 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1805 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
1807 if (aCI) delete aCI;
1808 Standard_ConstructionError::Raise("Different number of faces in the sections");
1811 TopTools_MapOfShape aFaces1,aFaces2;
1812 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1813 aFaces1.Add(anExp.Current());
1815 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1816 aFaces2.Add(anExp.Current());
1819 // creating map of edge faces
1820 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1821 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1822 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1823 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1825 // constuct map face->face (and subshapes)
1826 TopTools_IndexedDataMapOfShapeShape FF;
1827 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
1828 TopoDS_Shape FS1, FS2;
1829 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
1830 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
1831 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
1834 MESSAGE (" first pair of corresponding faces is found");
1836 // add pairs of edges and vertexes to FF
1837 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
1839 if (aCI) delete aCI;
1840 Standard_ConstructionError::Raise("Can not create correct pipe");
1842 MESSAGE (" correspondences for subshapes of first pair of faces is found");
1844 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1845 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
1847 // make pipe for each pair of faces
1848 // auxilary map vertex->edge for created pipe edges
1849 TopTools_IndexedDataMapOfShapeShape VPE;
1850 ShapeAnalysis_Edge sae;
1851 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
1853 for (j=1; j<=FF.Extent(); j++) {
1854 TopoDS_Shape F1 = FF.FindKey(j);
1855 if (F1.ShapeType() != TopAbs_FACE)
1857 TopoDS_Shape F2 = FF.FindFromIndex(j);
1860 //if (nbff!=3) continue;
1862 MESSAGE (" make pipe for "<<nbff<<" face");
1864 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
1865 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1866 Handle(Geom_RectangularTrimmedSurface) RTS =
1867 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
1868 S1 = RTS->BasisSurface();
1870 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
1871 if (Pln1.IsNull()) {
1872 if (aCI) delete aCI;
1873 Standard_ConstructionError::Raise("Surface from face is not plane");
1875 gp_Vec aDir1(Pln1->Axis().Direction());
1877 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
1878 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1879 Handle(Geom_RectangularTrimmedSurface) RTS =
1880 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
1881 S2 = RTS->BasisSurface();
1883 Handle(Geom_Plane) Pln2 =
1884 Handle(Geom_Plane)::DownCast(S2);
1885 if (Pln2.IsNull()) {
1886 if (aCI) delete aCI;
1887 Standard_ConstructionError::Raise("Surface from face is not plane");
1889 gp_Vec aDir2(Pln2->Axis().Direction());
1891 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
1892 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
1894 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
1896 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
1899 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
1900 TopTools_SequenceOfShape aNewFs;
1902 for (; anExpE.More(); anExpE.Next()) {
1903 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
1905 if (!FF.Contains(E1))
1906 MESSAGE ("map FF not contains key E1");
1908 if (VPE.Contains(E1)) {
1909 aNewFs.Append(VPE.FindFromKey(E1));
1911 MESSAGE (" using existed face");
1916 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
1917 TopoDS_Vertex V1 = sae.FirstVertex(E1);
1918 TopoDS_Vertex V2 = sae.LastVertex(E1);
1919 if (!FF.Contains(V1))
1920 MESSAGE ("map FF not contains key V1");
1921 if (!FF.Contains(V2))
1922 MESSAGE ("map FF not contains key V2");
1923 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
1924 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
1925 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
1926 if (Vtmp.IsSame(V4))
1928 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1929 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1930 gp_Pnt P3 = BRep_Tool::Pnt(V3);
1931 gp_Pnt P4 = BRep_Tool::Pnt(V4);
1934 Handle(Geom_BSplineCurve) C2;
1935 if (VPE.Contains(V2)) {
1936 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
1938 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
1941 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
1942 HAP->SetValue(1,P2);
1943 HAP->SetValue(2,P3);
1944 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
1945 anInt.Load(aDir1,aDir2);
1948 B.MakeEdge(E2,C2,1.e-7);
1949 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
1950 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
1955 Handle(Geom_BSplineCurve) C4;
1956 if (VPE.Contains(V1)) {
1957 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
1959 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
1962 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
1963 HAP->SetValue(1,P1);
1964 HAP->SetValue(2,P4);
1965 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
1966 anInt.Load(aDir1,aDir2);
1969 B.MakeEdge(E4,anInt.Curve(),1.e-7);
1970 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
1971 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
1980 B.Add(W,E4.Reversed());
1981 //cout<<" wire for edge "<<nbee<<" is created"<<endl;
1982 //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
1987 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
1988 //bool IsConicC1 = false;
1989 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
1990 // IsConicC1 = true;
1991 // cout<<"C1 - Geom_Conic"<<endl;
1993 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
1994 C1 = new Geom_TrimmedCurve(C1,fp,lp);
1997 // double tol = BRep_Tool::Tolerance(E1);
1998 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
1999 // C1 = ApxC1.Curve();
2001 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2002 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2003 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2008 Handle(Geom_BSplineCurve) CE1 =
2009 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2010 if (CE1->Degree()<3)
2011 CE1->IncreaseDegree(3);
2012 Handle(Geom_BSplineCurve) CE2 =
2013 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2014 if (CE2->Degree()<3)
2015 CE2->IncreaseDegree(3);
2016 Handle(Geom_BSplineCurve) CE3 =
2017 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2018 if (CE3->Degree()<3)
2019 CE3->IncreaseDegree(3);
2020 Handle(Geom_BSplineCurve) CE4 =
2021 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2022 if (CE4->Degree()<3)
2023 CE4->IncreaseDegree(3);
2024 //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
2025 // <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
2026 //if (fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
2027 // os<<"DrawTrSurf_BSplineCurve"<<endl;
2028 // GeomTools::Write(CE1,os);
2032 Handle(Geom_Surface) BS;
2034 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2035 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2039 MESSAGE (" can not create BSplineSurface - create Bezier");
2041 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2042 double fp1,lp1,fp2,lp2;
2043 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2044 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2053 // get points from C1
2054 if (P1.Distance(P1C1)<1.e-6) {
2062 double step = (lp-fp)/(NbP-1);
2063 Points.SetValue(1,1,P1);
2065 for (n1=2; n1<NbP; n1++) {
2069 Points.SetValue(1,n1,P);
2071 Points.SetValue(1,NbP,P2);
2072 // get points from C3
2073 if (P4.Distance(P1C3)<1.e-6) {
2081 step = (lp-fp)/(NbP-1);
2082 Points.SetValue(NbP,1,P4);
2084 for (n1=2; n1<NbP; n1++) {
2088 Points.SetValue(NbP,n1,P);
2090 Points.SetValue(NbP,NbP,P3);
2091 // create isolines and get points from them
2092 for (n1=1; n1<=NbP; n1++) {
2093 gp_Pnt PI1 = Points.Value(1,n1);
2094 gp_Pnt PI2 = Points.Value(NbP,n1);
2095 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2096 HAP->SetValue(1,PI1);
2097 HAP->SetValue(2,PI2);
2098 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2099 anInt.Load(aDir1,aDir2);
2101 Handle(Geom_Curve) iso = anInt.Curve();
2102 fp = iso->FirstParameter();
2103 lp = iso->LastParameter();
2104 step = (lp-fp)/(NbP-1);
2106 TopoDS_Compound VComp;
2107 B.MakeCompound(VComp);
2108 for (n2=2; n2<NbP; n2++) {
2112 Points.SetValue(n2,n1,P);
2115 // create surface and face
2116 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2117 BS = new Geom_BezierSurface(Points);
2120 BRepBuilderAPI_MakeFace BB(BS,W);
2121 TopoDS_Face NewF = BB.Face();
2122 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2124 sff->FixOrientation();
2125 TopoDS_Face FixedFace = sff->Face();
2126 aNewFs.Append(FixedFace);
2127 VPE.Add(E1,FixedFace);
2128 //cout<<" face for edge "<<nbee<<" is created"<<endl;
2129 //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
2132 TopoDS_Shell aShell;
2133 B.MakeShell(aShell);
2134 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2135 B.Add(aShell,aNewFs(nf));
2140 // make sewing for this shell
2141 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2142 aSewing->SetTolerance(Precision::Confusion());
2143 aSewing->SetFaceMode(Standard_True);
2144 aSewing->SetFloatingEdgesMode(Standard_False);
2145 aSewing->SetNonManifoldMode(Standard_False);
2146 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2147 aSewing->Add(anExp.Current());
2150 MESSAGE (" shell for face "<<nbff<<" is created");
2151 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2152 //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
2153 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2154 aShell = TopoDS::Shell(aSewShape);
2155 GProp_GProps aSystem;
2156 BRepGProp::VolumeProperties(aShell, aSystem);
2157 if (aSystem.Mass()<0) {
2158 //cout<<"aSewShape is reversed"<<endl;
2161 if (BRep_Tool::IsClosed(aShell)) {
2162 TopoDS_Solid aSolid;
2163 B.MakeSolid(aSolid);
2164 B.Add(aSolid,aShell);
2165 B.Add(aComp,aSolid);
2166 MESSAGE (" solid for face "<<nbff<<" is created");
2169 B.Add(aComp,aShell);
2170 MESSAGE (" solid for face "<<nbff<<" is not created");
2174 B.Add(aComp,aShell);
2175 MESSAGE (" solid for face "<<nbff<<" is not created");
2177 //cout<<" solid for face "<<nbff<<" is created"<<endl;
2179 //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
2181 //TopoDS_Shell FixedShell = sfs->Shell();
2183 GProp_GProps aSystem;
2184 BRepGProp::VolumeProperties(FixedShell, aSystem);
2185 if (aSystem.Mass()<0) {
2186 //cout<<"aSewShape is reversed"<<endl;
2187 FixedShell.Reverse();
2189 if (BRep_Tool::IsClosed(FixedShell)) {
2190 TopoDS_Solid aSolid;
2191 B.MakeSolid(aSolid);
2192 B.Add(aSolid,aShell);
2193 B.Add(aComp,aSolid);
2196 B.Add(aComp,FixedShell);
2202 //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
2206 //=======================================================================
2207 //function : CreatePipeBiNormalAlongVector
2208 //purpose : auxilary for Execute()
2209 //=======================================================================
2210 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2211 GEOMImpl_IPipe* aCI)
2213 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2215 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2216 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2217 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2218 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2220 if (aShapeBase.IsNull()) {
2221 if (aCIBN) delete aCIBN;
2222 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2226 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2229 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2230 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2232 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2235 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2236 TopExp_Explorer wexp(aShapeBase,TopAbs_WIRE);
2237 aProf = wexp.Current();
2240 Standard_TypeMismatch::Raise
2241 ("MakePipe aborted : invalid type of base");
2243 BRepOffsetAPI_MakePipeShell PipeBuilder(aWirePath);
2244 PipeBuilder.Add(aProf);
2246 if (aShapeVec.IsNull()) {
2247 if (aCIBN) delete aCIBN;
2248 Standard_NullObject::Raise
2249 ("MakePipe aborted : null vector argument");
2251 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2252 Standard_TypeMismatch::Raise
2253 ("MakePipe aborted: invalid type of vector");
2254 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2255 TopoDS_Vertex V1, V2;
2256 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2257 if (V1.IsNull() || V2.IsNull())
2258 Standard_NullObject::Raise
2259 ("MakePipe aborted: vector is not defined");
2260 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2261 gp_Dir BiNormal(aVec);
2262 PipeBuilder.SetMode(BiNormal);
2263 PipeBuilder.Build();
2264 if (aShapeBase.ShapeType() == TopAbs_FACE) {
2265 PipeBuilder.MakeSolid();
2268 return PipeBuilder.Shape();
2271 //=======================================================================
2272 //function : Execute
2274 //=======================================================================
2275 Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
2277 //cout<<"PipeDriver::Execute"<<endl;
2278 if (Label().IsNull()) return 0;
2279 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
2280 GEOMImpl_IPipe* aCI= 0;
2281 Standard_Integer aType = aFunction->GetType();
2282 if (aType == PIPE_BASE_PATH)
2283 aCI = new GEOMImpl_IPipe(aFunction);
2284 else if (aType == PIPE_DIFFERENT_SECTIONS)
2285 aCI = new GEOMImpl_IPipeDiffSect(aFunction);
2286 else if (aType == PIPE_SHELL_SECTIONS)
2287 aCI = new GEOMImpl_IPipeShellSect(aFunction);
2288 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
2289 aCI = new GEOMImpl_IPipeShellSect(aFunction);
2290 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
2291 aCI = new GEOMImpl_IPipeBiNormal(aFunction);
2295 TopoDS_Wire aWirePath;
2296 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
2297 // working with path
2298 Handle(GEOM_Function) aRefPath = aCI->GetPath();
2299 TopoDS_Shape aShapePath = aRefPath->GetValue();
2301 if (aShapePath.IsNull()) {
2302 MESSAGE ("Driver : path is null");
2303 if (aCI) delete aCI;
2304 Standard_NullObject::Raise("MakePipe aborted : null path argument");
2309 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
2310 TopTools_SequenceOfShape anEdges;
2311 TopExp_Explorer anExp;
2315 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2316 B.Add(W, anExp.Current());
2322 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
2323 aWirePath = TopoDS::Wire(aShapePath);
2327 if (aShapePath.ShapeType() == TopAbs_EDGE) {
2328 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
2329 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
2334 if (aCI) delete aCI;
2335 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
2339 TopoDS_Shape aShape;
2341 if (aType == PIPE_BASE_PATH) {
2342 Handle(GEOM_Function) aRefBase = aCI->GetBase();
2343 TopoDS_Shape aShapeBase;
2345 // Make copy to prevent modifying of base object 0020766 : EDF 1320
2346 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
2348 aShapeBase = Copy.Shape();
2350 if (aShapeBase.IsNull()) {
2351 if (aCI) delete aCI;
2352 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2356 aShape = BRepOffsetAPI_MakePipe(aWirePath, aShapeBase);
2359 //building pipe with different sections
2360 else if (aType == PIPE_DIFFERENT_SECTIONS) {
2361 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
2362 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
2363 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
2364 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
2365 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
2371 Standard_Integer nbBases = aBasesObjs->Length();
2372 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
2374 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
2375 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
2378 for (i = 1; i <= nbBases; i++) {
2379 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
2380 if (anItem.IsNull())
2382 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
2383 if (aRefBase.IsNull())
2385 if (aRefBase->GetValue().IsNull())
2388 aHSeqBases->Append(aRefBase->GetValue());
2390 for (i = 1; i <= nbLocs; i++) {
2391 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
2392 if (anItemLoc.IsNull())
2394 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
2395 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
2396 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
2399 aHSeqLocs->Append(aShapeLoc);
2402 aShape = CreatePipeWithDifferentSections(aWirePath, aHSeqBases, aHSeqLocs, aWithContact, aWithCorrect);
2405 //building pipe with shell sections
2406 else if (aType == PIPE_SHELL_SECTIONS) {
2407 aShape = CreatePipeForShellSections(aWirePath,aCI);
2410 //building pipe shell sections without path
2411 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
2412 aShape = CreatePipeShellsWithoutPath(aCI);
2415 //building a pipe with constant bi-normal along given vector
2416 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
2417 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
2425 if (aShape.IsNull()) return 0;
2427 BRepCheck_Analyzer ana (aShape, Standard_False);
2428 if (!ana.IsValid()) {
2429 ShapeFix_ShapeTolerance aSFT;
2430 aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion());
2431 Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
2432 aSfs->SetPrecision(Precision::Confusion());
2434 aShape = aSfs->Shape();
2436 ana.Init(aShape, Standard_False);
2438 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
2441 // Glue (for bug 0020207)
2442 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
2444 aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
2446 TopoDS_Shape aRes = GEOMImpl_IShapesOperations::CompsolidToCompound(aShape);
2447 aFunction->SetValue(aRes);
2449 log.SetTouched(Label());
2453 //=======================================================================
2454 //function : GEOMImpl_PipeDriver_Type_
2456 //=======================================================================
2457 Standard_EXPORT Handle_Standard_Type& GEOMImpl_PipeDriver_Type_()
2459 static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
2460 if (aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
2461 static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
2462 if (aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
2463 static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
2464 if (aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
2466 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
2467 static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_PipeDriver",
2468 sizeof(GEOMImpl_PipeDriver),
2470 (Standard_Address)_Ancestors,
2471 (Standard_Address)NULL);
2476 //=======================================================================
2477 //function : DownCast
2479 //=======================================================================
2480 const Handle(GEOMImpl_PipeDriver) Handle(GEOMImpl_PipeDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
2482 Handle(GEOMImpl_PipeDriver) _anOtherObject;
2484 if (!AnObject.IsNull()) {
2485 if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_PipeDriver))) {
2486 _anOtherObject = Handle(GEOMImpl_PipeDriver)((Handle(GEOMImpl_PipeDriver)&)AnObject);
2490 return _anOtherObject;