1 // Copyright (C) 2007-2015 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, or (at your option) any later version.
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
23 #include <GEOMImpl_PipeDriver.hxx>
25 #include <GEOMImpl_IPipeDiffSect.hxx>
26 #include <GEOMImpl_IPipeShellSect.hxx>
27 #include <GEOMImpl_IPipeBiNormal.hxx>
28 #include <GEOMImpl_IPipe.hxx>
29 #include <GEOMImpl_IPipePath.hxx>
30 #include <GEOMImpl_GlueDriver.hxx>
31 #include <GEOMImpl_Types.hxx>
33 #include <GEOM_Function.hxx>
35 #include <GEOMUtils.hxx>
37 #include <ShapeAnalysis_FreeBounds.hxx>
38 #include <ShapeAnalysis_Edge.hxx>
39 #include <ShapeFix_Face.hxx>
40 #include <ShapeFix_Shell.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BRepBuilderAPI_Copy.hxx>
45 #include <BRepBuilderAPI_MakeFace.hxx>
46 #include <BRepBuilderAPI_MakeWire.hxx>
47 #include <BRepBuilderAPI_Sewing.hxx>
48 #include <BRepGProp.hxx>
49 #include <GeomFill_Trihedron.hxx>
50 #include <GeomFill_CorrectedFrenet.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_DataMapOfShapeSequenceOfShape.hxx>
66 #include <TopTools_SequenceOfShape.hxx>
67 #include <TopTools_HSequenceOfShape.hxx>
68 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
69 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
70 #include <TopTools_ListIteratorOfListOfShape.hxx>
71 #include <TopTools_MapIteratorOfMapOfShape.hxx>
73 #include <GProp_GProps.hxx>
75 #include <GeomAPI_ProjectPointOnCurve.hxx>
76 #include <GeomAPI_Interpolate.hxx>
77 #include <Geom_TrimmedCurve.hxx>
78 #include <Geom_Plane.hxx>
79 #include <Geom_RectangularTrimmedSurface.hxx>
80 #include <Geom_BezierSurface.hxx>
81 #include <Geom_Line.hxx>
82 #include <Geom_Conic.hxx>
83 #include <Geom_BSplineCurve.hxx>
84 #include <Geom_BSplineSurface.hxx>
85 #include <GeomAdaptor_HCurve.hxx>
86 #include <GeomFill_BSplineCurves.hxx>
87 #include <GeomConvert_ApproxCurve.hxx>
88 #include <GeomConvert.hxx>
90 #include <TColgp_SequenceOfPnt.hxx>
91 #include <TColgp_HArray1OfPnt.hxx>
92 #include <TColgp_Array2OfPnt.hxx>
93 #include <TColStd_HSequenceOfTransient.hxx>
95 #include <Precision.hxx>
97 #include <Standard_NullObject.hxx>
98 #include <Standard_TypeMismatch.hxx>
99 #include <Standard_ConstructionError.hxx>
101 #include "utilities.h"
105 #define GROUP_SIDE1 2
106 #define GROUP_SIDE2 3
107 #define GROUP_OTHER 4
109 static bool FillGroups(const TopTools_SequenceOfShape *theGroups,
110 const TopTools_IndexedMapOfShape &theIndices,
111 Handle(TColStd_HArray1OfInteger) *theGroupIds);
113 static void StoreGroups(GEOMImpl_IPipe *theCI,
114 Handle(TColStd_HArray1OfInteger) *theGroups);
116 static bool DoGroups(BRepOffsetAPI_MakePipeShell &theSweep,
117 TopTools_SequenceOfShape *theGroups);
119 static bool CreateGroups(BRepOffsetAPI_MakePipeShell &theSweep,
120 GEOMImpl_IPipe *theCI);
122 //=======================================================================
125 //=======================================================================
126 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
128 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
132 //=======================================================================
133 //function : GEOMImpl_PipeDriver
135 //=======================================================================
136 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
140 //=======================================================================
141 //function : EvaluateBestSweepMode
142 //purpose : auxilary for right call of MakePipe and MakePipeShell
143 //=======================================================================
144 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
146 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
148 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
149 for (; Explo.More(); Explo.Next())
151 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
152 Standard_Real fpar, lpar;
153 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
154 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
155 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
157 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
158 aCorrFrenet->SetCurve(GAHcurve);
159 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
160 if (aMode == GeomFill_IsDiscreteTrihedron)
165 if (aMode == GeomFill_IsCorrectedFrenet)
172 //=======================================================================
173 //function : BuildPipeShell
174 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
175 // mode. Returns Standard_True if the building is done successfully.
176 //=======================================================================
177 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
181 Standard_Boolean isDone = theBuilder.IsDone();
184 // Try to use Descrete Trihedron mode.
185 theBuilder.SetDiscreteMode();
187 isDone = theBuilder.IsDone();
193 //=======================================================================
194 //function : FillForOtherEdges
195 //purpose : auxilary for CreatePipeForShellSections()
196 //=======================================================================
197 static bool FillForOtherEdges(const TopoDS_Shape& F1,
198 const TopoDS_Shape& E1,
199 const TopoDS_Shape& V1,
200 TopTools_IndexedDataMapOfShapeShape& FF)
202 //cout<<"FillForOtherEdges"<<endl;
203 // find other pairs for vertexes and edges
204 // creating map of vertex edges for both faces
205 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
206 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
207 if (!FF.Contains(F1))
208 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
209 if (!FF.Contains(E1))
210 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
211 if (!FF.Contains(V1))
212 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
213 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
214 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
215 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
216 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
217 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
219 TopoDS_Edge ES1 = TopoDS::Edge(E1);
220 TopoDS_Edge ES2 = TopoDS::Edge(E2);
221 TopoDS_Shape VS1 = V1;
222 TopoDS_Shape VS2 = V2;
224 ShapeAnalysis_Edge sae;
226 if (!aMapVertEdge1.Contains(VS1))
227 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
228 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
229 //TopoDS_Shape E1next;
230 TopTools_ListIteratorOfListOfShape anIter1(aList1);
231 if (anIter1.Value().IsSame(ES1)) {
234 //E1next = anIter1.Value();
235 if (!aMapVertEdge2.Contains(VS2))
236 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
237 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
238 //TopoDS_Shape E2next;
239 TopTools_ListIteratorOfListOfShape anIter2(aList2);
240 if (anIter2.Value().IsSame(ES2)) {
243 //E2next = anIter2.Value();
244 //ES1 = TopoDS::Edge(E1next);
245 //ES2 = TopoDS::Edge(E2next);
246 ES1 = TopoDS::Edge(anIter1.Value());
247 ES2 = TopoDS::Edge(anIter2.Value());
248 if (!FF.Contains(ES1)) {
251 if (VS1.IsSame(sae.FirstVertex(ES1)))
252 VS1 = sae.LastVertex(ES1);
254 VS1 = sae.FirstVertex(ES1);
255 if (VS2.IsSame(sae.FirstVertex(ES2)))
256 VS2 = sae.LastVertex(ES2);
258 VS2 = sae.FirstVertex(ES2);
261 if (!FF.Contains(VS1)) {
269 //=======================================================================
270 //function : FillCorrespondingEdges
271 //purpose : auxilary for CreatePipeForShellSections()
272 //=======================================================================
273 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
274 const TopoDS_Shape& FS2,
275 const TopoDS_Vertex& aLoc1,
276 const TopoDS_Vertex& aLoc2,
277 const TopoDS_Wire& aWirePath,
278 TopTools_IndexedDataMapOfShapeShape& FF)
280 //cout<<"FillCorrespondingEdges"<<endl;
281 // find corresponding edges
282 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
283 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
284 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
285 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
286 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
287 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
288 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
289 if (theBestMode == GeomFill_IsDiscreteTrihedron)
290 aBuilder.SetDiscreteMode();
291 aBuilder.Add(aWire1, aLoc1);
292 aBuilder.Add(aWire2, aLoc2);
293 if (!aBuilder.IsReady()) {
297 BuildPipeShell(aBuilder);
299 TopoDS_Shape aShape = aBuilder.Shape();
300 ShapeAnalysis_Edge sae;
301 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
302 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
303 TopTools_MapOfShape Vs1,Vs2;
305 exp.Init(FS1, TopAbs_EDGE);
306 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
307 TopoDS_Vertex V11 = sae.FirstVertex(E1);
308 TopoDS_Vertex V21 = sae.LastVertex(E1);
309 gp_Pnt P11 = BRep_Tool::Pnt(V11);
310 gp_Pnt P21 = BRep_Tool::Pnt(V21);
311 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
312 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
313 // find corresponding vertexes from created shape
314 TopoDS_Vertex VN11,VN21;
315 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
316 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
317 gp_Pnt P = BRep_Tool::Pnt(V);
318 if (P.Distance(P11)<tol) {
321 if (P.Distance(P21)<tol) {
325 // find edge contains VN11 and VN21 and corresponding vertexes
326 TopoDS_Vertex VN12,VN22;
327 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
328 TopoDS_Shape F = exp.Current();
329 TopExp_Explorer expe;
331 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
332 TopoDS_Edge E = TopoDS::Edge(expe.Current());
333 TopoDS_Vertex VF = sae.FirstVertex(E);
334 TopoDS_Vertex VL = sae.LastVertex(E);
335 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
341 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
342 TopoDS_Edge E = TopoDS::Edge(expe.Current());
343 TopoDS_Vertex VF = sae.FirstVertex(E);
344 TopoDS_Vertex VL = sae.LastVertex(E);
345 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
347 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
349 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
351 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
357 // find vertexes from FS2 corresponded to VN12 and VN22
358 // and find edge from FS2 contains V12 and V22,
359 // this edge will be corresponded to edge E1
360 TopoDS_Vertex V12,V22;
361 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
362 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
363 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
364 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
366 TopExp_Explorer expe;
367 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
368 TopoDS_Edge E = TopoDS::Edge(expe.Current());
369 TopoDS_Vertex VF = sae.FirstVertex(E);
370 TopoDS_Vertex VL = sae.LastVertex(E);
371 gp_Pnt PF = BRep_Tool::Pnt(VF);
372 gp_Pnt PL = BRep_Tool::Pnt(VL);
373 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
379 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
390 // find other pairs for vertexes and edges
391 // creating map of vertex edges for both faces
392 return FillForOtherEdges(FS1,E1,V21,FF);
397 //=======================================================================
398 //function : FillCorrespondingEdges
399 //purpose : auxilary for CreatePipeShellsWithoutPath()
400 //=======================================================================
401 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
402 const TopoDS_Shape& FS2,
403 const TopoDS_Vertex& aLoc1,
404 const TopoDS_Vertex& aLoc2,
405 TopTools_IndexedDataMapOfShapeShape& FF)
407 //cout<<"FillCorrespondingEdges"<<endl;
409 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
410 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
413 ShapeAnalysis_Edge sae;
414 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
415 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
416 TopTools_MapOfShape Vs1,Vs2;
418 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
421 TopExp_Explorer exp1;
422 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
423 E1 = TopoDS::Edge(exp1.Current());
424 TopoDS_Vertex V1 = sae.FirstVertex(E1);
425 TopoDS_Vertex V2 = sae.LastVertex(E1);
426 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
427 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
428 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
429 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
430 if (P1.Distance(Ptmp1)<tol) {
434 if (P1.Distance(Ptmp2)<tol) {
441 TopoDS_Vertex VE21,VE22;
443 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
444 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
445 TopoDS_Vertex V1 = sae.FirstVertex(E);
446 TopoDS_Vertex V2 = sae.LastVertex(E);
447 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
448 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
449 if (P2.Distance(Ptmp1)<tol) {
461 if (P2.Distance(Ptmp2)<tol) {
475 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
476 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
477 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
478 gp_Vec aDir1(PV21,PE21);
479 gp_Vec aDir2(PV21,PE22);
480 double ang1 = aDir.Angle(aDir1);
481 double ang2 = aDir.Angle(aDir2);
482 if (fabs(ang1)<fabs(ang2)) {
495 // find other pairs for vertexes and edges
496 return FillForOtherEdges(FS1,E1,V21,FF);
499 //=======================================================================
500 //function : FindNextPairOfFaces
501 //purpose : auxilary for CreatePipeForShellSections()
502 //=======================================================================
503 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
504 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
505 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
506 TopTools_IndexedDataMapOfShapeShape& FF,
509 //cout<<"FindNextPairOfFaces"<<endl;
510 TopExp_Explorer anExp;
511 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
512 TopoDS_Shape E1 = anExp.Current();
513 if (!FF.Contains(E1)) {
515 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
517 if (!FF.Contains(E1))
518 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
519 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
520 TopExp_Explorer anExpV;
521 anExpV.Init(E1, TopAbs_VERTEX);
522 TopoDS_Shape V1 = anExpV.Current();
523 if (!FF.Contains(V1)) {
525 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
528 if (!aMapEdgeFaces1.Contains(E1))
529 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
530 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
531 if (aList1.Extent()<2)
533 TopTools_ListIteratorOfListOfShape anIter(aList1);
534 if (anIter.Value().IsEqual(aCurFace)) {
537 TopoDS_Shape F1other = anIter.Value();
538 if (FF.Contains(F1other))
541 if (!FF.Contains(aCurFace))
542 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
543 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
544 if (!aMapEdgeFaces2.Contains(E2))
545 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
546 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
547 if (aList2.Extent()<2) {
549 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
551 TopTools_ListIteratorOfListOfShape anIter2(aList2);
552 if (anIter2.Value().IsEqual(F2)) {
555 TopoDS_Shape F2other = anIter2.Value();
556 FF.Add(F1other,F2other);
558 // add pairs of edges to FF
559 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
562 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
565 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
569 //=======================================================================
570 //function : FindFirstPairFaces
571 //purpose : auxilary for Execute()
572 //=======================================================================
573 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
574 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
575 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
577 //cout<<"FindFirstPairFaces"<<endl;
579 // check if vertexes are sub-shapes of sections
580 gp_Pnt P1 = BRep_Tool::Pnt(V1);
581 gp_Pnt P2 = BRep_Tool::Pnt(V2);
582 TopoDS_Vertex V1new,V2new;
584 double mindist = 1.e10;
585 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
586 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
587 gp_Pnt P = BRep_Tool::Pnt(V);
588 double dist = P1.Distance(P);
595 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
596 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
597 gp_Pnt P = BRep_Tool::Pnt(V);
598 double dist = P2.Distance(P);
605 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
606 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
607 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
608 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
609 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
610 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
612 // replace vertexes if it is needed
613 if (!V1.IsSame(V1new)) {
615 P1 = BRep_Tool::Pnt(V1);
616 MESSAGE (" replace V1");
619 MESSAGE (" not replace V1");
620 if (!V2.IsSame(V2new)) {
622 P2 = BRep_Tool::Pnt(V2);
623 MESSAGE (" replace V2");
626 MESSAGE (" not replace V2");
628 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
629 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
630 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
631 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
633 if (!aMapVertFaces1.Contains(V1))
634 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
635 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
636 TopTools_ListIteratorOfListOfShape anIter1(aList1);
637 FS1 = anIter1.Value();
639 double x1=0., y1=0., z1=0.;
641 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
642 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
643 gp_Pnt P = BRep_Tool::Pnt(V);
649 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
651 TColgp_SequenceOfPnt Ps;
652 TopTools_SequenceOfShape Fs;
653 if (!aMapVertFaces2.Contains(V2))
654 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
655 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
656 TopTools_ListIteratorOfListOfShape anIter2(aList2);
657 for (; anIter2.More(); anIter2.Next()) {
658 TopoDS_Shape F = anIter2.Value();
659 double x2=0., y2=0., z2=0.;
661 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
662 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
663 gp_Pnt P = BRep_Tool::Pnt(V);
669 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
676 double MinAng = M_PI;
678 for (; i<=Fs.Length(); i++) {
679 gp_Vec tmpDir(PM1,Ps(i));
680 double ang = fabs(aDir.Angle(tmpDir));
689 //=======================================================================
690 //function : CreatePipeWithDifferentSections
692 //=======================================================================
693 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
694 (const TopoDS_Wire &theWirePath,
695 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
696 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
697 const Standard_Boolean theWithContact,
698 const Standard_Boolean theWithCorrect,
699 Handle(TColStd_HArray1OfInteger) *theGroups)
703 TopoDS_Wire aWirePath = theWirePath;
705 Standard_Integer nbBases = theHSeqBases->Length();
706 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
708 if (nbLocs && nbLocs != nbBases) {
709 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
712 TopTools_SequenceOfShape aSeqBases;
713 TopTools_SequenceOfShape aSeqLocs;
714 TopTools_SequenceOfShape aSeqFaces;
715 Standard_Boolean NeedCreateSolid = Standard_False;
717 Standard_Integer i = 1;
718 for (i = 1; i <= nbBases; i++) {
719 if (theHSeqBases->Value(i).IsNull())
722 // Make copy to prevent modifying of base object 0020766 : EDF 1320
723 TopoDS_Shape aShapeBase;
724 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
726 aShapeBase = Copy.Shape();
728 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
730 //if for section was specified face with a few wires then a few
731 // pipes were build and make solid
732 if (aTypeBase == TopAbs_SHELL) {
733 // create wire as boundary contour if shell is no closed
734 // get free boundary shapes
735 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
736 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
737 TopExp_Explorer anExp;
739 Standard_Integer NbWires = 0;
740 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
742 aWire = anExp.Current();
746 Standard_ConstructionError::Raise("Bad shell is used as section ");
748 NeedCreateSolid = Standard_True;
749 aSeqFaces.Append(aShapeBase);
750 aSeqBases.Append(aWire);
752 else if (aTypeBase == TopAbs_FACE) {
753 NeedCreateSolid = Standard_True;
754 //for case one path should be used other type function
755 aSeqFaces.Append(aShapeBase);
756 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
757 for (; aExpW.More(); aExpW.Next()) {
758 TopoDS_Shape aWireProf = aExpW.Current();
759 aSeqBases.Append(aWireProf);
762 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
763 aSeqBases.Append(aShapeBase);
765 else if (aTypeBase == TopAbs_EDGE) {
766 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
767 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
768 aSeqBases.Append(aWireProf);
771 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
772 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
774 aSeqLocs.Append(aShapeLoc);
778 nbLocs = aSeqLocs.Length();
781 TopTools_SequenceOfShape Edges;
783 // we have to check that each location shape is a vertex from
784 // path and update aSeqLocs if it is needed (and possible)
785 TColgp_SequenceOfPnt PLocs;
786 for (i=1; i<=nbLocs; i++) {
787 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
788 PLocs.Append(BRep_Tool::Pnt(V));
790 //TopTools_SequenceOfShape Edges;
791 TopExp_Explorer anExp;
792 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
793 Edges.Append(anExp.Current());
795 int nbEdges = Edges.Length();
796 ShapeAnalysis_Edge sae;
797 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
798 double tol = BRep_Tool::Tolerance(edge);
799 TopoDS_Vertex VF = sae.FirstVertex(edge);
800 gp_Pnt PF = BRep_Tool::Pnt(VF);
801 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
802 if (PF.Distance(PLocs.First()) > tol) {
803 Standard_ConstructionError::Raise
804 ("First location shapes is not coincided with first vertex of aWirePath");
806 aSeqLocs.ChangeValue(1) = VF;
807 edge = TopoDS::Edge(Edges.Last());
808 tol = BRep_Tool::Tolerance(edge);
809 TopoDS_Vertex VL = sae.LastVertex(edge);
810 gp_Pnt PL = BRep_Tool::Pnt(VL);
811 if (PL.Distance(PLocs.Last()) > tol) {
812 Standard_ConstructionError::Raise
813 ("Last location shapes is not coincided with last vertex of aWirePath");
815 aSeqLocs.ChangeValue(nbLocs) = VL;
817 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
818 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
819 tol = BRep_Tool::Tolerance(edge);
820 TopoDS_Vertex V1 = sae.FirstVertex(E);
821 TopoDS_Vertex V2 = sae.LastVertex(E);
822 gp_Pnt P1 = BRep_Tool::Pnt(V1);
823 gp_Pnt P2 = BRep_Tool::Pnt(V2);
824 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
825 aSeqLocs.ChangeValue(jcurr) = V2;
829 // find distance between E and aLocs(jcurr)
831 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
832 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
833 if (PPCurve.NbPoints()>0 &&
834 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
835 double param = PPCurve.Parameter(1);
838 // split current edge
839 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
840 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
845 if (Pfp.Distance(P1)<tol) {
846 B.MakeEdge(E1,tc1,tol);
848 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
849 B.Add(E1,TopoDS::Vertex(tmpV));
850 B.MakeEdge(E2,tc2,tol);
851 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
852 B.Add(E2,TopoDS::Vertex(tmpV));
856 B.MakeEdge(E1,tc2,tol);
857 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
858 B.Add(E1,TopoDS::Vertex(tmpV));
861 B.MakeEdge(E2,tc1,tol);
863 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
864 B.Add(E2,TopoDS::Vertex(tmpV));
869 Edges.InsertAfter(i-1,E1);
870 Edges.InsertAfter(i,E2);
874 if (nbEdges<Edges.Length()) {
875 // one of edges was splitted => we have to update WirePath
879 for (i=1; i<=Edges.Length(); i++) {
880 B.Add(W,TopoDS::Edge(Edges.Value(i)));
886 // check curvature of wire for condition that
887 // max summary angle between directions along
888 // wire path must be < 4*PI. If not - split wire
889 // and seguences of shapes, perform pipe for each
890 // and make sewing after that
895 if ( Edges.Length() > 0 ) {
896 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
899 SumAng = fabs(Vec1.Angle(Vec2));
903 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
905 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
906 for (i=2; i<=Edges.Length(); i++) {
907 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
908 double tol = BRep_Tool::Tolerance(edge);
909 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
911 double ang = fabs(Vec1.Angle(Vec2));
915 SplitEdgeNums.Append(i-1);
917 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
918 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
919 gp_Pnt P = BRep_Tool::Pnt(aVert);
920 if (P1.Distance(P) < tol) {
921 SplitLocNums.Append(j);
931 bool isCreateGroups = (theGroups != NULL);
933 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
934 TopTools_SequenceOfShape aSeqRes;
935 TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
936 Standard_Integer iGrp;
937 int nn, num1 = 1, num2 = 1;
938 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
939 // create wirepath and sequences of shapes
943 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
944 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
946 num1 = SplitEdgeNums.Value(nn) + 1;
947 TopTools_SequenceOfShape aTmpSeqBases;
948 TopTools_SequenceOfShape aTmpSeqLocs;
949 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
950 aTmpSeqBases.Append(aSeqBases.Value(i));
951 aTmpSeqLocs.Append(aSeqLocs.Value(i));
953 num2 = SplitLocNums.Value(nn);
955 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
956 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
957 if (theBestMode == GeomFill_IsDiscreteTrihedron)
958 aBuilder.SetDiscreteMode();
959 Standard_Integer nbShapes = aTmpSeqBases.Length();
960 for (i=1; i<=nbShapes; i++) {
961 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
962 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
963 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
965 if (!aBuilder.IsReady()) {
966 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
969 BuildPipeShell(aBuilder);
971 TopoDS_Shape resShape = aBuilder.Shape();
972 aSeqRes.Append(resShape);
975 if (isCreateGroups) {
977 TopTools_SequenceOfShape aGroups[5];
979 if (!DoGroups(aBuilder, aGroups)) {
980 Standard_ConstructionError::Raise("Generate groups failure");
983 // Get shapes from all groups.
984 for (iGrp = 0; iGrp < 5; ++iGrp) {
985 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
989 // create wirepath and sequences of shapes for last part
993 for (i=num1; i<=Edges.Length(); i++) {
994 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
996 TopTools_SequenceOfShape aTmpSeqBases;
997 TopTools_SequenceOfShape aTmpSeqLocs;
998 for (i=num2; i<=aSeqLocs.Length(); i++) {
999 aTmpSeqBases.Append(aSeqBases.Value(i));
1000 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1002 // make pipe for last part
1003 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1004 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1005 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1006 aBuilder.SetDiscreteMode();
1007 Standard_Integer nbShapes = aTmpSeqBases.Length();
1008 for (i=1; i<=nbShapes; i++) {
1009 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1010 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1011 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1013 if (!aBuilder.IsReady()) {
1014 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1017 BuildPipeShell(aBuilder);
1019 TopoDS_Shape resShape = aBuilder.Shape();
1020 aSeqRes.Append(resShape);
1023 if (isCreateGroups) {
1025 TopTools_SequenceOfShape aGroups[5];
1027 if (!DoGroups(aBuilder, aGroups)) {
1028 Standard_ConstructionError::Raise("Generate groups failure");
1031 // Get shapes from all groups.
1032 for (iGrp = 0; iGrp < 5; ++iGrp) {
1033 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1037 // make sewing for result
1038 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1039 aSewing->SetTolerance(Precision::Confusion());
1040 aSewing->SetFaceMode(Standard_True);
1041 aSewing->SetFloatingEdgesMode(Standard_False);
1042 aSewing->SetNonManifoldMode(Standard_False);
1043 for (i=1; i<=aSeqRes.Length(); i++) {
1044 aSewing->Add(aSeqRes.Value(i));
1047 aShape = aSewing->SewedShape();
1049 if (isCreateGroups) {
1050 // Replase Group shapes by modified ones.
1051 TopTools_SequenceOfShape aSeqGroups[5];
1054 for (iGrp = 0; iGrp < 5; ++iGrp) {
1056 for (i = 1; i <= aSeqRes.Length(); ++i) {
1057 if (iGrp == GROUP_DOWN && i > 1) {
1058 // For DOWN group we use only the first pipe.
1062 if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
1063 // For UP group we use only the last pipe.
1067 const TopTools_SequenceOfShape &aShapes =
1068 aMapResGroups[iGrp].Find(aSeqRes.Value(i));
1071 // For each sub-shape of pipe
1072 for (j = 1; j <= aShapes.Length(); ++j) {
1073 const TopoDS_Shape &aGrpShape = aShapes.Value(j);
1075 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1076 // Use the shape modified by sewing.
1077 const TopoDS_Shape &aModifGrpShape =
1078 aSewing->ModifiedSubShape(aGrpShape);
1080 aSeqGroups[iGrp].Append(aModifGrpShape);
1082 // Use the shape as it is.
1083 aSeqGroups[iGrp].Append(aGrpShape);
1090 TopTools_IndexedMapOfShape anIndices;
1092 TopExp::MapShapes(aShape, anIndices);
1094 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1095 Standard_ConstructionError::Raise("Generate groups failure");
1100 // old implementation without splitting
1101 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1102 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1103 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1104 aBuilder.SetDiscreteMode();
1106 Standard_Integer nbShapes = aSeqBases.Length();
1107 Standard_Integer step = nbShapes/nbBases;
1109 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1110 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1112 Standard_Integer ind =0;
1113 Standard_Real aTolConf = Precision::Confusion();
1114 Standard_Real aTolAng = Precision::Angular();
1116 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1117 TopTools_SequenceOfShape usedBases;
1118 Standard_Integer j = 1;
1119 for (; j <= nbBases; j++) {
1120 ind = i + (j-1)*step;
1121 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1122 usedBases.Append(aWireProf);
1124 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1125 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1126 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1129 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1131 if (!aBuilder.IsReady()) {
1132 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1135 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1137 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1139 if (isDone && NeedCreateSolid) {
1140 isDone = aBuilder.MakeSolid();
1144 Standard_ConstructionError::Raise("Pipe construction failure");
1146 aShape = aBuilder.Shape();
1148 if (isCreateGroups) {
1150 TopTools_SequenceOfShape aSeqGroups[5];
1152 if (!DoGroups(aBuilder, aSeqGroups)) {
1153 Standard_ConstructionError::Raise("Generate groups failure");
1157 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1158 TopTools_IndexedMapOfShape anIndices;
1159 const TopoDS_Shape aResult = aBuilder.Shape();
1161 TopExp::MapShapes(aResult, anIndices);
1163 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1164 Standard_ConstructionError::Raise("Generate groups failure");
1167 aSeqFaces.Append(aShape);
1168 for (j = 1; j <=usedBases.Length(); j++)
1169 aBuilder.Delete(usedBases.Value(j));
1176 //=======================================================================
1177 //function : CreatePipeForShellSections
1178 //purpose : auxilary for Execute()
1179 //=======================================================================
1180 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1181 GEOMImpl_IPipe* aCI)
1186 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1187 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1188 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1189 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1190 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1191 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1192 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1194 Standard_Integer nbBases = aBasesObjs->Length(),
1195 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1196 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1198 if (nbLocs != nbBases) {
1199 if (aCI) delete aCI;
1200 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1202 if (nbSubBases && nbSubBases != nbBases) {
1203 if (aCI) delete aCI;
1204 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1207 TopTools_SequenceOfShape VLocs;
1208 for (i=1; i<=nbBases; i++) {
1209 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1210 if (anItemLoc.IsNull())
1212 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1213 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1214 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1216 VLocs.Append(aShapeLoc);
1218 nbLocs = VLocs.Length();
1219 if (nbLocs != nbBases) {
1220 if (aCI) delete aCI;
1221 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1223 // split wire path by location points
1224 TColgp_SequenceOfPnt PLocs;
1225 for (i=1; i<=nbLocs; i++) {
1226 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1227 PLocs.Append(BRep_Tool::Pnt(V));
1230 TopTools_SequenceOfShape Edges;
1231 TopTools_SequenceOfShape Wires;
1232 ShapeAnalysis_Edge sae;
1235 TopExp_Explorer anExp;
1236 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1237 Edges.Append(anExp.Current());
1239 Standard_Integer Num1 = 0;
1240 Standard_Integer Num2 = 0;
1241 for (i=1; i<=Edges.Length(); i++) {
1242 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1243 double tol = BRep_Tool::Tolerance(E);
1244 TopoDS_Vertex V1 = sae.FirstVertex(E);
1245 TopoDS_Vertex V2 = sae.LastVertex(E);
1246 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1247 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1248 if (P1.Distance(PLocs.First()) < tol) {
1251 if (P2.Distance(PLocs.Last()) < tol) {
1255 if (Num1>0 && Num2>0) {
1258 for (i=Num1; i<=Num2; i++) {
1259 B.Add(W,Edges.Value(i));
1264 Wires.Append(aWirePath);
1268 TopExp_Explorer anExp;
1269 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1270 Edges.Append(anExp.Current());
1272 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1273 double tol = BRep_Tool::Tolerance(edge);
1274 TopoDS_Vertex VF = sae.FirstVertex(edge);
1275 gp_Pnt PF = BRep_Tool::Pnt(VF);
1276 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1277 if (PF.Distance(PLocs.First()) > tol) {
1278 if (aCI) delete aCI;
1279 Standard_ConstructionError::Raise
1280 ("First location shapes is not coincided with first vertex of aWirePath");
1282 VLocs.ChangeValue(1) = VF;
1283 edge = TopoDS::Edge(Edges.Last());
1284 tol = BRep_Tool::Tolerance(edge);
1285 TopoDS_Vertex VL = sae.LastVertex(edge);
1286 gp_Pnt PL = BRep_Tool::Pnt(VL);
1287 if (PL.Distance(PLocs.Last()) > tol) {
1288 if (aCI) delete aCI;
1289 Standard_ConstructionError::Raise
1290 ("Last location shapes is not coincided with last vertex of aWirePath");
1292 VLocs.ChangeValue(nbLocs) = VL;
1294 TopTools_SequenceOfShape tmpEdges;
1295 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1296 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1297 tol = BRep_Tool::Tolerance(E);
1298 TopoDS_Vertex V1 = sae.FirstVertex(E);
1299 TopoDS_Vertex V2 = sae.LastVertex(E);
1300 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1301 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1302 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1303 // make wire from current edge and add created
1307 for (j=1; j<=tmpEdges.Length(); j++)
1308 B.Add(W,tmpEdges.Value(j));
1311 VLocs.ChangeValue(jcurr) = V2;
1316 // find distance between E and aLocs(jcurr)
1318 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1319 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1320 if (PPCurve.NbPoints()>0 &&
1321 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1322 double param = PPCurve.Parameter(1);
1325 // split current edge
1326 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1327 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1331 if (Pfp.Distance(P1)<tol) {
1332 B.MakeEdge(E1,tc1,tol);
1334 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1335 B.Add(E1,TopoDS::Vertex(tmpV));
1336 tmpEdges.Append(E1);
1337 B.MakeEdge(E2,tc2,tol);
1338 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1339 B.Add(E2,TopoDS::Vertex(tmpV));
1343 B.MakeEdge(E1,tc2,tol);
1344 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1345 B.Add(E1,TopoDS::Vertex(tmpV));
1348 tmpEdges.Append(E1);
1349 B.MakeEdge(E2,tc1,tol);
1351 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1352 B.Add(E2,TopoDS::Vertex(tmpV));
1355 // create wire from tmpEdges
1358 for (j=1; j<=tmpEdges.Length(); j++)
1359 B.Add(W,tmpEdges.Value(j));
1364 Edges.InsertAfter(i-1,E1);
1365 Edges.InsertAfter(i,E2);
1372 // create wire from other edges
1375 for (; i<=Edges.Length(); i++)
1376 B.Add(W,Edges.Value(i));
1380 if (Wires.Length() != nbLocs-1) {
1381 if (aCI) delete aCI;
1382 Standard_ConstructionError::Raise
1383 ("One of location shapes is not lied on the path");
1386 TopTools_SequenceOfShape aGroups[5];
1387 TopoDS_Compound aComp;
1388 B.MakeCompound(aComp);
1389 for (i = 1; i < nbBases; i++) {
1390 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1392 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1393 if (anItem1.IsNull())
1395 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1396 if (aRefBase1.IsNull())
1398 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1399 if (aShBase1.IsNull())
1401 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1403 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1404 if (anItem2.IsNull())
1406 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1407 if (aRefBase2.IsNull())
1409 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1410 if (aShBase2.IsNull())
1412 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1414 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1415 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1417 if (aCI) delete aCI;
1418 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1421 bool CreateFewSolids = false;
1423 TopExp_Explorer anExp;
1424 Standard_Integer nbf1 = 0;
1425 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1428 Standard_Integer nbf2 = 0;
1429 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1433 CreateFewSolids = true;
1436 if (!CreateFewSolids) {
1437 // we can create only one solid
1438 TopoDS_Shape aWire1, aWire2;
1440 if (aType1==TopAbs_SHELL) {
1441 // create wire as boundary contour if shell is no closed
1442 // get free boundary shapes
1443 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1444 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1445 //TopExp_Explorer anExp;
1446 Standard_Integer NbWires = 0;
1447 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1449 aWire1 = anExp.Current();
1453 if (aCI) delete aCI;
1454 Standard_ConstructionError::Raise("Bad shell is used as section ");
1457 else { // aType1==TopAbs_FACE
1458 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1459 aWire1 = aExpW.Current();
1462 if (aType2==TopAbs_SHELL) {
1463 // create wire as boundary contour if shell is no closed
1464 // get free boundary shapes
1465 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1466 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1467 //TopExp_Explorer anExp;
1468 Standard_Integer NbWires = 0;
1469 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1471 aWire2 = anExp.Current();
1475 if (aCI) delete aCI;
1476 Standard_ConstructionError::Raise("Bad shell is used as section ");
1479 else { // aType2==TopAbs_FACE
1480 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1481 aWire2 = aExpW.Current();
1483 // make pipe using aWire1 and aWire2
1484 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1485 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1486 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1487 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1488 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1489 aBuilder.SetDiscreteMode();
1490 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1491 aWithContact, aWithCorrect);
1492 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1493 aWithContact, aWithCorrect);
1494 if (!aBuilder.IsReady()) {
1495 if (aCI) delete aCI;
1496 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1499 BuildPipeShell(aBuilder);
1501 TopoDS_Shape aShape = aBuilder.Shape();
1502 TopTools_SequenceOfShape aLocalGroups[5];
1505 if (isGenerateGroups) {
1507 if (!DoGroups(aBuilder, aLocalGroups)) {
1508 if (aCI) delete aCI;
1509 Standard_ConstructionError::Raise("Generate groups failure");
1512 // Clear the groups Down and Up.
1513 aLocalGroups[GROUP_DOWN].Clear();
1514 aLocalGroups[GROUP_UP].Clear();
1517 TopoDS_Shell aShell;
1518 B.MakeShell(aShell);
1519 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1520 B.Add(aShell,anExp.Current());
1522 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1523 B.Add(aShell,anExp.Current());
1525 if (isGenerateGroups && i == 1) {
1526 aLocalGroups[GROUP_DOWN].Append(anExp.Current());
1529 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1530 B.Add(aShell,anExp.Current());
1532 if (isGenerateGroups && i == nbBases - 1) {
1533 aLocalGroups[GROUP_UP].Append(anExp.Current());
1536 // make sewing for this shell
1537 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1538 aSewing->SetTolerance(Precision::Confusion());
1539 aSewing->SetFaceMode(Standard_True);
1540 aSewing->SetFloatingEdgesMode(Standard_False);
1541 aSewing->SetNonManifoldMode(Standard_False);
1542 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1543 aSewing->Add(anExp.Current());
1546 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1547 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1548 aShell = TopoDS::Shell(aSewShape);
1549 GProp_GProps aSystem;
1550 BRepGProp::VolumeProperties(aShell, aSystem);
1551 if (aSystem.Mass()<0) {
1554 if (BRep_Tool::IsClosed(aShell)) {
1555 TopoDS_Solid aSolid;
1556 B.MakeSolid(aSolid);
1557 B.Add(aSolid,aShell);
1558 B.Add(aComp,aSolid);
1561 B.Add(aComp,aShell);
1565 B.Add(aComp,aShell);
1568 if (isGenerateGroups) {
1569 Standard_Integer iGrp;
1571 for (iGrp = 0; iGrp < 5; ++iGrp) {
1574 // For each sub-shape of pipe
1575 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1576 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1578 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1579 // Use the shape modified by sewing.
1580 const TopoDS_Shape &aModifGrpShape =
1581 aSewing->ModifiedSubShape(aGrpShape);
1583 aGroups[iGrp].Append(aModifGrpShape);
1585 // Use the shape as it is.
1586 aGroups[iGrp].Append(aGrpShape);
1594 // main block - creation few solids (for each pair of faces)
1595 TopTools_MapOfShape aFaces1,aFaces2;
1596 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1597 aFaces1.Add(anExp.Current());
1599 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1600 aFaces2.Add(anExp.Current());
1602 // creating map of edge faces
1603 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1604 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1605 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1606 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1608 // constuct map face->face
1609 TopTools_IndexedDataMapOfShapeShape FF;
1610 TopoDS_Shape FS1,FS2;
1611 if (nbSubBases==0) {
1612 // find edge the most distant from location point
1613 // (this edge is not shared by two faces)
1614 double maxdist = 0.;
1616 TopoDS_Vertex V11,V21;
1617 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1618 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1619 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1620 if (aList.Extent()>1)
1622 TopExp_Explorer expv;
1623 expv.Init(tmp, TopAbs_VERTEX);
1624 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1626 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1627 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1628 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1629 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1634 TopTools_ListIteratorOfListOfShape anIter(aList);
1635 FS1 = anIter.Value();
1639 // main direction for comparing
1640 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1641 // find corresponding edge from next section
1642 double minang = M_PI;
1643 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1644 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1646 TopoDS_Vertex V12,V22;
1647 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1648 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1649 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1650 if (aList.Extent()>1)
1652 TopExp_Explorer expv;
1653 expv.Init(tmp, TopAbs_VERTEX);
1654 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1656 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1657 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1658 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1659 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1660 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1661 TopoDS_Vertex V1,V2;
1664 V1 = V2tmp; P1 = P2tmp;
1665 V2 = V1tmp; P2 = P1tmp;
1668 V1 = V1tmp; P1 = P1tmp;
1669 V2 = V2tmp; P2 = P2tmp;
1671 gp_Vec Vec1(P11,P1);
1672 gp_Vec Vec2(P21,P2);
1673 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1678 TopTools_ListIteratorOfListOfShape anIter(aList);
1679 FS2 = anIter.Value();
1683 // put all pairs to map FF
1689 // add pairs of edges to FF
1690 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1692 if (aCI) delete aCI;
1693 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1699 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1700 if (anItem.IsNull()) {
1701 if (aCI) delete aCI;
1702 Standard_ConstructionError::Raise("Invalid subbase shape");
1704 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1705 if (aRefBase.IsNull()) {
1706 if (aCI) delete aCI;
1707 Standard_ConstructionError::Raise("Invalid subbase shape");
1709 TopoDS_Shape aSh = aRefBase->GetValue();
1711 if (aCI) delete aCI;
1712 Standard_ConstructionError::Raise("Invalid subbase shape");
1714 if (aSh.ShapeType()!=TopAbs_FACE) {
1715 if (aCI) delete aCI;
1716 Standard_ConstructionError::Raise("Invalid subbase shape");
1721 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1722 if (anItem.IsNull()) {
1723 if (aCI) delete aCI;
1724 Standard_ConstructionError::Raise("Invalid subbase shape");
1726 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1727 if (aRefBase.IsNull()) {
1728 if (aCI) delete aCI;
1729 Standard_ConstructionError::Raise("Invalid subbase shape");
1731 TopoDS_Shape aSh = aRefBase->GetValue();
1733 if (aCI) delete aCI;
1734 Standard_ConstructionError::Raise("Invalid subbase shape");
1736 if (aSh.ShapeType()!=TopAbs_FACE) {
1737 if (aCI) delete aCI;
1738 Standard_ConstructionError::Raise("Invalid subbase shape");
1743 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1744 if (aCI) delete aCI;
1745 Standard_ConstructionError::Raise("Invalid subbase shape");
1750 // add pairs of edges to FF
1751 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1752 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1754 if (aCI) delete aCI;
1755 Standard_ConstructionError::Raise("Can not create correct pipe");
1759 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1761 // make pipe for each pair of faces
1762 for (j=1; j<=FF.Extent(); j++) {
1763 TopoDS_Shape F1 = FF.FindKey(j);
1764 if (F1.ShapeType() != TopAbs_FACE)
1766 TopoDS_Shape F2 = FF.FindFromIndex(j);
1767 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1768 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1769 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1770 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1771 // make pipe using aWire1 and aWire2
1772 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1773 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1774 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1775 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1776 aBuilder.SetDiscreteMode();
1777 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1778 aWithContact, aWithCorrect);
1779 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1780 aWithContact, aWithCorrect);
1781 if (!aBuilder.IsReady()) {
1782 if (aCI) delete aCI;
1783 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1786 BuildPipeShell(aBuilder);
1788 TopoDS_Shape aShape = aBuilder.Shape();
1789 TopTools_SequenceOfShape aLocalGroups[5];
1792 if (isGenerateGroups) {
1794 if (!DoGroups(aBuilder, aLocalGroups)) {
1795 if (aCI) delete aCI;
1796 Standard_ConstructionError::Raise("Generate groups failure");
1799 // Clear the groups Down and Up.
1800 aLocalGroups[GROUP_DOWN].Clear();
1801 aLocalGroups[GROUP_UP].Clear();
1804 aLocalGroups[GROUP_DOWN].Append(F1);
1807 if (i == nbBases - 1) {
1808 aLocalGroups[GROUP_UP].Append(F2);
1812 TopoDS_Shell aShell;
1813 B.MakeShell(aShell);
1814 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1815 B.Add(aShell,anExp.Current());
1820 // make sewing for this shell
1821 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1822 aSewing->SetTolerance(Precision::Confusion());
1823 aSewing->SetFaceMode(Standard_True);
1824 aSewing->SetFloatingEdgesMode(Standard_False);
1825 aSewing->SetNonManifoldMode(Standard_False);
1826 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1827 aSewing->Add(anExp.Current());
1830 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1831 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1832 aShell = TopoDS::Shell(aSewShape);
1833 GProp_GProps aSystem;
1834 BRepGProp::VolumeProperties(aShell, aSystem);
1835 if (aSystem.Mass()<0) {
1836 //cout<<"aSewShape is reversed"<<endl;
1839 if (BRep_Tool::IsClosed(aShell)) {
1840 TopoDS_Solid aSolid;
1841 B.MakeSolid(aSolid);
1842 B.Add(aSolid,aShell);
1843 B.Add(aComp,aSolid);
1846 B.Add(aComp,aShell);
1850 B.Add(aComp,aShell);
1853 if (isGenerateGroups) {
1854 // Replase Group shapes by modified ones.
1855 Standard_Integer iGrp;
1858 for (iGrp = 0; iGrp < 5; ++iGrp) {
1861 // For each sub-shape of pipe
1862 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1863 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1865 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1866 // Use the shape modified by sewing.
1867 const TopoDS_Shape &aModifGrpShape =
1868 aSewing->ModifiedSubShape(aGrpShape);
1870 aGroups[iGrp].Append(aModifGrpShape);
1872 // Use the shape as it is.
1873 aGroups[iGrp].Append(aGrpShape);
1883 if (isGenerateGroups) {
1885 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1886 TopTools_IndexedMapOfShape anIndices;
1888 TopExp::MapShapes(aComp, anIndices);
1890 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
1891 if (aCI) delete aCI;
1892 Standard_ConstructionError::Raise("Generate groups failure");
1895 StoreGroups(aCI, aGroupIds);
1901 //=======================================================================
1902 //function : CreatePipeShellsWithoutPath
1903 //purpose : auxilary for Execute()
1904 //=======================================================================
1905 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
1907 //cout<<"CreatePipeShellsWithoutPath"<<endl;
1911 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1913 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1914 // vertex for recognition
1915 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
1916 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1918 Standard_Integer nbBases = aBasesObjs->Length(),
1919 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
1921 if (nbv != nbBases) {
1922 if (aCI) delete aCI;
1923 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
1926 TopTools_SequenceOfShape aGroups[5];
1927 TopTools_SequenceOfShape SecVs,Bases;
1928 for (i=1; i<=nbBases; i++) {
1930 Handle(Standard_Transient) anItem = VObjs->Value(i);
1931 if (anItem.IsNull())
1933 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
1934 TopoDS_Shape V = aRef->GetValue();
1935 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
1939 anItem = aBasesObjs->Value(i);
1940 if (anItem.IsNull())
1942 aRef = Handle(GEOM_Function)::DownCast(anItem);
1943 TopoDS_Shape aSh = aRef->GetValue();
1948 nbv = SecVs.Length();
1949 nbBases = Bases.Length();
1950 if (nbv != nbBases) {
1951 if (aCI) delete aCI;
1952 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
1955 TopoDS_Compound aComp;
1956 B.MakeCompound(aComp);
1958 for (i = 1; i < nbBases; i++) {
1959 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
1960 TopoDS_Shape aShBase1 = Bases.Value(i);
1961 TopoDS_Shape aShBase2 = Bases.Value(i+1);
1962 TopExp_Explorer anExp;
1963 Standard_Integer nbf1 = 0;
1964 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1967 Standard_Integer nbf2 = 0;
1968 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1971 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
1973 if (aCI) delete aCI;
1974 Standard_ConstructionError::Raise("Different number of faces in the sections");
1977 TopTools_MapOfShape aFaces1,aFaces2;
1978 TopTools_MapOfShape aBndEdges1;
1980 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1981 const TopoDS_Shape &aBaseFace1 = anExp.Current();
1983 if (aFaces1.Add(aBaseFace1)) {
1984 // Get boundary edges.
1985 TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
1987 for (; anExpE.More(); anExpE.Next()) {
1988 const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
1990 if (!aBndEdges1.Add(aBaseEdge1)) {
1991 aBndEdges1.Remove(aBaseEdge1);
1996 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1997 aFaces2.Add(anExp.Current());
2000 // creating map of edge faces
2001 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
2002 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
2003 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
2004 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
2006 // constuct map face->face (and sub-shapes)
2007 TopTools_IndexedDataMapOfShapeShape FF;
2008 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
2009 TopoDS_Shape FS1, FS2;
2010 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
2011 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
2012 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
2015 MESSAGE (" first pair of corresponding faces is found");
2017 // add pairs of edges and vertexes to FF
2018 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
2020 if (aCI) delete aCI;
2021 Standard_ConstructionError::Raise("Can not create correct pipe");
2023 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
2025 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2026 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
2028 // make pipe for each pair of faces
2029 // auxilary map vertex->edge for created pipe edges
2030 TopTools_IndexedDataMapOfShapeShape VPE;
2031 ShapeAnalysis_Edge sae;
2032 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
2034 for (j=1; j<=FF.Extent(); j++) {
2035 TopoDS_Shape F1 = FF.FindKey(j);
2036 if (F1.ShapeType() != TopAbs_FACE)
2038 TopoDS_Shape F2 = FF.FindFromIndex(j);
2041 //if (nbff!=3) continue;
2043 MESSAGE (" make pipe for "<<nbff<<" face");
2045 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
2046 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2047 Handle(Geom_RectangularTrimmedSurface) RTS =
2048 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
2049 S1 = RTS->BasisSurface();
2051 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
2052 if (Pln1.IsNull()) {
2053 if (aCI) delete aCI;
2054 Standard_ConstructionError::Raise("Surface from face is not plane");
2056 gp_Vec aDir1(Pln1->Axis().Direction());
2058 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
2059 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2060 Handle(Geom_RectangularTrimmedSurface) RTS =
2061 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
2062 S2 = RTS->BasisSurface();
2064 Handle(Geom_Plane) Pln2 =
2065 Handle(Geom_Plane)::DownCast(S2);
2066 if (Pln2.IsNull()) {
2067 if (aCI) delete aCI;
2068 Standard_ConstructionError::Raise("Surface from face is not plane");
2070 gp_Vec aDir2(Pln2->Axis().Direction());
2072 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
2073 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
2075 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
2077 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
2080 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
2081 TopTools_SequenceOfShape aNewFs;
2082 TopTools_SequenceOfShape aLocalGroups[5];
2085 for (; anExpE.More(); anExpE.Next()) {
2086 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2088 if (!FF.Contains(E1))
2089 MESSAGE ("map FF not contains key E1");
2091 if (VPE.Contains(E1)) {
2092 aNewFs.Append(VPE.FindFromKey(E1));
2094 MESSAGE (" using existed face");
2099 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2100 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2101 TopoDS_Vertex V2 = sae.LastVertex(E1);
2102 if (!FF.Contains(V1))
2103 MESSAGE ("map FF not contains key V1");
2104 if (!FF.Contains(V2))
2105 MESSAGE ("map FF not contains key V2");
2106 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2107 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2108 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2109 if (Vtmp.IsSame(V4))
2111 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2112 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2113 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2114 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2117 Handle(Geom_BSplineCurve) C2;
2118 if (VPE.Contains(V2)) {
2119 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2121 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2124 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2125 HAP->SetValue(1,P2);
2126 HAP->SetValue(2,P3);
2127 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2128 anInt.Load(aDir1,aDir2);
2131 B.MakeEdge(E2,C2,1.e-7);
2132 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2133 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2138 Handle(Geom_BSplineCurve) C4;
2139 if (VPE.Contains(V1)) {
2140 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2142 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2145 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2146 HAP->SetValue(1,P1);
2147 HAP->SetValue(2,P4);
2148 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2149 anInt.Load(aDir1,aDir2);
2152 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2153 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2154 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2163 B.Add(W,E4.Reversed());
2168 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2169 //bool IsConicC1 = false;
2170 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2171 // IsConicC1 = true;
2172 // cout<<"C1 - Geom_Conic"<<endl;
2174 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2175 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2178 // double tol = BRep_Tool::Tolerance(E1);
2179 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2180 // C1 = ApxC1.Curve();
2182 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2183 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2184 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2189 Handle(Geom_BSplineCurve) CE1 =
2190 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2191 if (CE1->Degree()<3)
2192 CE1->IncreaseDegree(3);
2193 Handle(Geom_BSplineCurve) CE2 =
2194 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2195 if (CE2->Degree()<3)
2196 CE2->IncreaseDegree(3);
2197 Handle(Geom_BSplineCurve) CE3 =
2198 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2199 if (CE3->Degree()<3)
2200 CE3->IncreaseDegree(3);
2201 Handle(Geom_BSplineCurve) CE4 =
2202 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2203 if (CE4->Degree()<3)
2204 CE4->IncreaseDegree(3);
2206 Handle(Geom_Surface) BS;
2208 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2209 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2213 MESSAGE (" can not create BSplineSurface - create Bezier");
2215 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2216 double fp1,lp1,fp2,lp2;
2217 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2218 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2227 // get points from C1
2228 if (P1.Distance(P1C1)<1.e-6) {
2236 double step = (lp-fp)/(NbP-1);
2237 Points.SetValue(1,1,P1);
2239 for (n1=2; n1<NbP; n1++) {
2243 Points.SetValue(1,n1,P);
2245 Points.SetValue(1,NbP,P2);
2246 // get points from C3
2247 if (P4.Distance(P1C3)<1.e-6) {
2255 step = (lp-fp)/(NbP-1);
2256 Points.SetValue(NbP,1,P4);
2258 for (n1=2; n1<NbP; n1++) {
2262 Points.SetValue(NbP,n1,P);
2264 Points.SetValue(NbP,NbP,P3);
2265 // create isolines and get points from them
2266 for (n1=1; n1<=NbP; n1++) {
2267 gp_Pnt PI1 = Points.Value(1,n1);
2268 gp_Pnt PI2 = Points.Value(NbP,n1);
2269 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2270 HAP->SetValue(1,PI1);
2271 HAP->SetValue(2,PI2);
2272 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2273 anInt.Load(aDir1,aDir2);
2275 Handle(Geom_Curve) iso = anInt.Curve();
2276 fp = iso->FirstParameter();
2277 lp = iso->LastParameter();
2278 step = (lp-fp)/(NbP-1);
2280 TopoDS_Compound VComp;
2281 B.MakeCompound(VComp);
2282 for (n2=2; n2<NbP; n2++) {
2286 Points.SetValue(n2,n1,P);
2289 // create surface and face
2290 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2291 BS = new Geom_BezierSurface(Points);
2294 BRepBuilderAPI_MakeFace BB(BS,W);
2295 TopoDS_Face NewF = BB.Face();
2296 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2298 sff->FixOrientation();
2299 TopoDS_Face FixedFace = sff->Face();
2300 aNewFs.Append(FixedFace);
2301 VPE.Add(E1,FixedFace);
2303 if (isGenerateGroups) {
2304 if (aBndEdges1.Contains(E1)) {
2305 // This is a boundary face.
2306 aLocalGroups[GROUP_OTHER].Append(FixedFace);
2311 TopoDS_Shell aShell;
2312 B.MakeShell(aShell);
2313 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2314 B.Add(aShell,aNewFs(nf));
2320 if (isGenerateGroups && i == 1) {
2321 aLocalGroups[GROUP_DOWN].Append(F1);
2324 if (isGenerateGroups && i == nbBases - 1) {
2325 aLocalGroups[GROUP_UP].Append(F2);
2328 // make sewing for this shell
2329 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2330 aSewing->SetTolerance(Precision::Confusion());
2331 aSewing->SetFaceMode(Standard_True);
2332 aSewing->SetFloatingEdgesMode(Standard_False);
2333 aSewing->SetNonManifoldMode(Standard_False);
2334 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2335 aSewing->Add(anExp.Current());
2338 MESSAGE (" shell for face "<<nbff<<" is created");
2339 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2340 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2341 aShell = TopoDS::Shell(aSewShape);
2342 GProp_GProps aSystem;
2343 BRepGProp::VolumeProperties(aShell, aSystem);
2344 if (aSystem.Mass()<0) {
2345 //cout<<"aSewShape is reversed"<<endl;
2348 if (BRep_Tool::IsClosed(aShell)) {
2349 TopoDS_Solid aSolid;
2350 B.MakeSolid(aSolid);
2351 B.Add(aSolid,aShell);
2352 B.Add(aComp,aSolid);
2353 MESSAGE (" solid for face "<<nbff<<" is created");
2356 B.Add(aComp,aShell);
2357 MESSAGE (" solid for face "<<nbff<<" is not created");
2361 B.Add(aComp,aShell);
2362 MESSAGE (" solid for face "<<nbff<<" is not created");
2365 if (isGenerateGroups) {
2366 Standard_Integer iGrp;
2368 for (iGrp = 0; iGrp < 5; ++iGrp) {
2371 // For each sub-shape of pipe
2372 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2373 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2375 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2376 // Use the shape modified by sewing.
2377 const TopoDS_Shape &aModifGrpShape =
2378 aSewing->ModifiedSubShape(aGrpShape);
2380 aGroups[iGrp].Append(aModifGrpShape);
2382 // Use the shape as it is.
2383 aGroups[iGrp].Append(aGrpShape);
2391 if (isGenerateGroups) {
2393 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2394 TopTools_IndexedMapOfShape anIndices;
2396 TopExp::MapShapes(aComp, anIndices);
2398 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2399 if (aCI) delete aCI;
2400 Standard_ConstructionError::Raise("Generate groups failure");
2403 StoreGroups(aCI, aGroupIds);
2409 //=======================================================================
2410 //function : CreatePipeBiNormalAlongVector
2411 //purpose : auxilary for Execute()
2412 //=======================================================================
2413 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2414 GEOMImpl_IPipe* aCI)
2416 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2418 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2419 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2420 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2421 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2423 if (aShapeBase.IsNull()) {
2424 if (aCIBN) delete aCIBN;
2425 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2428 // Make copy to prevent modifying of base object: 0021525
2429 BRepBuilderAPI_Copy Copy (aShapeBase);
2431 aShapeBase = Copy.Shape();
2434 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2437 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2438 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2440 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2443 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2444 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2445 aProf = wexp.Current();
2448 Standard_TypeMismatch::Raise
2449 ("MakePipe aborted : invalid type of base");
2451 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2452 PipeBuilder.Add(aProf);
2454 if (aShapeVec.IsNull()) {
2455 if (aCIBN) delete aCIBN;
2456 Standard_NullObject::Raise
2457 ("MakePipe aborted : null vector argument");
2459 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2460 Standard_TypeMismatch::Raise
2461 ("MakePipe aborted: invalid type of vector");
2462 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2463 TopoDS_Vertex V1, V2;
2464 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2465 if (V1.IsNull() || V2.IsNull())
2466 Standard_NullObject::Raise
2467 ("MakePipe aborted: vector is not defined");
2468 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2469 gp_Dir BiNormal(aVec);
2470 PipeBuilder.SetMode(BiNormal);
2472 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2474 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2475 PipeBuilder.MakeSolid();
2478 if (!CreateGroups(PipeBuilder, aCIBN)) {
2479 if (aCIBN) delete aCIBN;
2480 Standard_ConstructionError::Raise("Generate groups failure");
2483 return PipeBuilder.Shape();
2486 //=======================================================================
2487 //function : FillGroups
2488 //purpose : auxilary for DoGroups()
2489 //=======================================================================
2490 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
2491 const TopTools_IndexedMapOfShape &theIndices,
2492 Handle(TColStd_HArray1OfInteger) *theGroupIds)
2496 for (i = 0; i < 5; ++i) {
2497 if (!theGroups[i].IsEmpty()) {
2498 const Standard_Integer aNbShapes = theGroups[i].Length();
2501 theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
2503 for (j = 1; j <= aNbShapes; ++j) {
2504 const TopoDS_Shape &aShape = theGroups[i].Value(j);
2505 const Standard_Integer anIndex = theIndices.FindIndex(aShape);
2511 theGroupIds[i]->SetValue(j, anIndex);
2519 //=======================================================================
2520 //function : StoreGroups
2521 //purpose : auxilary for CreateGroups()
2522 //=======================================================================
2523 void StoreGroups(GEOMImpl_IPipe *theCI,
2524 Handle(TColStd_HArray1OfInteger) *theGroups)
2526 if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
2527 theCI->SetGroupDown(theGroups[GROUP_DOWN]);
2530 if (theGroups[GROUP_UP].IsNull() == Standard_False) {
2531 theCI->SetGroupUp(theGroups[GROUP_UP]);
2534 if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
2535 theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
2538 if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
2539 theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
2542 if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
2543 theCI->SetGroupOther(theGroups[GROUP_OTHER]);
2547 //=======================================================================
2548 //function : CreateDownUpGroups
2549 //purpose : auxilary for DoGroups()
2550 //=======================================================================
2551 static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
2552 TopTools_SequenceOfShape *theGroups,
2553 Standard_Boolean &IsDoSides)
2555 const TopoDS_Shape aDownShape = theSweep->FirstShape();
2556 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2557 TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
2559 IsDoSides = Standard_False;
2564 anUpDownType = TopAbs_EDGE;
2566 if (GEOMUtils::IsOpenPath(aDownShape)) {
2567 IsDoSides = Standard_True;
2572 anUpDownType = TopAbs_FACE;
2578 if (anUpDownType == TopAbs_SHAPE) {
2579 // Invalid Up and Down group type.
2583 TopExp_Explorer anExp(aDownShape, anUpDownType);
2584 TopTools_MapOfShape aMapFence;
2586 // Create Down group.
2587 for (; anExp.More(); anExp.Next()) {
2588 const TopoDS_Shape &aShape = anExp.Current();
2590 if (aMapFence.Add(aShape)) {
2591 theGroups[GROUP_DOWN].Append(aShape);
2596 const TopoDS_Shape anUpShape = theSweep->LastShape();
2599 anExp.Init(anUpShape, anUpDownType);
2601 for (; anExp.More(); anExp.Next()) {
2602 const TopoDS_Shape &aShape = anExp.Current();
2604 if (aMapFence.Add(aShape)) {
2605 theGroups[GROUP_UP].Append(aShape);
2612 //=======================================================================
2613 //function : DoGroups
2614 //purpose : auxilary for CreateGroups()
2615 //=======================================================================
2616 bool DoGroups(BRepOffsetAPI_MakePipeShell &theSweep,
2617 TopTools_SequenceOfShape *theGroups)
2619 Standard_Boolean isDoSides = Standard_False;
2621 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2622 // Up and Down groups creation failure
2626 const TopoDS_Shape aDownShape = theSweep.FirstShape();
2629 // Create Side1 and Side2 groups.
2630 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2631 TopoDS_Vertex aV[2];
2634 if (aType == TopAbs_EDGE) {
2635 TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
2636 } else { // aType == TopAbs_WIRE
2637 TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
2640 for (i = 0; i < 2; ++i) {
2641 if (aV[i].IsNull() == Standard_False) {
2642 const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
2644 if (!aLstSide.IsEmpty()) {
2645 TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
2646 TopTools_MapOfShape aMapFence;
2647 const Standard_Integer anIdSide =
2648 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2650 for (; aSideIt.More(); aSideIt.Next()) {
2651 const TopoDS_Shape &aSideShape = aSideIt.Value();
2653 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2654 if (aMapFence.Add(aSideShape)) {
2655 theGroups[anIdSide].Append(aSideShape);
2658 // Only edges can be is Side1 and Side2 groups.
2666 // Create Other group. Get boudnary edges of the profile.
2667 TopTools_MapOfShape aMapBndEdges;
2668 TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
2670 for (; anExp.More(); anExp.Next()) {
2671 const TopoDS_Shape &anEdge = anExp.Current();
2673 if (!aMapBndEdges.Add(anEdge)) {
2674 aMapBndEdges.Remove(anEdge);
2678 // Fill the map of faces generated from profile's boundary edges.
2679 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2680 TopTools_MapOfShape aMapFence;
2682 for (; anIter.More(); anIter.Next()) {
2683 const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
2685 if (!aLstOther.IsEmpty()) {
2686 TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
2688 for (; anOtherIt.More(); anOtherIt.Next()) {
2689 const TopoDS_Shape &anOtherShape = anOtherIt.Value();
2691 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2692 if (aMapFence.Add(anOtherShape)) {
2693 theGroups[GROUP_OTHER].Append(anOtherShape);
2696 // Only faces can be in Other group.
2707 //=======================================================================
2708 //function : CreateGroups
2709 //purpose : auxilary for Execute()
2710 //=======================================================================
2711 bool CreateGroups(BRepOffsetAPI_MakePipeShell &theSweep,
2712 GEOMImpl_IPipe *theCI)
2714 if (!theCI->GetGenerateGroups()) {
2720 TopTools_SequenceOfShape aGroups[5];
2722 if (!DoGroups(theSweep, aGroups)) {
2727 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2728 TopTools_IndexedMapOfShape anIndices;
2729 const TopoDS_Shape aResult = theSweep.Shape();
2731 TopExp::MapShapes(aResult, anIndices);
2733 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2738 StoreGroups(theCI, aGroupIds);
2743 //=======================================================================
2744 //function : DoGroups
2745 //purpose : auxilary for CreateGroups()
2746 //=======================================================================
2747 static bool DoGroups(const TopoDS_Shape &theProfile,
2748 const TopoDS_Shape &thePath,
2749 BRepOffsetAPI_MakePipe &theSweep,
2750 TopTools_SequenceOfShape *theGroups)
2752 Standard_Boolean isDoSides = Standard_False;
2754 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2755 // Up and Down groups creation failure
2760 // Create Side1 and Side2 groups.
2761 const TopAbs_ShapeEnum aType = theProfile.ShapeType();
2762 TopoDS_Vertex aV[2];
2765 if (aType == TopAbs_EDGE) {
2766 TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
2767 } else { // aType == TopAbs_WIRE
2768 TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
2771 for (i = 0; i < 2; ++i) {
2772 if (aV[i].IsNull() == Standard_False) {
2773 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2774 TopTools_MapOfShape aMapFence;
2775 const Standard_Integer anIdSide =
2776 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2778 for (; anExpP.More(); anExpP.Next()) {
2779 const TopoDS_Shape aSideShape =
2780 theSweep.Generated(anExpP.Current(), aV[i]);
2782 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2783 if (aMapFence.Add(aSideShape)) {
2784 theGroups[anIdSide].Append(aSideShape);
2787 // Only edges can be is Side1 and Side2 groups.
2794 // Create Other group. Get boudnary edges of the profile.
2795 TopTools_MapOfShape aMapBndEdges;
2796 TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
2798 for (; anExp.More(); anExp.Next()) {
2799 const TopoDS_Shape &anEdge = anExp.Current();
2801 if (!aMapBndEdges.Add(anEdge)) {
2802 aMapBndEdges.Remove(anEdge);
2806 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2807 TopTools_MapOfShape aMapFence;
2809 for (; anExpP.More(); anExpP.Next()) {
2810 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2812 for (; anIter.More(); anIter.Next()) {
2813 const TopoDS_Shape anOtherShape =
2814 theSweep.Generated(anExpP.Current(), anIter.Key());
2816 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2817 if (aMapFence.Add(anOtherShape)) {
2818 theGroups[GROUP_OTHER].Append(anOtherShape);
2821 // Only faces can be in Other group.
2831 //=======================================================================
2832 //function : CreateGroups
2833 //purpose : auxilary for Execute()
2834 //=======================================================================
2835 static bool CreateGroups(const TopoDS_Shape &theProfile,
2836 const TopoDS_Shape &thePath,
2837 BRepOffsetAPI_MakePipe &theSweep,
2838 GEOMImpl_IPipe *theCI)
2840 if (!theCI->GetGenerateGroups()) {
2846 TopTools_SequenceOfShape aGroups[5];
2848 if (!DoGroups(theProfile, thePath, theSweep, aGroups)) {
2853 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2854 TopTools_IndexedMapOfShape anIndices;
2855 const TopoDS_Shape aResult = theSweep.Shape();
2857 TopExp::MapShapes(aResult, anIndices);
2859 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2864 StoreGroups(theCI, aGroupIds);
2869 //=======================================================================
2870 //function : Execute
2872 //=======================================================================
2873 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
2875 if (Label().IsNull()) return 0;
2876 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
2877 Standard_Integer aType = aFunction->GetType();
2879 GEOMImpl_IPipe* aCI = 0;
2880 if (aType == PIPE_BASE_PATH)
2881 aCI = new GEOMImpl_IPipe (aFunction);
2882 else if (aType == PIPE_DIFFERENT_SECTIONS)
2883 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
2884 else if (aType == PIPE_SHELL_SECTIONS)
2885 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2886 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
2887 aCI = new GEOMImpl_IPipeShellSect (aFunction);
2888 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
2889 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
2893 TopoDS_Wire aWirePath;
2894 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
2895 // working with path
2896 Handle(GEOM_Function) aRefPath = aCI->GetPath();
2897 TopoDS_Shape aShapePath = aRefPath->GetValue();
2899 if (aShapePath.IsNull()) {
2900 MESSAGE ("Driver : path is null");
2901 if (aCI) delete aCI;
2902 Standard_NullObject::Raise("MakePipe aborted : null path argument");
2907 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
2908 TopTools_SequenceOfShape anEdges;
2909 TopExp_Explorer anExp;
2913 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2914 B.Add(W, anExp.Current());
2920 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
2921 aWirePath = TopoDS::Wire(aShapePath);
2925 if (aShapePath.ShapeType() == TopAbs_EDGE) {
2926 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
2927 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
2932 if (aCI) delete aCI;
2933 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
2936 // Check if it is possible to create groups.
2937 if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
2942 Standard_ConstructionError::Raise
2943 ("Can't create groups if the path is closed");
2947 TopoDS_Shape aShape;
2948 const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
2950 if (aType == PIPE_BASE_PATH) {
2951 Handle(GEOM_Function) aRefBase = aCI->GetBase();
2952 TopoDS_Shape aShapeBase;
2954 // Make copy to prevent modifying of base object 0020766 : EDF 1320
2955 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
2957 aShapeBase = Copy.Shape();
2959 if (aShapeBase.IsNull()) {
2960 if (aCI) delete aCI;
2961 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2965 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
2966 aShapeBase.ShapeType() == TopAbs_WIRE)
2968 TopoDS_Wire Profile;
2969 if (aShapeBase.ShapeType() == TopAbs_WIRE)
2970 Profile = TopoDS::Wire(aShapeBase);
2974 BB.MakeWire(Profile);
2975 BB.Add(Profile, aShapeBase);
2978 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
2979 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
2980 if (FaceBuilder.IsDone())
2981 Sweep.SetMode(FaceBuilder.Face());
2984 Standard_Boolean isDone = BuildPipeShell(Sweep);
2988 if (aCI) delete aCI;
2989 Standard_ConstructionError::Raise("MakePipeShell failed");
2992 aShape = Sweep.Shape(); //result is good
2994 if (!CreateGroups(Sweep, aCI)) {
2995 if (aCI) delete aCI;
2996 Standard_ConstructionError::Raise("Generate groups failure");
3001 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
3002 BRepOffsetAPI_MakePipe aMkPipe(aWirePath, aShapeBase, theBestMode);
3004 if (aMkPipe.IsDone()) {
3005 aShape = aMkPipe.Shape();
3007 if (!CreateGroups(aShapeBase, aWirePath, aMkPipe, aCI)) {
3008 if (aCI) delete aCI;
3009 Standard_ConstructionError::Raise("Generate groups failure");
3011 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
3012 // Try to use Descrete Trihedron mode.
3013 BRepOffsetAPI_MakePipe aMkPipeDescrete
3014 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron);
3016 if (aMkPipeDescrete.IsDone()) {
3017 aShape = aMkPipeDescrete.Shape();
3019 if (!CreateGroups(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
3020 if (aCI) delete aCI;
3021 Standard_ConstructionError::Raise("Generate groups failure");
3028 //building pipe with different sections
3029 else if (aType == PIPE_DIFFERENT_SECTIONS) {
3030 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
3031 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
3032 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
3033 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
3034 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
3041 Standard_Integer nbBases = aBasesObjs->Length();
3042 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
3044 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
3045 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
3048 for (i = 1; i <= nbBases; i++) {
3049 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
3050 if (anItem.IsNull())
3052 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
3053 if (aRefBase.IsNull())
3055 if (aRefBase->GetValue().IsNull())
3058 aHSeqBases->Append(aRefBase->GetValue());
3060 for (i = 1; i <= nbLocs; i++) {
3061 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
3062 if (anItemLoc.IsNull())
3064 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
3065 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
3066 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
3069 aHSeqLocs->Append(aShapeLoc);
3073 Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
3074 Handle(TColStd_HArray1OfInteger) aGroups[5];
3076 if (isGenerateGroups) {
3080 aShape = CreatePipeWithDifferentSections
3081 (aWirePath, aHSeqBases, aHSeqLocs,
3082 aWithContact, aWithCorrect, pGroups);
3084 if (isGenerateGroups) {
3085 // Store created groups.
3086 GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
3088 StoreGroups(&aPipeDS, aGroups);
3092 //building pipe with shell sections
3093 else if (aType == PIPE_SHELL_SECTIONS) {
3094 aShape = CreatePipeForShellSections(aWirePath,aCI);
3097 //building pipe shell sections without path
3098 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
3099 aShape = CreatePipeShellsWithoutPath(aCI);
3102 //building a pipe with constant bi-normal along given vector
3103 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
3104 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
3112 if (aShape.IsNull()) return 0;
3114 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
3115 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
3117 if (aType != PIPE_BASE_PATH &&
3118 aType != PIPE_SHELLS_WITHOUT_PATH) {
3119 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
3120 if (anExpV.More()) {
3121 Standard_Real aVertMaxTol = -RealLast();
3122 for (; anExpV.More(); anExpV.Next()) {
3123 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
3124 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
3125 if (aTol > aVertMaxTol)
3128 aVertMaxTol += Precision::Confusion();
3130 TopTools_DataMapOfShapeListOfShape aMapModif;
3131 TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
3133 if (isGenerateGroups) {
3134 pMapModif = &aMapModif;
3137 TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
3138 (aShape, aVertMaxTol, Standard_True, pMapModif);
3140 if (isGenerateGroups && !aMapModif.IsEmpty()) {
3142 GEOMImpl_IPipe aCI(aFunction);
3143 Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
3144 { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
3145 aCI.GetGroupSide2(), aCI.GetGroupOther() };
3146 TopTools_IndexedMapOfShape anIndices;
3147 TopTools_IndexedMapOfShape aNewIndices;
3148 TopTools_SequenceOfShape aNewShapes[5];
3149 TopTools_MapOfShape aMapReplaced;
3150 TopTools_MapOfShape aMapGlued;
3151 Standard_Integer iGrp;
3154 TopExp::MapShapes(aShape, anIndices);
3155 TopExp::MapShapes(aNewShape, aNewIndices);
3157 for (iGrp = 0; iGrp < 5; ++iGrp) {
3158 if (aGroupIDs[iGrp].IsNull() == Standard_False) {
3159 const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
3160 const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
3162 for (i = aLower; i <= anUpper; ++i) {
3163 const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
3164 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
3166 if (aMapModif.IsBound(aSubShape)) {
3167 const TopTools_ListOfShape &aListModif =
3168 aMapModif.Find(aSubShape);
3169 TopTools_ListIteratorOfListOfShape anIter(aListModif);
3171 for (; anIter.More(); anIter.Next()) {
3172 const TopoDS_Shape &aNewShape = anIter.Value();
3174 if (aMapReplaced.Add(aNewShape)) {
3175 aNewShapes[iGrp].Append(aNewShape);
3177 // This is a glued shape. It means that it is internal
3178 // one and should be removed from groups later.
3179 aMapGlued.Add(aNewShape);
3183 // Shape is not modified.
3184 aNewShapes[iGrp].Append(aSubShape);
3190 if (!aMapGlued.IsEmpty()) {
3191 // Remove glued (internal) shapes from groups.
3192 for (iGrp = 0; iGrp < 5; ++iGrp) {
3193 Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
3195 for (i = 1; i < aNbShapes; ++i) {
3196 const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
3198 if (aMapGlued.Contains(aNewShape)) {
3199 aNewShapes[iGrp].Remove(i);
3207 // Store modified groups.
3208 Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
3210 if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
3211 Standard_ConstructionError::Raise("Generate groups failure");
3214 StoreGroups(&aCI, aNewGroupIDs);
3221 // Note: group indices should not be changed after the next call.
3222 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
3223 aFunction->SetValue(aRes);
3225 log.SetTouched(Label());
3229 //================================================================================
3231 * \brief Returns a name of creation operation and names and values of creation parameters
3233 //================================================================================
3235 bool GEOMImpl_PipeDriver::
3236 GetCreationInformation(std::string& theOperationName,
3237 std::vector<GEOM_Param>& theParams)
3239 if (Label().IsNull()) return 0;
3240 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
3241 Standard_Integer aType = function->GetType();
3244 case PIPE_BASE_PATH:
3246 theOperationName = "PIPE";
3247 GEOMImpl_IPipe aCI( function );
3248 AddParam( theParams, "Base Object", aCI.GetBase() );
3249 AddParam( theParams, "Path Object", aCI.GetPath() );
3252 case PIPE_BI_NORMAL_ALONG_VECTOR:
3254 theOperationName = "PIPE";
3255 GEOMImpl_IPipeBiNormal aCI( function );
3256 AddParam( theParams, "Base Object", aCI.GetBase() );
3257 AddParam( theParams, "Path Object", aCI.GetPath() );
3258 AddParam( theParams, "BiNormal", aCI.GetVector() );
3261 case PIPE_DIFFERENT_SECTIONS:
3263 theOperationName = "PIPE";
3264 GEOMImpl_IPipeDiffSect aCI( function );
3265 AddParam( theParams, "Bases", aCI.GetBases() );
3266 AddParam( theParams, "Locations", aCI.GetLocations() );
3267 AddParam( theParams, "Path", aCI.GetPath() );
3268 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3269 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3272 case PIPE_SHELL_SECTIONS:
3274 theOperationName = "PIPE";
3275 GEOMImpl_IPipeShellSect aCI( function );
3276 AddParam( theParams, "Bases", aCI.GetBases() );
3277 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
3278 AddParam( theParams, "Locations", aCI.GetLocations() );
3279 AddParam( theParams, "Path", aCI.GetPath() );
3280 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3281 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3284 case PIPE_SHELLS_WITHOUT_PATH:
3286 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
3287 GEOMImpl_IPipeShellSect aCI( function );
3288 AddParam( theParams, "Bases", aCI.GetBases() );
3289 AddParam( theParams, "Locations", aCI.GetLocations() );
3299 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
3300 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);