1 // Copyright (C) 2007-2020 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_MakeSolid.hxx>
47 #include <BRepBuilderAPI_MakeWire.hxx>
48 #include <BRepBuilderAPI_Sewing.hxx>
49 #include <BRepClass3d_SolidClassifier.hxx>
50 #include <BRepGProp.hxx>
51 #include <GeomFill_Trihedron.hxx>
52 #include <GeomFill_CorrectedFrenet.hxx>
53 #include <BRepOffsetAPI_MakePipe.hxx>
54 #include <BRepOffsetAPI_MakePipeShell.hxx>
55 #include <BRepOffsetAPI_ThruSections.hxx>
59 #include <TopExp_Explorer.hxx>
61 #include <TopoDS_Wire.hxx>
62 #include <TopoDS_Edge.hxx>
63 #include <TopoDS_Shape.hxx>
64 #include <TopoDS_Solid.hxx>
65 #include <TopoDS_Shell.hxx>
66 #include <TopoDS_Face.hxx>
67 #include <TopoDS_Compound.hxx>
68 #include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
69 #include <TopTools_SequenceOfShape.hxx>
70 #include <TopTools_HSequenceOfShape.hxx>
71 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
72 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
73 #include <TopTools_ListIteratorOfListOfShape.hxx>
74 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <GProp_GProps.hxx>
78 #include <GeomAPI_ProjectPointOnCurve.hxx>
79 #include <GeomAPI_Interpolate.hxx>
80 #include <Geom_TrimmedCurve.hxx>
81 #include <Geom_Plane.hxx>
82 #include <Geom_RectangularTrimmedSurface.hxx>
83 #include <Geom_BezierSurface.hxx>
84 #include <Geom_Line.hxx>
85 #include <Geom_Conic.hxx>
86 #include <Geom_BSplineCurve.hxx>
87 #include <Geom_BSplineSurface.hxx>
88 #include <GeomAdaptor_HCurve.hxx>
89 #include <GeomFill_BSplineCurves.hxx>
90 #include <GeomConvert_ApproxCurve.hxx>
91 #include <GeomConvert.hxx>
93 #include <TColgp_SequenceOfPnt.hxx>
94 #include <TColgp_HArray1OfPnt.hxx>
95 #include <TColgp_Array2OfPnt.hxx>
96 #include <TColStd_HSequenceOfTransient.hxx>
98 #include <Precision.hxx>
100 #include <Standard_NullObject.hxx>
101 #include <Standard_TypeMismatch.hxx>
102 #include <Standard_ConstructionError.hxx>
104 #include "utilities.h"
108 #define GROUP_SIDE1 2
109 #define GROUP_SIDE2 3
110 #define GROUP_OTHER 4
112 static const Standard_Real TolPipeSurf = 5.e-4;
114 static bool FillGroups(const TopTools_SequenceOfShape *theGroups,
115 const TopTools_IndexedMapOfShape &theIndices,
116 Handle(TColStd_HArray1OfInteger) *theGroupIds);
118 static void StoreGroups(GEOMImpl_IPipe *theCI,
119 Handle(TColStd_HArray1OfInteger) *theGroups);
121 // after OCCT improvement
122 static bool DoGroups1(const TopoDS_Shape &theProfile,
123 BRepOffsetAPI_MakePipeShell &theSweep,
124 TopTools_SequenceOfShape *theGroups);
126 static bool CreateGroups1(const TopoDS_Shape &theProfile,
127 BRepOffsetAPI_MakePipeShell &theSweep,
128 GEOMImpl_IPipe *theCI);
130 //=======================================================================
133 //=======================================================================
134 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
136 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
140 //=======================================================================
141 //function : GEOMImpl_PipeDriver
143 //=======================================================================
144 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
148 //=======================================================================
149 //function : EvaluateBestSweepMode
150 //purpose : auxiliary for right call of MakePipe and MakePipeShell
151 //=======================================================================
152 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
154 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
156 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
157 for (; Explo.More(); Explo.Next())
159 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
160 Standard_Real fpar, lpar;
161 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
162 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
163 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
165 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
166 aCorrFrenet->SetCurve(GAHcurve);
167 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
168 if (aMode == GeomFill_IsDiscreteTrihedron)
173 if (aMode == GeomFill_IsCorrectedFrenet)
180 //=======================================================================
181 //function : BuildPipeShell
182 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
183 // mode. Returns Standard_True if the building is done successfully.
184 //=======================================================================
185 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
187 theBuilder.SetForceApproxC1(Standard_True);
191 Standard_Boolean isDone = theBuilder.IsDone();
194 theBuilder.ErrorOnSurface() > TolPipeSurf) {
195 // Try to use Descrete Trihedron mode.
196 theBuilder.SetDiscreteMode();
198 isDone = theBuilder.IsDone();
204 //=======================================================================
205 //function : FillForOtherEdges
206 //purpose : auxiliary for CreatePipeForShellSections()
207 //=======================================================================
208 static bool FillForOtherEdges(const TopoDS_Shape& F1,
209 const TopoDS_Shape& E1,
210 const TopoDS_Shape& V1,
211 TopTools_IndexedDataMapOfShapeShape& FF)
213 // find other pairs for vertexes and edges
214 // creating map of vertex edges for both faces
215 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
216 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
217 if (!FF.Contains(F1)) MESSAGE(" FillForOtherEdges: map FF not contains key F1");
218 if (!FF.Contains(E1)) MESSAGE(" FillForOtherEdges: map FF not contains key E1");
219 if (!FF.Contains(V1)) MESSAGE(" FillForOtherEdges: map FF not contains key V1");
220 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
221 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
222 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
223 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
224 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
226 TopoDS_Edge ES1 = TopoDS::Edge(E1);
227 TopoDS_Edge ES2 = TopoDS::Edge(E2);
228 TopoDS_Shape VS1 = V1;
229 TopoDS_Shape VS2 = V2;
231 ShapeAnalysis_Edge sae;
233 if (!aMapVertEdge1.Contains(VS1)) MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
234 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
235 TopTools_ListIteratorOfListOfShape anIter1(aList1);
236 if (anIter1.Value().IsSame(ES1)) {
239 if (!aMapVertEdge2.Contains(VS2)) MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
240 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
241 TopTools_ListIteratorOfListOfShape anIter2(aList2);
242 if (anIter2.Value().IsSame(ES2)) {
245 ES1 = TopoDS::Edge(anIter1.Value());
246 ES2 = TopoDS::Edge(anIter2.Value());
247 if (!FF.Contains(ES1)) {
250 if (VS1.IsSame(sae.FirstVertex(ES1)))
251 VS1 = sae.LastVertex(ES1);
253 VS1 = sae.FirstVertex(ES1);
254 if (VS2.IsSame(sae.FirstVertex(ES2)))
255 VS2 = sae.LastVertex(ES2);
257 VS2 = sae.FirstVertex(ES2);
260 if (!FF.Contains(VS1)) {
268 //=======================================================================
269 //function : FillCorrespondingEdges
270 //purpose : auxiliary for CreatePipeForShellSections()
271 //=======================================================================
272 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
273 const TopoDS_Shape& FS2,
274 const TopoDS_Vertex& aLoc1,
275 const TopoDS_Vertex& aLoc2,
276 const TopoDS_Wire& aWirePath,
277 TopTools_IndexedDataMapOfShapeShape& FF)
279 // find corresponding edges
280 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
281 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
282 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
283 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
284 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
285 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
286 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
287 if (theBestMode == GeomFill_IsDiscreteTrihedron)
288 aBuilder.SetDiscreteMode();
289 aBuilder.Add(aWire1, aLoc1);
290 aBuilder.Add(aWire2, aLoc2);
291 if (!aBuilder.IsReady()) {
295 BuildPipeShell(aBuilder);
297 TopoDS_Shape aShape = aBuilder.Shape();
298 ShapeAnalysis_Edge sae;
299 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
300 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
301 TopTools_MapOfShape Vs1,Vs2;
303 exp.Init(FS1, TopAbs_EDGE);
304 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
305 TopoDS_Vertex V11 = sae.FirstVertex(E1);
306 TopoDS_Vertex V21 = sae.LastVertex(E1);
307 gp_Pnt P11 = BRep_Tool::Pnt(V11);
308 gp_Pnt P21 = BRep_Tool::Pnt(V21);
309 // find corresponding vertexes from created shape
310 TopoDS_Vertex VN11,VN21;
311 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
312 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
313 gp_Pnt P = BRep_Tool::Pnt(V);
314 if (P.Distance(P11)<tol) {
317 if (P.Distance(P21)<tol) {
321 // find edge contains VN11 and VN21 and corresponding vertexes
322 TopoDS_Vertex VN12,VN22;
323 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
324 TopoDS_Shape F = exp.Current();
325 TopExp_Explorer expe;
327 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
328 TopoDS_Edge E = TopoDS::Edge(expe.Current());
329 TopoDS_Vertex VF = sae.FirstVertex(E);
330 TopoDS_Vertex VL = sae.LastVertex(E);
331 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
337 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
338 TopoDS_Edge E = TopoDS::Edge(expe.Current());
339 TopoDS_Vertex VF = sae.FirstVertex(E);
340 TopoDS_Vertex VL = sae.LastVertex(E);
341 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
343 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
345 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
347 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
353 // find vertexes from FS2 corresponded to VN12 and VN22
354 // and find edge from FS2 contains V12 and V22,
355 // this edge will be corresponded to edge E1
356 TopoDS_Vertex V12,V22;
357 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
358 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
360 TopExp_Explorer expe;
361 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
362 TopoDS_Edge E = TopoDS::Edge(expe.Current());
363 TopoDS_Vertex VF = sae.FirstVertex(E);
364 TopoDS_Vertex VL = sae.LastVertex(E);
365 gp_Pnt PF = BRep_Tool::Pnt(VF);
366 gp_Pnt PL = BRep_Tool::Pnt(VL);
367 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
373 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
384 // find other pairs for vertexes and edges
385 // creating map of vertex edges for both faces
386 return FillForOtherEdges(FS1,E1,V21,FF);
391 //=======================================================================
392 //function : FillCorrespondingEdges
393 //purpose : auxiliary for CreatePipeShellsWithoutPath()
394 //=======================================================================
395 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
396 const TopoDS_Shape& FS2,
397 const TopoDS_Vertex& aLoc1,
398 const TopoDS_Vertex& aLoc2,
399 TopTools_IndexedDataMapOfShapeShape& FF)
401 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
402 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
405 ShapeAnalysis_Edge sae;
406 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
407 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
408 TopTools_MapOfShape Vs1,Vs2;
410 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
413 TopExp_Explorer exp1;
414 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
415 E1 = TopoDS::Edge(exp1.Current());
416 TopoDS_Vertex V1 = sae.FirstVertex(E1);
417 TopoDS_Vertex V2 = sae.LastVertex(E1);
418 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
419 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
420 if (P1.Distance(Ptmp1)<tol) {
424 if (P1.Distance(Ptmp2)<tol) {
431 TopoDS_Vertex VE21,VE22;
433 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
434 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
435 TopoDS_Vertex V1 = sae.FirstVertex(E);
436 TopoDS_Vertex V2 = sae.LastVertex(E);
437 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
438 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
439 if (P2.Distance(Ptmp1)<tol) {
451 if (P2.Distance(Ptmp2)<tol) {
465 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
466 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
467 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
468 gp_Vec aDir1(PV21,PE21);
469 gp_Vec aDir2(PV21,PE22);
470 double ang1 = aDir.Angle(aDir1);
471 double ang2 = aDir.Angle(aDir2);
472 if (fabs(ang1)<fabs(ang2)) {
485 // find other pairs for vertexes and edges
486 return FillForOtherEdges(FS1,E1,V21,FF);
489 //=======================================================================
490 //function : FindNextPairOfFaces
491 //purpose : auxiliary for CreatePipeForShellSections()
492 //=======================================================================
493 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
494 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
495 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
496 TopTools_IndexedDataMapOfShapeShape& FF,
499 TopExp_Explorer anExp;
500 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
501 TopoDS_Shape E1 = anExp.Current();
502 if (!FF.Contains(E1)) {
504 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
506 if (!FF.Contains(E1)) MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
507 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
508 TopExp_Explorer anExpV;
509 anExpV.Init(E1, TopAbs_VERTEX);
510 TopoDS_Shape V1 = anExpV.Current();
511 if (!FF.Contains(V1)) {
513 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
516 if (!aMapEdgeFaces1.Contains(E1)) MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
517 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
518 if (aList1.Extent()<2)
520 TopTools_ListIteratorOfListOfShape anIter(aList1);
521 if (anIter.Value().IsEqual(aCurFace)) {
524 TopoDS_Shape F1other = anIter.Value();
525 if (FF.Contains(F1other))
528 if (!FF.Contains(aCurFace)) MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
529 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
530 if (!aMapEdgeFaces2.Contains(E2)) MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
531 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
532 if (aList2.Extent()<2) {
534 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
536 TopTools_ListIteratorOfListOfShape anIter2(aList2);
537 if (anIter2.Value().IsEqual(F2)) {
540 TopoDS_Shape F2other = anIter2.Value();
541 FF.Add(F1other,F2other);
543 // add pairs of edges to FF
544 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
547 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not map other edges");
550 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
554 //=======================================================================
555 //function : FindFirstPairFaces
556 //purpose : auxiliary for Execute()
557 //=======================================================================
558 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
559 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
560 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
562 // check if vertexes are sub-shapes of sections
563 gp_Pnt P1 = BRep_Tool::Pnt(V1);
564 gp_Pnt P2 = BRep_Tool::Pnt(V2);
565 TopoDS_Vertex V1new,V2new;
567 double mindist = 1.e10;
568 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
569 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
570 gp_Pnt P = BRep_Tool::Pnt(V);
571 double dist = P1.Distance(P);
578 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
579 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
580 gp_Pnt P = BRep_Tool::Pnt(V);
581 double dist = P2.Distance(P);
588 // replace vertexes if it is needed
589 if (!V1.IsSame(V1new)) {
591 P1 = BRep_Tool::Pnt(V1);
592 MESSAGE (" replace V1");
595 MESSAGE (" not replace V1");
596 if (!V2.IsSame(V2new)) {
598 P2 = BRep_Tool::Pnt(V2);
599 MESSAGE (" replace V2");
602 MESSAGE (" not replace V2");
604 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
605 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
606 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
607 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
609 if (!aMapVertFaces1.Contains(V1))
610 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
611 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
612 TopTools_ListIteratorOfListOfShape anIter1(aList1);
613 FS1 = anIter1.Value();
615 double x1=0., y1=0., z1=0.;
617 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
618 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
619 gp_Pnt P = BRep_Tool::Pnt(V);
625 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
627 TColgp_SequenceOfPnt Ps;
628 TopTools_SequenceOfShape Fs;
629 if (!aMapVertFaces2.Contains(V2))
630 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
631 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
632 TopTools_ListIteratorOfListOfShape anIter2(aList2);
633 for (; anIter2.More(); anIter2.Next()) {
634 TopoDS_Shape F = anIter2.Value();
635 double x2=0., y2=0., z2=0.;
637 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
638 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
639 gp_Pnt P = BRep_Tool::Pnt(V);
645 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
652 double MinAng = M_PI;
654 for (; i<=Fs.Length(); i++) {
655 gp_Vec tmpDir(PM1,Ps(i));
656 double ang = fabs(aDir.Angle(tmpDir));
665 //=======================================================================
666 //function : RemoveFaces
667 //purpose : This function returns theShapeFrom without faces of the shape
668 // theFacesToRm. It returns a shell if theShapeFrom is a solid or
669 // a compound otherwise. Auxiliary for CreatePipeWithDifferentSections
671 //=======================================================================
672 static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom,
673 const TopoDS_Shape &theFacesToRm)
675 TopTools_IndexedMapOfShape aMapFaces;
676 TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE);
677 BRep_Builder aBuilder;
678 TopoDS_Shape aResult;
680 if (theShapeFrom.ShapeType() == TopAbs_SOLID) {
682 aBuilder.MakeShell(TopoDS::Shell(aResult));
685 aBuilder.MakeCompound(TopoDS::Compound(aResult));
688 TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces);
690 for (; anExp.More(); anExp.Next()) {
691 const TopoDS_Shape &aFace = anExp.Current();
693 if (!aMapFaces.Contains(aFace)) {
694 aBuilder.Add(aResult, aFace);
701 //=======================================================================
702 //function : makeSolid
703 //purpose : auxiliary for CreatePipeWithDifferentSections
704 //=======================================================================
705 Standard_Boolean makeSolid(
706 BRepOffsetAPI_MakePipeShell aBuilder,
707 const TopoDS_Shape& aSh1,
708 const TopoDS_Shape& aSh2,
709 TopoDS_Shape& aShape)
711 Standard_Boolean isDone = Standard_True;
712 Standard_Integer nbPlanar = 0;
713 if (aSh1.ShapeType() == TopAbs_FACE && aSh2.ShapeType() == TopAbs_FACE)
715 Handle(Geom_Surface) aS = BRep_Tool::Surface(TopoDS::Face(aSh1));
716 if (aS->IsKind(STANDARD_TYPE(Geom_Plane))) {
719 else if (aS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
720 Handle(Geom_RectangularTrimmedSurface) aTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
721 if (aTS->BasisSurface()->IsKind(STANDARD_TYPE(Geom_Plane))) {
725 aS = BRep_Tool::Surface(TopoDS::Face(aSh2));
726 if (aS->IsKind(STANDARD_TYPE(Geom_Plane))) {
729 else if (aS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
730 Handle(Geom_RectangularTrimmedSurface) aTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
731 if (aTS->BasisSurface()->IsKind(STANDARD_TYPE(Geom_Plane))) {
737 TopoDS_Shape aPipe = aBuilder.Shape();
738 // make sewing for result
739 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
740 Standard_Real aTol = Precision::Confusion();
741 aSewing->SetTolerance(aTol);
742 aSewing->SetFaceMode(Standard_True);
743 aSewing->SetFloatingEdgesMode(Standard_False);
744 aSewing->SetNonManifoldMode(Standard_False);
745 TopExp_Explorer anExp;
746 for (anExp.Init(aPipe, TopAbs_FACE); anExp.More(); anExp.Next()) {
747 aSewing->Add(anExp.Current());
752 aShape = aSewing->SewedShape();
753 if (aShape.ShapeType() == TopAbs_SHELL) {
755 BRepBuilderAPI_MakeSolid aMkSolid;
756 aMkSolid.Add(TopoDS::Shell(aShape));
757 if (!aMkSolid.IsDone()) {
758 isDone = Standard_False;
761 TopoDS_Solid aSolid = aMkSolid.Solid();
762 BRepClass3d_SolidClassifier aSC(aSolid);
763 aSC.PerformInfinitePoint(Precision::Confusion());
764 if (aSC.State() == TopAbs_IN) {
765 aShape = aSolid.Reversed();
773 isDone = Standard_False;
777 isDone = Standard_False;
780 isDone = aBuilder.MakeSolid();
782 aShape = aBuilder.Shape();
788 //=======================================================================
789 //function : CreatePipeWithDifferentSections
791 //=======================================================================
792 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
793 (const TopoDS_Wire &theWirePath,
794 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
795 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
796 const Standard_Boolean theWithContact,
797 const Standard_Boolean theWithCorrect,
798 const Standard_Boolean IsBySteps,
799 Handle(TColStd_HArray1OfInteger) *theGroups)
803 TopoDS_Wire aWirePath = theWirePath;
805 Standard_Integer nbBases = theHSeqBases->Length();
806 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
808 if (nbLocs && nbLocs != nbBases) {
809 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
812 TopTools_SequenceOfShape aSeqBases;
813 TopTools_SequenceOfShape aSeqLocs;
814 TopTools_SequenceOfShape aSeqFaces;
815 Standard_Boolean NeedCreateSolid = Standard_False;
817 Standard_Integer i = 1;
818 for (i = 1; i <= nbBases; i++) {
819 if (theHSeqBases->Value(i).IsNull())
822 // Make copy to prevent modifying of base object 0020766 : EDF 1320
823 TopoDS_Shape aShapeBase;
824 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
826 aShapeBase = Copy.Shape();
828 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
830 //if for section was specified face with a few wires then a few
831 // pipes were build and make solid
832 if (aTypeBase == TopAbs_SHELL) {
833 // create wire as boundary contour if shell is no closed
834 // get free boundary shapes
835 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
836 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
837 TopExp_Explorer anExp;
839 Standard_Integer NbWires = 0;
840 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
842 aWire = anExp.Current();
846 Standard_ConstructionError::Raise("Bad shell is used as section ");
848 NeedCreateSolid = Standard_True;
849 aSeqFaces.Append(aShapeBase);
850 aSeqBases.Append(aWire);
852 else if (aTypeBase == TopAbs_FACE) {
853 NeedCreateSolid = Standard_True;
854 //for case one path should be used other type function
855 aSeqFaces.Append(aShapeBase);
856 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
857 for (; aExpW.More(); aExpW.Next()) {
858 TopoDS_Shape aWireProf = aExpW.Current();
859 aSeqBases.Append(aWireProf);
862 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
863 aSeqBases.Append(aShapeBase);
865 else if (aTypeBase == TopAbs_EDGE) {
866 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
867 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
868 aSeqBases.Append(aWireProf);
871 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
872 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
874 aSeqLocs.Append(aShapeLoc);
878 nbLocs = aSeqLocs.Length();
881 TopTools_SequenceOfShape Edges;
883 // we have to check that each location shape is a vertex from
884 // path and update aSeqLocs if it is needed (and possible)
885 TColgp_SequenceOfPnt PLocs;
886 for (i=1; i<=nbLocs; i++) {
887 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
888 PLocs.Append(BRep_Tool::Pnt(V));
890 //TopTools_SequenceOfShape Edges;
891 TopExp_Explorer anExp;
892 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
893 Edges.Append(anExp.Current());
895 int nbEdges = Edges.Length();
896 ShapeAnalysis_Edge sae;
897 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
898 double tol = BRep_Tool::Tolerance(edge);
899 TopoDS_Vertex VF = sae.FirstVertex(edge);
900 gp_Pnt PF = BRep_Tool::Pnt(VF);
901 if (PF.Distance(PLocs.First()) > tol) {
902 Standard_ConstructionError::Raise
903 ("First location shapes is not coincided with first vertex of aWirePath");
905 aSeqLocs.ChangeValue(1) = VF;
906 edge = TopoDS::Edge(Edges.Last());
907 tol = BRep_Tool::Tolerance(edge);
908 TopoDS_Vertex VL = sae.LastVertex(edge);
909 gp_Pnt PL = BRep_Tool::Pnt(VL);
910 if (PL.Distance(PLocs.Last()) > tol) {
911 Standard_ConstructionError::Raise
912 ("Last location shapes is not coincided with last vertex of aWirePath");
914 aSeqLocs.ChangeValue(nbLocs) = VL;
916 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
917 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
918 tol = BRep_Tool::Tolerance(edge);
919 TopoDS_Vertex V1 = sae.FirstVertex(E);
920 TopoDS_Vertex V2 = sae.LastVertex(E);
921 gp_Pnt P1 = BRep_Tool::Pnt(V1);
922 gp_Pnt P2 = BRep_Tool::Pnt(V2);
923 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
924 aSeqLocs.ChangeValue(jcurr) = V2;
928 // find distance between E and aLocs(jcurr)
930 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
931 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
932 if (PPCurve.NbPoints()>0 &&
933 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
934 double param = PPCurve.Parameter(1);
937 // split current edge
938 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
939 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
944 if (Pfp.Distance(P1)<tol) {
945 B.MakeEdge(E1,tc1,tol);
947 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
948 B.Add(E1,TopoDS::Vertex(tmpV));
949 B.MakeEdge(E2,tc2,tol);
950 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
951 B.Add(E2,TopoDS::Vertex(tmpV));
955 B.MakeEdge(E1,tc2,tol);
956 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
957 B.Add(E1,TopoDS::Vertex(tmpV));
960 B.MakeEdge(E2,tc1,tol);
962 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
963 B.Add(E2,TopoDS::Vertex(tmpV));
968 Edges.InsertAfter(i-1,E1);
969 Edges.InsertAfter(i,E2);
973 if (nbEdges<Edges.Length()) {
974 // one of edges was split => we have to update WirePath
978 for (i=1; i<=Edges.Length(); i++) {
979 B.Add(W,TopoDS::Edge(Edges.Value(i)));
985 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
988 // Fill SplitEdgeNums and SplitLocNums with intermediate location indices
989 // and corresponding edge indices.
990 Standard_Integer i = 1;
995 for (j = 2; j < aSeqLocs.Length(); j++) {
996 SplitLocNums.Append(j);
997 aVert = TopoDS::Vertex(aSeqLocs.Value(j));
998 aP = BRep_Tool::Pnt(aVert);
1000 while (i < Edges.Length()) {
1003 TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i));
1004 Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
1005 Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp);
1008 aC->D0(aLp, aPLast);
1011 if (aP.Distance(aPLast) < aTol) {
1012 SplitEdgeNums.Append(i - 1);
1018 // check curvature of wire for condition that
1019 // max summary angle between directions along
1020 // wire path must be < 4*PI. If not - split wire
1021 // and seguences of shapes, perform pipe for each
1022 // and make sewing after that
1027 if ( Edges.Length() > 0 ) {
1028 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
1031 SumAng = fabs(Vec1.Angle(Vec2));
1036 for (i=2; i<=Edges.Length(); i++) {
1037 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
1038 double tol = BRep_Tool::Tolerance(edge);
1039 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1041 double ang = fabs(Vec1.Angle(Vec2));
1043 if (SumAng>4*M_PI) {
1045 SplitEdgeNums.Append(i-1);
1047 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
1048 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
1049 gp_Pnt P = BRep_Tool::Pnt(aVert);
1050 if (P1.Distance(P) < tol) {
1051 SplitLocNums.Append(j);
1062 bool isCreateGroups = (theGroups != NULL);
1064 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
1065 TopTools_SequenceOfShape aSeqRes;
1066 TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
1067 Standard_Integer iGrp;
1068 int nn, num1 = 1, num2 = 1;
1069 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
1070 // create wirepath and sequences of shapes
1074 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
1075 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1077 num1 = SplitEdgeNums.Value(nn) + 1;
1078 TopTools_SequenceOfShape aTmpSeqBases;
1079 TopTools_SequenceOfShape aTmpSeqLocs;
1080 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
1081 aTmpSeqBases.Append(aSeqBases.Value(i));
1082 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1084 num2 = SplitLocNums.Value(nn);
1086 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1087 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1088 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1089 aBuilder.SetDiscreteMode();
1090 Standard_Integer nbShapes = aTmpSeqBases.Length();
1091 for (i=1; i<=nbShapes; i++) {
1092 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1093 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1094 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1096 if (!aBuilder.IsReady()) {
1097 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1100 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1102 if (isDone && NeedCreateSolid && nn == 1) {
1103 // Make solid for the first step.
1104 isDone = aBuilder.MakeSolid();
1108 Standard_ConstructionError::Raise("Pipe construction failure");
1111 TopoDS_Shape resShape = aBuilder.Shape();
1113 if (NeedCreateSolid && nn == 1) {
1114 // Remove top lid from the result.
1115 resShape = RemoveFaces(resShape, aBuilder.LastShape());
1118 aSeqRes.Append(resShape);
1121 if (isCreateGroups) {
1123 TopTools_SequenceOfShape aGroups[5];
1125 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1126 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1127 Standard_ConstructionError::Raise("Generate groups failure");
1130 // Get shapes from all groups.
1131 for (iGrp = 0; iGrp < 5; ++iGrp) {
1132 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1136 // create wirepath and sequences of shapes for last part
1140 for (i=num1; i<=Edges.Length(); i++) {
1141 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1143 TopTools_SequenceOfShape aTmpSeqBases;
1144 TopTools_SequenceOfShape aTmpSeqLocs;
1145 for (i=num2; i<=aSeqLocs.Length(); i++) {
1146 aTmpSeqBases.Append(aSeqBases.Value(i));
1147 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1149 // make pipe for last part
1150 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1151 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1152 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1153 aBuilder.SetDiscreteMode();
1154 Standard_Integer nbShapes = aTmpSeqBases.Length();
1155 for (i=1; i<=nbShapes; i++) {
1156 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1157 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1158 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1160 if (!aBuilder.IsReady()) {
1161 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1164 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1166 if (isDone && NeedCreateSolid) {
1167 isDone = aBuilder.MakeSolid();
1171 Standard_ConstructionError::Raise("Pipe construction failure");
1174 TopoDS_Shape resShape = aBuilder.Shape();
1176 if (NeedCreateSolid) {
1177 // Remove bottom lid from the result.
1178 resShape = RemoveFaces(resShape, aBuilder.FirstShape());
1181 aSeqRes.Append(resShape);
1184 if (isCreateGroups) {
1186 TopTools_SequenceOfShape aGroups[5];
1188 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1189 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1190 Standard_ConstructionError::Raise("Generate groups failure");
1193 // Get shapes from all groups.
1194 for (iGrp = 0; iGrp < 5; ++iGrp) {
1195 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1199 // make sewing for result
1200 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1201 aSewing->SetTolerance(Precision::Confusion());
1202 aSewing->SetFaceMode(Standard_True);
1203 aSewing->SetFloatingEdgesMode(Standard_False);
1204 aSewing->SetNonManifoldMode(Standard_False);
1205 for (i=1; i<=aSeqRes.Length(); i++) {
1206 aSewing->Add(aSeqRes.Value(i));
1209 aShape = aSewing->SewedShape();
1211 if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) {
1213 BRepBuilderAPI_MakeSolid aMkSolid;
1215 aMkSolid.Add(TopoDS::Shell(aShape));
1217 if (!aMkSolid.IsDone()) {
1218 Standard_ConstructionError::Raise("Can't create solid pipe");
1221 TopoDS_Solid aSolid = aMkSolid.Solid();
1222 BRepClass3d_SolidClassifier aSC(aSolid);
1224 aSC.PerformInfinitePoint(Precision::Confusion());
1226 if (aSC.State() == TopAbs_IN) {
1227 aShape = aSolid.Reversed();
1233 if (isCreateGroups) {
1234 // Replase Group shapes by modified ones.
1235 TopTools_SequenceOfShape aSeqGroups[5];
1238 for (iGrp = 0; iGrp < 5; ++iGrp) {
1240 for (i = 1; i <= aSeqRes.Length(); ++i) {
1241 if (iGrp == GROUP_DOWN && i > 1) {
1242 // For DOWN group we use only the first pipe.
1246 if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
1247 // For UP group we use only the last pipe.
1251 const TopTools_SequenceOfShape &aShapes =
1252 aMapResGroups[iGrp].Find(aSeqRes.Value(i));
1255 // For each sub-shape of pipe
1256 for (j = 1; j <= aShapes.Length(); ++j) {
1257 const TopoDS_Shape &aGrpShape = aShapes.Value(j);
1259 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1260 // Use the shape modified by sewing.
1261 const TopoDS_Shape &aModifGrpShape =
1262 aSewing->ModifiedSubShape(aGrpShape);
1264 aSeqGroups[iGrp].Append(aModifGrpShape);
1266 // Use the shape as it is.
1267 aSeqGroups[iGrp].Append(aGrpShape);
1274 TopTools_IndexedMapOfShape anIndices;
1276 TopExp::MapShapes(aShape, anIndices);
1278 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1279 Standard_ConstructionError::Raise("Generate groups failure");
1284 // old implementation without splitting
1286 // Generally, we should better use BRepOffsetAPI_ThruSections algorithm if
1287 // 1) the path is a polyline, and
1288 // 2) all break points of the path have correspondent sections
1289 bool doThruSections = false;
1290 if (!theWithContact && !theWithCorrect && theGroups == NULL &&
1291 nbBases == Edges.Length() + 1) {
1292 doThruSections = true;
1293 // check if all edges are lines
1294 Standard_Real aFP, aLP;
1295 for (int ie = 1; ie <= Edges.Length() && doThruSections; ie++) {
1296 TopoDS_Edge anE = TopoDS::Edge(Edges.Value(ie));
1297 Handle(Geom_Curve) aC = BRep_Tool::Curve(anE, aFP, aLP);
1299 while(aC->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
1300 Handle(Geom_TrimmedCurve) aTc = Handle(Geom_TrimmedCurve)::DownCast(aC);
1301 aC = aTc->BasisCurve();
1303 if (!aC->IsKind(STANDARD_TYPE(Geom_Line)))
1304 doThruSections = false;
1309 if (doThruSections) {
1310 BRepOffsetAPI_ThruSections aBuilder (NeedCreateSolid, Standard_True, Precision::Confusion()*10.0);
1311 aBuilder.CheckCompatibility(Standard_False);
1313 for (int ibase = 1; ibase <= nbBases; ibase++) {
1314 TopoDS_Shape aBase = aSeqBases.Value(ibase);
1315 aBuilder.AddWire(TopoDS::Wire(aBase));
1319 aShape = aBuilder.Shape();
1322 // old implementation without splitting
1323 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1324 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1325 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1326 aBuilder.SetDiscreteMode();
1328 Standard_Integer nbShapes = aSeqBases.Length();
1329 Standard_Integer step = nbShapes/nbBases;
1331 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1332 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1334 Standard_Integer ind =0;
1335 Standard_Real aTolConf = Precision::Confusion();
1336 Standard_Real aTolAng = Precision::Angular();
1338 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1339 TopTools_SequenceOfShape usedBases;
1340 Standard_Integer j = 1;
1341 for (; j <= nbBases; j++) {
1342 ind = i + (j-1)*step;
1343 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1344 usedBases.Append(aWireProf);
1346 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1347 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1348 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1351 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1353 if (!aBuilder.IsReady()) {
1354 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1357 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1359 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1362 if (NeedCreateSolid) {
1363 TopoDS_Shape aSh1 = aSeqFaces.Value(1);
1364 TopoDS_Shape aSh2 = aSeqFaces.Value(aSeqFaces.Length());
1365 isDone = makeSolid(aBuilder, aSh1, aSh2, aShape);
1368 aShape = aBuilder.Shape();
1373 Standard_ConstructionError::Raise("Pipe construction failure");
1376 if (isCreateGroups) {
1378 TopTools_SequenceOfShape aSeqGroups[5];
1380 TopoDS_Shape aProfile = usedBases.Value(1);
1381 if (!DoGroups1(aProfile, aBuilder, aSeqGroups)) {
1382 Standard_ConstructionError::Raise("Generate groups failure");
1386 //Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1387 TopTools_IndexedMapOfShape anIndices;
1388 const TopoDS_Shape aResult = aBuilder.Shape();
1390 TopExp::MapShapes(aResult, anIndices);
1392 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1393 Standard_ConstructionError::Raise("Generate groups failure");
1396 aSeqFaces.Append(aShape);
1397 for (j = 1; j <=usedBases.Length(); j++)
1398 aBuilder.Delete(usedBases.Value(j));
1406 //=======================================================================
1407 //function : CreatePipeForShellSections
1408 //purpose : auxiliary for Execute()
1409 //=======================================================================
1410 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1411 GEOMImpl_IPipe* aCI)
1416 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1417 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1418 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1419 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1420 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1421 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1422 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1424 Standard_Integer nbBases = aBasesObjs->Length(),
1425 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1426 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1428 if (nbLocs != nbBases) {
1429 if (aCI) delete aCI;
1430 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1432 if (nbSubBases && nbSubBases != nbBases) {
1433 if (aCI) delete aCI;
1434 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1437 TopTools_SequenceOfShape VLocs;
1438 for (i=1; i<=nbBases; i++) {
1439 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1440 if (anItemLoc.IsNull())
1442 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1443 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1444 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1446 VLocs.Append(aShapeLoc);
1448 nbLocs = VLocs.Length();
1449 if (nbLocs != nbBases) {
1450 if (aCI) delete aCI;
1451 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1453 // split wire path by location points
1454 TColgp_SequenceOfPnt PLocs;
1455 for (i=1; i<=nbLocs; i++) {
1456 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1457 PLocs.Append(BRep_Tool::Pnt(V));
1460 TopTools_SequenceOfShape Edges;
1461 TopTools_SequenceOfShape Wires;
1462 ShapeAnalysis_Edge sae;
1465 TopExp_Explorer anExp;
1466 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1467 Edges.Append(anExp.Current());
1469 Standard_Integer Num1 = 0;
1470 Standard_Integer Num2 = 0;
1471 for (i=1; i<=Edges.Length(); i++) {
1472 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1473 double tol = BRep_Tool::Tolerance(E);
1474 TopoDS_Vertex V1 = sae.FirstVertex(E);
1475 TopoDS_Vertex V2 = sae.LastVertex(E);
1476 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1477 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1478 if (P1.Distance(PLocs.First()) < tol) {
1481 if (P2.Distance(PLocs.Last()) < tol) {
1485 if (Num1>0 && Num2>0) {
1488 for (i=Num1; i<=Num2; i++) {
1489 B.Add(W,Edges.Value(i));
1494 Wires.Append(aWirePath);
1498 TopExp_Explorer anExp;
1499 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1500 Edges.Append(anExp.Current());
1502 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1503 double tol = BRep_Tool::Tolerance(edge);
1504 TopoDS_Vertex VF = sae.FirstVertex(edge);
1505 gp_Pnt PF = BRep_Tool::Pnt(VF);
1506 if (PF.Distance(PLocs.First()) > tol) {
1507 if (aCI) delete aCI;
1508 Standard_ConstructionError::Raise
1509 ("First location shapes is not coincided with first vertex of aWirePath");
1511 VLocs.ChangeValue(1) = VF;
1512 edge = TopoDS::Edge(Edges.Last());
1513 tol = BRep_Tool::Tolerance(edge);
1514 TopoDS_Vertex VL = sae.LastVertex(edge);
1515 gp_Pnt PL = BRep_Tool::Pnt(VL);
1516 if (PL.Distance(PLocs.Last()) > tol) {
1517 if (aCI) delete aCI;
1518 Standard_ConstructionError::Raise
1519 ("Last location shapes is not coincided with last vertex of aWirePath");
1521 VLocs.ChangeValue(nbLocs) = VL;
1523 TopTools_SequenceOfShape tmpEdges;
1524 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1525 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1526 tol = BRep_Tool::Tolerance(E);
1527 TopoDS_Vertex V1 = sae.FirstVertex(E);
1528 TopoDS_Vertex V2 = sae.LastVertex(E);
1529 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1530 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1531 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1532 // make wire from current edge and add created
1536 for (j=1; j<=tmpEdges.Length(); j++)
1537 B.Add(W,tmpEdges.Value(j));
1540 VLocs.ChangeValue(jcurr) = V2;
1545 // find distance between E and aLocs(jcurr)
1547 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1548 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1549 if (PPCurve.NbPoints()>0 &&
1550 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1551 double param = PPCurve.Parameter(1);
1554 // split current edge
1555 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1556 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1560 if (Pfp.Distance(P1)<tol) {
1561 B.MakeEdge(E1,tc1,tol);
1563 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1564 B.Add(E1,TopoDS::Vertex(tmpV));
1565 tmpEdges.Append(E1);
1566 B.MakeEdge(E2,tc2,tol);
1567 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1568 B.Add(E2,TopoDS::Vertex(tmpV));
1572 B.MakeEdge(E1,tc2,tol);
1573 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1574 B.Add(E1,TopoDS::Vertex(tmpV));
1577 tmpEdges.Append(E1);
1578 B.MakeEdge(E2,tc1,tol);
1580 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1581 B.Add(E2,TopoDS::Vertex(tmpV));
1584 // create wire from tmpEdges
1587 for (j=1; j<=tmpEdges.Length(); j++)
1588 B.Add(W,tmpEdges.Value(j));
1593 Edges.InsertAfter(i-1,E1);
1594 Edges.InsertAfter(i,E2);
1601 // create wire from other edges
1604 for (; i<=Edges.Length(); i++)
1605 B.Add(W,Edges.Value(i));
1609 if (Wires.Length() != nbLocs-1) {
1610 if (aCI) delete aCI;
1611 Standard_ConstructionError::Raise
1612 ("One of location shapes is not lied on the path");
1615 TopTools_SequenceOfShape aGroups[5];
1616 TopoDS_Compound aComp;
1617 B.MakeCompound(aComp);
1618 for (i = 1; i < nbBases; i++) {
1619 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1621 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1622 if (anItem1.IsNull())
1624 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1625 if (aRefBase1.IsNull())
1627 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1628 if (aShBase1.IsNull())
1630 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1632 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1633 if (anItem2.IsNull())
1635 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1636 if (aRefBase2.IsNull())
1638 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1639 if (aShBase2.IsNull())
1641 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1643 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1644 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1646 if (aCI) delete aCI;
1647 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1650 bool CreateFewSolids = false;
1652 TopExp_Explorer anExp;
1653 Standard_Integer nbf1 = 0;
1654 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1657 Standard_Integer nbf2 = 0;
1658 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1662 CreateFewSolids = true;
1665 if (!CreateFewSolids) {
1666 // we can create only one solid
1667 TopoDS_Shape aWire1, aWire2;
1669 if (aType1==TopAbs_SHELL) {
1670 // create wire as boundary contour if shell is no closed
1671 // get free boundary shapes
1672 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1673 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1674 //TopExp_Explorer anExp;
1675 Standard_Integer NbWires = 0;
1676 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1678 aWire1 = anExp.Current();
1682 if (aCI) delete aCI;
1683 Standard_ConstructionError::Raise("Bad shell is used as section ");
1686 else { // aType1==TopAbs_FACE
1687 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1688 aWire1 = aExpW.Current();
1691 if (aType2==TopAbs_SHELL) {
1692 // create wire as boundary contour if shell is no closed
1693 // get free boundary shapes
1694 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1695 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1696 //TopExp_Explorer anExp;
1697 Standard_Integer NbWires = 0;
1698 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1700 aWire2 = anExp.Current();
1704 if (aCI) delete aCI;
1705 Standard_ConstructionError::Raise("Bad shell is used as section ");
1708 else { // aType2==TopAbs_FACE
1709 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1710 aWire2 = aExpW.Current();
1712 // make pipe using aWire1 and aWire2
1713 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1714 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1715 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1716 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1717 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1718 aBuilder.SetDiscreteMode();
1719 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1720 aWithContact, aWithCorrect);
1721 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1722 aWithContact, aWithCorrect);
1723 if (!aBuilder.IsReady()) {
1724 if (aCI) delete aCI;
1725 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1728 BuildPipeShell(aBuilder);
1730 TopoDS_Shape aShape = aBuilder.Shape();
1731 TopTools_SequenceOfShape aLocalGroups[5];
1734 if (isGenerateGroups) {
1736 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
1737 if (aCI) delete aCI;
1738 Standard_ConstructionError::Raise("Generate groups failure");
1741 // Clear the groups Down and Up.
1742 aLocalGroups[GROUP_DOWN].Clear();
1743 aLocalGroups[GROUP_UP].Clear();
1746 TopoDS_Shell aShell;
1747 B.MakeShell(aShell);
1748 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1749 B.Add(aShell,anExp.Current());
1751 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1752 B.Add(aShell,anExp.Current());
1754 if (isGenerateGroups && i == 1) {
1755 aLocalGroups[GROUP_DOWN].Append(anExp.Current());
1758 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1759 B.Add(aShell,anExp.Current());
1761 if (isGenerateGroups && i == nbBases - 1) {
1762 aLocalGroups[GROUP_UP].Append(anExp.Current());
1765 // make sewing for this shell
1766 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1767 aSewing->SetTolerance(Precision::Confusion());
1768 aSewing->SetFaceMode(Standard_True);
1769 aSewing->SetFloatingEdgesMode(Standard_False);
1770 aSewing->SetNonManifoldMode(Standard_False);
1771 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1772 aSewing->Add(anExp.Current());
1775 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1776 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1777 aShell = TopoDS::Shell(aSewShape);
1778 GProp_GProps aSystem;
1779 BRepGProp::VolumeProperties(aShell, aSystem);
1780 if (aSystem.Mass()<0) {
1783 if (BRep_Tool::IsClosed(aShell)) {
1784 TopoDS_Solid aSolid;
1785 B.MakeSolid(aSolid);
1786 B.Add(aSolid,aShell);
1787 B.Add(aComp,aSolid);
1790 B.Add(aComp,aShell);
1794 B.Add(aComp,aShell);
1797 if (isGenerateGroups) {
1798 Standard_Integer iGrp;
1800 for (iGrp = 0; iGrp < 5; ++iGrp) {
1803 // For each sub-shape of pipe
1804 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1805 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1807 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1808 // Use the shape modified by sewing.
1809 const TopoDS_Shape &aModifGrpShape =
1810 aSewing->ModifiedSubShape(aGrpShape);
1812 aGroups[iGrp].Append(aModifGrpShape);
1814 // Use the shape as it is.
1815 aGroups[iGrp].Append(aGrpShape);
1823 // main block - creation few solids (for each pair of faces)
1824 TopTools_MapOfShape aFaces1,aFaces2;
1825 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1826 aFaces1.Add(anExp.Current());
1828 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1829 aFaces2.Add(anExp.Current());
1831 // creating map of edge faces
1832 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1833 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1834 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1835 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1837 // construct map face->face
1838 TopTools_IndexedDataMapOfShapeShape FF;
1839 TopoDS_Shape FS1,FS2;
1840 if (nbSubBases==0) {
1841 // find edge the most distant from location point
1842 // (this edge is not shared by two faces)
1843 double maxdist = 0.;
1845 TopoDS_Vertex V11,V21;
1846 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1847 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1848 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1849 if (aList.Extent()>1)
1851 TopExp_Explorer expv;
1852 expv.Init(tmp, TopAbs_VERTEX);
1853 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1855 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1856 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1857 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1858 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1863 TopTools_ListIteratorOfListOfShape anIter(aList);
1864 FS1 = anIter.Value();
1868 // main direction for comparing
1869 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1870 // find corresponding edge from next section
1871 double minang = M_PI;
1872 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1873 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1875 TopoDS_Vertex V12,V22;
1876 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1877 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1878 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1879 if (aList.Extent()>1)
1881 TopExp_Explorer expv;
1882 expv.Init(tmp, TopAbs_VERTEX);
1883 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1885 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1886 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1887 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1888 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1889 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1890 TopoDS_Vertex V1,V2;
1893 V1 = V2tmp; P1 = P2tmp;
1894 V2 = V1tmp; P2 = P1tmp;
1897 V1 = V1tmp; P1 = P1tmp;
1898 V2 = V2tmp; P2 = P2tmp;
1900 gp_Vec Vec1(P11,P1);
1901 gp_Vec Vec2(P21,P2);
1902 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1907 TopTools_ListIteratorOfListOfShape anIter(aList);
1908 FS2 = anIter.Value();
1912 // put all pairs to map FF
1918 // add pairs of edges to FF
1919 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1921 if (aCI) delete aCI;
1922 Standard_ConstructionError::Raise("FindForOtherEdges: Can not map other edges");
1928 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1929 if (anItem.IsNull()) {
1930 if (aCI) delete aCI;
1931 Standard_ConstructionError::Raise("Invalid subbase shape");
1933 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1934 if (aRefBase.IsNull()) {
1935 if (aCI) delete aCI;
1936 Standard_ConstructionError::Raise("Invalid subbase shape");
1938 TopoDS_Shape aSh = aRefBase->GetValue();
1940 if (aCI) delete aCI;
1941 Standard_ConstructionError::Raise("Invalid subbase shape");
1943 if (aSh.ShapeType()!=TopAbs_FACE) {
1944 if (aCI) delete aCI;
1945 Standard_ConstructionError::Raise("Invalid subbase shape");
1950 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1951 if (anItem.IsNull()) {
1952 if (aCI) delete aCI;
1953 Standard_ConstructionError::Raise("Invalid subbase shape");
1955 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1956 if (aRefBase.IsNull()) {
1957 if (aCI) delete aCI;
1958 Standard_ConstructionError::Raise("Invalid subbase shape");
1960 TopoDS_Shape aSh = aRefBase->GetValue();
1962 if (aCI) delete aCI;
1963 Standard_ConstructionError::Raise("Invalid subbase shape");
1965 if (aSh.ShapeType()!=TopAbs_FACE) {
1966 if (aCI) delete aCI;
1967 Standard_ConstructionError::Raise("Invalid subbase shape");
1972 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1973 if (aCI) delete aCI;
1974 Standard_ConstructionError::Raise("Invalid subbase shape");
1979 // add pairs of edges to FF
1980 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1981 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1983 if (aCI) delete aCI;
1984 Standard_ConstructionError::Raise("Can not create correct pipe");
1988 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1990 // make pipe for each pair of faces
1991 for (j=1; j<=FF.Extent(); j++) {
1992 TopoDS_Shape F1 = FF.FindKey(j);
1993 if (F1.ShapeType() != TopAbs_FACE)
1995 TopoDS_Shape F2 = FF.FindFromIndex(j);
1996 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1997 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1998 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1999 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
2000 // make pipe using aWire1 and aWire2
2001 if (!aWire1.IsNull() && !aWire2.IsNull()) {
2002 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
2003 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
2004 if (theBestMode == GeomFill_IsDiscreteTrihedron)
2005 aBuilder.SetDiscreteMode();
2006 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
2007 aWithContact, aWithCorrect);
2008 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
2009 aWithContact, aWithCorrect);
2010 if (!aBuilder.IsReady()) {
2011 if (aCI) delete aCI;
2012 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
2015 BuildPipeShell(aBuilder);
2017 TopoDS_Shape aShape = aBuilder.Shape();
2018 TopTools_SequenceOfShape aLocalGroups[5];
2021 if (isGenerateGroups) {
2023 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
2024 if (aCI) delete aCI;
2025 Standard_ConstructionError::Raise("Generate groups failure");
2028 // Clear the groups Down and Up.
2029 aLocalGroups[GROUP_DOWN].Clear();
2030 aLocalGroups[GROUP_UP].Clear();
2033 aLocalGroups[GROUP_DOWN].Append(F1);
2036 if (i == nbBases - 1) {
2037 aLocalGroups[GROUP_UP].Append(F2);
2041 TopoDS_Shell aShell;
2042 B.MakeShell(aShell);
2043 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
2044 B.Add(aShell,anExp.Current());
2049 // make sewing for this shell
2050 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2051 aSewing->SetTolerance(Precision::Confusion());
2052 aSewing->SetFaceMode(Standard_True);
2053 aSewing->SetFloatingEdgesMode(Standard_False);
2054 aSewing->SetNonManifoldMode(Standard_False);
2055 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2056 aSewing->Add(anExp.Current());
2059 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2060 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2061 aShell = TopoDS::Shell(aSewShape);
2062 GProp_GProps aSystem;
2063 BRepGProp::VolumeProperties(aShell, aSystem);
2064 if (aSystem.Mass() < 0) {
2067 if (BRep_Tool::IsClosed(aShell)) {
2068 TopoDS_Solid aSolid;
2069 B.MakeSolid(aSolid);
2070 B.Add(aSolid,aShell);
2071 B.Add(aComp,aSolid);
2074 B.Add(aComp,aShell);
2078 B.Add(aComp,aShell);
2081 if (isGenerateGroups) {
2082 // Replase Group shapes by modified ones.
2083 Standard_Integer iGrp;
2086 for (iGrp = 0; iGrp < 5; ++iGrp) {
2089 // For each sub-shape of pipe
2090 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2091 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2093 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2094 // Use the shape modified by sewing.
2095 const TopoDS_Shape &aModifGrpShape =
2096 aSewing->ModifiedSubShape(aGrpShape);
2098 aGroups[iGrp].Append(aModifGrpShape);
2100 // Use the shape as it is.
2101 aGroups[iGrp].Append(aGrpShape);
2111 if (isGenerateGroups) {
2113 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2114 TopTools_IndexedMapOfShape anIndices;
2116 TopExp::MapShapes(aComp, anIndices);
2118 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2119 if (aCI) delete aCI;
2120 Standard_ConstructionError::Raise("Generate groups failure");
2123 StoreGroups(aCI, aGroupIds);
2129 //=======================================================================
2130 //function : CreatePipeShellsWithoutPath
2131 //purpose : auxiliary for Execute()
2132 //=======================================================================
2133 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
2138 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
2140 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
2141 // vertex for recognition
2142 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
2143 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
2145 Standard_Integer nbBases = aBasesObjs->Length(),
2146 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
2148 if (nbv != nbBases) {
2149 if (aCI) delete aCI;
2150 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
2153 TopTools_SequenceOfShape aGroups[5];
2154 TopTools_SequenceOfShape SecVs,Bases;
2155 for (i=1; i<=nbBases; i++) {
2157 Handle(Standard_Transient) anItem = VObjs->Value(i);
2158 if (anItem.IsNull())
2160 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
2161 TopoDS_Shape V = aRef->GetValue();
2162 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
2166 anItem = aBasesObjs->Value(i);
2167 if (anItem.IsNull())
2169 aRef = Handle(GEOM_Function)::DownCast(anItem);
2170 TopoDS_Shape aSh = aRef->GetValue();
2175 nbv = SecVs.Length();
2176 nbBases = Bases.Length();
2177 if (nbv != nbBases) {
2178 if (aCI) delete aCI;
2179 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
2182 TopoDS_Compound aComp;
2183 B.MakeCompound(aComp);
2185 for (i = 1; i < nbBases; i++) {
2186 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
2187 TopoDS_Shape aShBase1 = Bases.Value(i);
2188 TopoDS_Shape aShBase2 = Bases.Value(i+1);
2189 TopExp_Explorer anExp;
2190 Standard_Integer nbf1 = 0;
2191 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2194 Standard_Integer nbf2 = 0;
2195 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2199 if (aCI) delete aCI;
2200 Standard_ConstructionError::Raise("Different number of faces in the sections");
2203 TopTools_MapOfShape aFaces1,aFaces2;
2204 TopTools_MapOfShape aBndEdges1;
2206 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2207 const TopoDS_Shape &aBaseFace1 = anExp.Current();
2209 if (aFaces1.Add(aBaseFace1)) {
2210 // Get boundary edges.
2211 TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
2213 for (; anExpE.More(); anExpE.Next()) {
2214 const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
2216 if (!aBndEdges1.Add(aBaseEdge1)) {
2217 aBndEdges1.Remove(aBaseEdge1);
2222 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2223 aFaces2.Add(anExp.Current());
2226 // creating map of edge faces
2227 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
2228 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
2229 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
2230 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
2232 // construct map face->face (and sub-shapes)
2233 TopTools_IndexedDataMapOfShapeShape FF;
2234 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
2235 TopoDS_Shape FS1, FS2;
2236 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
2237 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
2238 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
2241 MESSAGE (" first pair of corresponding faces is found");
2243 // add pairs of edges and vertexes to FF
2244 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
2246 if (aCI) delete aCI;
2247 Standard_ConstructionError::Raise("Can not create correct pipe");
2249 MESSAGE (" correspondences for sub-shapes of first pair of faces found");
2251 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2252 MESSAGE (" other correspondences found, make pipe for all pairs of faces");
2254 // make pipe for each pair of faces
2255 // auxiliary map vertex->edge for created pipe edges
2256 TopTools_IndexedDataMapOfShapeShape VPE;
2257 ShapeAnalysis_Edge sae;
2259 for (j=1; j<=FF.Extent(); j++) {
2260 TopoDS_Shape F1 = FF.FindKey(j);
2261 if (F1.ShapeType() != TopAbs_FACE)
2263 TopoDS_Shape F2 = FF.FindFromIndex(j);
2266 //if (nbff!=3) continue;
2268 MESSAGE (" make pipe for "<<nbff<<" face");
2270 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
2271 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2272 Handle(Geom_RectangularTrimmedSurface) RTS =
2273 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
2274 S1 = RTS->BasisSurface();
2276 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
2277 if (Pln1.IsNull()) {
2278 if (aCI) delete aCI;
2279 Standard_ConstructionError::Raise("Surface from face is not plane");
2281 gp_Vec aDir1(Pln1->Axis().Direction());
2283 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
2284 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2285 Handle(Geom_RectangularTrimmedSurface) RTS =
2286 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
2287 S2 = RTS->BasisSurface();
2289 Handle(Geom_Plane) Pln2 =
2290 Handle(Geom_Plane)::DownCast(S2);
2291 if (Pln2.IsNull()) {
2292 if (aCI) delete aCI;
2293 Standard_ConstructionError::Raise("Surface from face is not plane");
2295 gp_Vec aDir2(Pln2->Axis().Direction());
2297 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
2298 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
2300 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
2302 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
2305 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
2306 TopTools_SequenceOfShape aNewFs;
2307 TopTools_SequenceOfShape aLocalGroups[5];
2310 for (; anExpE.More(); anExpE.Next()) {
2311 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2313 if (!FF.Contains(E1))
2314 MESSAGE ("map FF not contains key E1");
2316 if (VPE.Contains(E1)) {
2317 aNewFs.Append(VPE.FindFromKey(E1));
2319 MESSAGE (" using existing face");
2324 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2325 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2326 TopoDS_Vertex V2 = sae.LastVertex(E1);
2327 if (!FF.Contains(V1))
2328 MESSAGE ("map FF not contains key V1");
2329 if (!FF.Contains(V2))
2330 MESSAGE ("map FF not contains key V2");
2331 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2332 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2333 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2334 if (Vtmp.IsSame(V4))
2336 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2337 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2338 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2339 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2342 Handle(Geom_BSplineCurve) C2;
2343 if (VPE.Contains(V2)) {
2344 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2346 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2349 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2350 HAP->SetValue(1,P2);
2351 HAP->SetValue(2,P3);
2352 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2353 anInt.Load(aDir1,aDir2);
2356 B.MakeEdge(E2,C2,1.e-7);
2357 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2358 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2363 Handle(Geom_BSplineCurve) C4;
2364 if (VPE.Contains(V1)) {
2365 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2367 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2370 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2371 HAP->SetValue(1,P1);
2372 HAP->SetValue(2,P4);
2373 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2374 anInt.Load(aDir1,aDir2);
2377 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2378 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2379 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2388 B.Add(W,E4.Reversed());
2393 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2394 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2395 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2397 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2398 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2399 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2401 Handle(Geom_BSplineCurve) CE1 =
2402 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2403 if (CE1->Degree()<3)
2404 CE1->IncreaseDegree(3);
2405 Handle(Geom_BSplineCurve) CE2 =
2406 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2407 if (CE2->Degree()<3)
2408 CE2->IncreaseDegree(3);
2409 Handle(Geom_BSplineCurve) CE3 =
2410 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2411 if (CE3->Degree()<3)
2412 CE3->IncreaseDegree(3);
2413 Handle(Geom_BSplineCurve) CE4 =
2414 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2415 if (CE4->Degree()<3)
2416 CE4->IncreaseDegree(3);
2418 Handle(Geom_Surface) BS;
2420 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2421 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2425 MESSAGE (" can not create BSplineSurface - create Bezier");
2427 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2428 double fp1,lp1,fp2,lp2;
2429 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2430 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2439 // get points from C1
2440 if (P1.Distance(P1C1)<1.e-6) {
2448 double step = (lp-fp)/(NbP-1);
2449 Points.SetValue(1,1,P1);
2451 for (n1=2; n1<NbP; n1++) {
2455 Points.SetValue(1,n1,P);
2457 Points.SetValue(1,NbP,P2);
2458 // get points from C3
2459 if (P4.Distance(P1C3)<1.e-6) {
2467 step = (lp-fp)/(NbP-1);
2468 Points.SetValue(NbP,1,P4);
2470 for (n1=2; n1<NbP; n1++) {
2474 Points.SetValue(NbP,n1,P);
2476 Points.SetValue(NbP,NbP,P3);
2477 // create isolines and get points from them
2478 for (n1=1; n1<=NbP; n1++) {
2479 gp_Pnt PI1 = Points.Value(1,n1);
2480 gp_Pnt PI2 = Points.Value(NbP,n1);
2481 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2482 HAP->SetValue(1,PI1);
2483 HAP->SetValue(2,PI2);
2484 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2485 anInt.Load(aDir1,aDir2);
2487 const Handle(Geom_BSplineCurve) iso = anInt.Curve();
2488 fp = iso->FirstParameter();
2489 lp = iso->LastParameter();
2490 step = (lp-fp)/(NbP-1);
2492 TopoDS_Compound VComp;
2493 B.MakeCompound(VComp);
2494 for (n2=2; n2<NbP; n2++) {
2498 Points.SetValue(n2,n1,P);
2501 // create surface and face
2502 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2503 BS = new Geom_BezierSurface(Points);
2506 BRepBuilderAPI_MakeFace BB(BS,W);
2507 TopoDS_Face NewF = BB.Face();
2508 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2510 sff->FixOrientation();
2511 TopoDS_Face FixedFace = sff->Face();
2512 aNewFs.Append(FixedFace);
2513 VPE.Add(E1,FixedFace);
2515 if (isGenerateGroups) {
2516 if (aBndEdges1.Contains(E1)) {
2517 // This is a boundary face.
2518 aLocalGroups[GROUP_OTHER].Append(FixedFace);
2523 TopoDS_Shell aShell;
2524 B.MakeShell(aShell);
2525 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2526 B.Add(aShell,aNewFs(nf));
2532 if (isGenerateGroups && i == 1) {
2533 aLocalGroups[GROUP_DOWN].Append(F1);
2536 if (isGenerateGroups && i == nbBases - 1) {
2537 aLocalGroups[GROUP_UP].Append(F2);
2540 // make sewing for this shell
2541 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2542 aSewing->SetTolerance(Precision::Confusion());
2543 aSewing->SetFaceMode(Standard_True);
2544 aSewing->SetFloatingEdgesMode(Standard_False);
2545 aSewing->SetNonManifoldMode(Standard_False);
2546 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2547 aSewing->Add(anExp.Current());
2550 MESSAGE (" shell for face "<<nbff<<" is created");
2551 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2552 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2553 aShell = TopoDS::Shell(aSewShape);
2554 GProp_GProps aSystem;
2555 BRepGProp::VolumeProperties(aShell, aSystem);
2556 if (aSystem.Mass() < 0) {
2559 if (BRep_Tool::IsClosed(aShell)) {
2560 TopoDS_Solid aSolid;
2561 B.MakeSolid(aSolid);
2562 B.Add(aSolid,aShell);
2563 B.Add(aComp,aSolid);
2564 MESSAGE (" solid for face "<<nbff<<" is created");
2567 B.Add(aComp,aShell);
2568 MESSAGE (" solid for face "<<nbff<<" is not created");
2572 B.Add(aComp,aShell);
2573 MESSAGE (" solid for face "<<nbff<<" is not created");
2576 if (isGenerateGroups) {
2577 Standard_Integer iGrp;
2579 for (iGrp = 0; iGrp < 5; ++iGrp) {
2582 // For each sub-shape of pipe
2583 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2584 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2586 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2587 // Use the shape modified by sewing.
2588 const TopoDS_Shape &aModifGrpShape =
2589 aSewing->ModifiedSubShape(aGrpShape);
2591 aGroups[iGrp].Append(aModifGrpShape);
2593 // Use the shape as it is.
2594 aGroups[iGrp].Append(aGrpShape);
2602 if (isGenerateGroups) {
2604 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2605 TopTools_IndexedMapOfShape anIndices;
2607 TopExp::MapShapes(aComp, anIndices);
2609 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2610 if (aCI) delete aCI;
2611 Standard_ConstructionError::Raise("Generate groups failure");
2614 StoreGroups(aCI, aGroupIds);
2620 //=======================================================================
2621 //function : CreatePipeBiNormalAlongVector
2622 //purpose : auxiliary for Execute()
2623 //=======================================================================
2624 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2625 GEOMImpl_IPipe* aCI)
2627 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2629 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2630 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2631 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2632 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2634 if (aShapeBase.IsNull()) {
2635 if (aCIBN) delete aCIBN;
2636 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2639 // Make copy to prevent modifying of base object: 0021525
2640 BRepBuilderAPI_Copy Copy (aShapeBase);
2642 aShapeBase = Copy.Shape();
2645 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2648 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2649 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2651 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2654 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2655 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2656 aProf = wexp.Current();
2659 Standard_TypeMismatch::Raise
2660 ("MakePipe aborted : invalid type of base");
2662 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2663 PipeBuilder.Add(aProf);
2665 if (aShapeVec.IsNull()) {
2666 if (aCIBN) delete aCIBN;
2667 Standard_NullObject::Raise
2668 ("MakePipe aborted : null vector argument");
2670 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2671 Standard_TypeMismatch::Raise
2672 ("MakePipe aborted: invalid type of vector");
2673 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2674 TopoDS_Vertex V1, V2;
2675 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2676 if (V1.IsNull() || V2.IsNull())
2677 Standard_NullObject::Raise
2678 ("MakePipe aborted: vector is not defined");
2679 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2680 gp_Dir BiNormal(aVec);
2681 PipeBuilder.SetMode(BiNormal);
2683 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2685 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2686 PipeBuilder.MakeSolid();
2689 if (!CreateGroups1(aProf, PipeBuilder, aCIBN)) {
2690 if (aCIBN) delete aCIBN;
2691 Standard_ConstructionError::Raise("Generate groups failure");
2694 return PipeBuilder.Shape();
2697 //=======================================================================
2698 //function : FillGroups
2699 //purpose : auxiliary for DoGroups()
2700 //=======================================================================
2701 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
2702 const TopTools_IndexedMapOfShape &theIndices,
2703 Handle(TColStd_HArray1OfInteger) *theGroupIds)
2707 for (i = 0; i < 5; ++i) {
2708 if (!theGroups[i].IsEmpty()) {
2709 const Standard_Integer aNbShapes = theGroups[i].Length();
2712 theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
2714 for (j = 1; j <= aNbShapes; ++j) {
2715 const TopoDS_Shape &aShape = theGroups[i].Value(j);
2716 const Standard_Integer anIndex = theIndices.FindIndex(aShape);
2722 theGroupIds[i]->SetValue(j, anIndex);
2730 //=======================================================================
2731 //function : StoreGroups
2732 //purpose : auxiliary for CreateGroups()
2733 //=======================================================================
2734 void StoreGroups(GEOMImpl_IPipe *theCI,
2735 Handle(TColStd_HArray1OfInteger) *theGroups)
2737 if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
2738 theCI->SetGroupDown(theGroups[GROUP_DOWN]);
2741 if (theGroups[GROUP_UP].IsNull() == Standard_False) {
2742 theCI->SetGroupUp(theGroups[GROUP_UP]);
2745 if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
2746 theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
2749 if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
2750 theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
2753 if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
2754 theCI->SetGroupOther(theGroups[GROUP_OTHER]);
2758 //=======================================================================
2759 //function : CreateDownUpGroups
2760 //purpose : auxiliary for DoGroups()
2761 //=======================================================================
2762 static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
2763 TopTools_SequenceOfShape *theGroups,
2764 Standard_Boolean &IsDoSides)
2766 const TopoDS_Shape aDownShape = theSweep->FirstShape();
2767 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2768 TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
2770 IsDoSides = Standard_False;
2775 anUpDownType = TopAbs_EDGE;
2777 if (GEOMUtils::IsOpenPath(aDownShape)) {
2778 IsDoSides = Standard_True;
2783 anUpDownType = TopAbs_FACE;
2789 if (anUpDownType == TopAbs_SHAPE) {
2790 // Invalid Up and Down group type.
2794 TopExp_Explorer anExp(aDownShape, anUpDownType);
2795 TopTools_MapOfShape aMapFence;
2797 // Create Down group.
2798 for (; anExp.More(); anExp.Next()) {
2799 const TopoDS_Shape &aShape = anExp.Current();
2801 if (aMapFence.Add(aShape)) {
2802 theGroups[GROUP_DOWN].Append(aShape);
2807 const TopoDS_Shape anUpShape = theSweep->LastShape();
2810 anExp.Init(anUpShape, anUpDownType);
2812 for (; anExp.More(); anExp.Next()) {
2813 const TopoDS_Shape &aShape = anExp.Current();
2815 if (aMapFence.Add(aShape)) {
2816 theGroups[GROUP_UP].Append(aShape);
2823 //=======================================================================
2824 //function : DoGroups1
2825 //purpose : auxiliary for CreateGroups1()
2826 //=======================================================================
2827 bool DoGroups1 (const TopoDS_Shape &theProfile,
2828 BRepOffsetAPI_MakePipeShell &theSweep,
2829 TopTools_SequenceOfShape *theGroups)
2831 Standard_Boolean isDoSides = Standard_False;
2833 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2834 // Up and Down groups creation failure
2838 TopoDS_Shape aDownShape = theProfile;
2839 if (aDownShape.IsNull()) aDownShape = theSweep.FirstShape();
2842 // Create Side1 and Side2 groups.
2843 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2844 TopoDS_Vertex aV[2];
2847 if (aType == TopAbs_EDGE) {
2848 TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
2849 } else { // aType == TopAbs_WIRE
2850 TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
2853 for (i = 0; i < 2; ++i) {
2854 if (aV[i].IsNull() == Standard_False) {
2855 const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
2857 if (!aLstSide.IsEmpty()) {
2858 TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
2859 TopTools_MapOfShape aMapFence;
2860 const Standard_Integer anIdSide =
2861 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2863 for (; aSideIt.More(); aSideIt.Next()) {
2864 const TopoDS_Shape &aSideShape = aSideIt.Value();
2866 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2867 if (aMapFence.Add(aSideShape)) {
2868 theGroups[anIdSide].Append(aSideShape);
2870 } else if (aSideShape.ShapeType() == TopAbs_WIRE) {
2871 if (aMapFence.Add(aSideShape)) {
2872 TopExp_Explorer anExpWE (aSideShape, TopAbs_EDGE);
2873 for (; anExpWE.More(); anExpWE.Next()) {
2874 theGroups[anIdSide].Append(anExpWE.Current());
2878 // Only edges can be in Side1 and Side2 groups.
2886 // Create Other group. Get boundary edges of the profile.
2887 TopTools_MapOfShape aMapBndEdges;
2888 TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
2890 for (; anExp.More(); anExp.Next()) {
2891 const TopoDS_Shape &anEdge = anExp.Current();
2893 if (!aMapBndEdges.Add(anEdge)) {
2894 aMapBndEdges.Remove(anEdge);
2898 // Fill the map of faces generated from profile's boundary edges.
2899 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2900 TopTools_MapOfShape aMapFence;
2902 for (; anIter.More(); anIter.Next()) {
2903 const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
2905 if (!aLstOther.IsEmpty()) {
2906 TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
2908 for (; anOtherIt.More(); anOtherIt.Next()) {
2909 const TopoDS_Shape &anOtherShape = anOtherIt.Value();
2911 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2912 if (aMapFence.Add(anOtherShape)) {
2913 theGroups[GROUP_OTHER].Append(anOtherShape);
2915 } else if (anOtherShape.ShapeType() == TopAbs_SHELL) {
2916 if (aMapFence.Add(anOtherShape)) {
2917 TopExp_Explorer anExpSHF (anOtherShape, TopAbs_FACE);
2918 for (; anExpSHF.More(); anExpSHF.Next()) {
2919 theGroups[GROUP_OTHER].Append(anExpSHF.Current());
2923 // Only faces can be in Other group.
2934 //=======================================================================
2935 //function : CreateGroups1
2936 //purpose : auxiliary for Execute()
2937 //=======================================================================
2938 bool CreateGroups1 (const TopoDS_Shape &theProfile,
2939 BRepOffsetAPI_MakePipeShell &theSweep,
2940 GEOMImpl_IPipe *theCI)
2942 if (!theCI->GetGenerateGroups()) {
2948 TopTools_SequenceOfShape aGroups[5];
2950 if (!DoGroups1(theProfile, theSweep, aGroups)) {
2955 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2956 TopTools_IndexedMapOfShape anIndices;
2957 const TopoDS_Shape aResult = theSweep.Shape();
2959 TopExp::MapShapes(aResult, anIndices);
2961 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2966 StoreGroups(theCI, aGroupIds);
2971 //=======================================================================
2972 //function : DoGroups2
2973 //purpose : auxiliary for CreateGroups()
2974 //=======================================================================
2975 static bool DoGroups2(const TopoDS_Shape &theProfile,
2976 const TopoDS_Shape &thePath,
2977 BRepOffsetAPI_MakePipe &theSweep,
2978 TopTools_SequenceOfShape *theGroups)
2980 Standard_Boolean isDoSides = Standard_False;
2982 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2983 // Up and Down groups creation failure
2988 // Create Side1 and Side2 groups.
2989 const TopAbs_ShapeEnum aType = theProfile.ShapeType();
2990 TopoDS_Vertex aV[2];
2993 if (aType == TopAbs_EDGE) {
2994 TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
2995 } else { // aType == TopAbs_WIRE
2996 TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
2999 for (i = 0; i < 2; ++i) {
3000 if (aV[i].IsNull() == Standard_False) {
3001 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
3002 TopTools_MapOfShape aMapFence;
3003 const Standard_Integer anIdSide =
3004 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
3006 for (; anExpP.More(); anExpP.Next()) {
3007 const TopoDS_Shape aSideShape =
3008 theSweep.Generated(anExpP.Current(), aV[i]);
3010 if (aSideShape.ShapeType() == TopAbs_EDGE) {
3011 if (aMapFence.Add(aSideShape)) {
3012 theGroups[anIdSide].Append(aSideShape);
3015 // Only edges can be is Side1 and Side2 groups.
3022 // Create Other group. Get boundary edges of the profile.
3023 TopTools_MapOfShape aMapBndEdges;
3024 TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
3026 for (; anExp.More(); anExp.Next()) {
3027 const TopoDS_Shape &anEdge = anExp.Current();
3029 if (!aMapBndEdges.Add(anEdge)) {
3030 aMapBndEdges.Remove(anEdge);
3034 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
3035 TopTools_MapOfShape aMapFence;
3037 for (; anExpP.More(); anExpP.Next()) {
3038 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
3040 for (; anIter.More(); anIter.Next()) {
3041 const TopoDS_Shape anOtherShape =
3042 theSweep.Generated(anExpP.Current(), anIter.Key());
3044 if (anOtherShape.ShapeType() == TopAbs_FACE) {
3045 if (aMapFence.Add(anOtherShape)) {
3046 theGroups[GROUP_OTHER].Append(anOtherShape);
3049 // Only faces can be in Other group.
3059 //=======================================================================
3060 //function : CreateGroups
3061 //purpose : auxiliary for Execute()
3062 //=======================================================================
3063 static bool CreateGroups2(const TopoDS_Shape &theProfile,
3064 const TopoDS_Shape &thePath,
3065 BRepOffsetAPI_MakePipe &theSweep,
3066 GEOMImpl_IPipe *theCI)
3068 if (!theCI->GetGenerateGroups()) {
3074 TopTools_SequenceOfShape aGroups[5];
3076 if (!DoGroups2(theProfile, thePath, theSweep, aGroups)) {
3081 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
3082 TopTools_IndexedMapOfShape anIndices;
3083 const TopoDS_Shape aResult = theSweep.Shape();
3085 TopExp::MapShapes(aResult, anIndices);
3087 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
3092 StoreGroups(theCI, aGroupIds);
3097 //=======================================================================
3098 //function : Execute
3100 //=======================================================================
3101 Standard_Integer GEOMImpl_PipeDriver::Execute(Handle(TFunction_Logbook)& log) const
3103 if (Label().IsNull()) return 0;
3104 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
3105 Standard_Integer aType = aFunction->GetType();
3107 GEOMImpl_IPipe* aCI = 0;
3108 if (aType == PIPE_BASE_PATH)
3109 aCI = new GEOMImpl_IPipe (aFunction);
3110 else if (aType == PIPE_DIFFERENT_SECTIONS)
3111 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
3112 else if (aType == PIPE_SHELL_SECTIONS)
3113 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3114 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
3115 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3116 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
3117 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
3121 TopoDS_Wire aWirePath;
3122 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
3123 // working with path
3124 Handle(GEOM_Function) aRefPath = aCI->GetPath();
3125 TopoDS_Shape aShapePath = aRefPath->GetValue();
3127 if (aShapePath.IsNull()) {
3128 MESSAGE ("Driver : path is null");
3129 if (aCI) delete aCI;
3130 Standard_NullObject::Raise("MakePipe aborted : null path argument");
3135 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
3136 TopTools_SequenceOfShape anEdges;
3137 TopExp_Explorer anExp;
3141 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
3142 B.Add(W, anExp.Current());
3148 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
3149 aWirePath = TopoDS::Wire(aShapePath);
3153 if (aShapePath.ShapeType() == TopAbs_EDGE) {
3154 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
3155 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
3160 if (aCI) delete aCI;
3161 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
3164 // Check if it is possible to create groups.
3165 if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
3170 Standard_ConstructionError::Raise
3171 ("Can't create groups if the path is closed");
3175 TopoDS_Shape aShape;
3176 const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
3178 if (aType == PIPE_BASE_PATH) {
3179 Handle(GEOM_Function) aRefBase = aCI->GetBase();
3180 TopoDS_Shape aShapeBase;
3182 // Make copy to prevent modifying of base object 0020766 : EDF 1320
3183 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
3185 aShapeBase = Copy.Shape();
3187 if (aShapeBase.IsNull()) {
3188 if (aCI) delete aCI;
3189 Standard_NullObject::Raise("MakePipe aborted : null base argument");
3193 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
3194 aShapeBase.ShapeType() == TopAbs_WIRE)
3196 TopoDS_Wire aProfile;
3197 if (aShapeBase.ShapeType() == TopAbs_WIRE)
3198 aProfile = TopoDS::Wire(aShapeBase);
3202 BB.MakeWire(aProfile);
3203 BB.Add(aProfile, aShapeBase);
3206 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
3207 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
3208 if (FaceBuilder.IsDone())
3209 Sweep.SetMode(FaceBuilder.Face());
3210 Sweep.Add(aProfile);
3212 Standard_Boolean isDone = BuildPipeShell(Sweep);
3216 if (aCI) delete aCI;
3217 Standard_ConstructionError::Raise("MakePipeShell failed");
3220 aShape = Sweep.Shape(); //result is good
3222 if (!CreateGroups1(aProfile, Sweep, aCI)) {
3223 if (aCI) delete aCI;
3224 Standard_ConstructionError::Raise("Generate groups failure");
3229 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
3230 BRepOffsetAPI_MakePipe aMkPipe
3231 (aWirePath, aShapeBase, theBestMode, Standard_True);
3233 if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) {
3234 aShape = aMkPipe.Shape();
3236 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipe, aCI)) {
3237 if (aCI) delete aCI;
3238 Standard_ConstructionError::Raise("Generate groups failure");
3240 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
3241 // Try to use Descrete Trihedron mode.
3242 BRepOffsetAPI_MakePipe aMkPipeDescrete
3243 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron, Standard_True);
3245 if (aMkPipeDescrete.IsDone()) {
3246 aShape = aMkPipeDescrete.Shape();
3248 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
3249 if (aCI) delete aCI;
3250 Standard_ConstructionError::Raise("Generate groups failure");
3257 //building pipe with different sections
3258 else if (aType == PIPE_DIFFERENT_SECTIONS) {
3259 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
3260 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
3261 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
3262 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
3263 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
3264 Standard_Boolean isBySteps = aCIDS->GetIsBySteps();
3271 Standard_Integer nbBases = aBasesObjs->Length();
3272 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
3274 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
3275 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
3278 for (i = 1; i <= nbBases; i++) {
3279 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
3280 if (anItem.IsNull())
3282 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
3283 if (aRefBase.IsNull())
3285 if (aRefBase->GetValue().IsNull())
3288 aHSeqBases->Append(aRefBase->GetValue());
3290 for (i = 1; i <= nbLocs; i++) {
3291 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
3292 if (anItemLoc.IsNull())
3294 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
3295 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
3296 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
3299 aHSeqLocs->Append(aShapeLoc);
3303 Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
3304 Handle(TColStd_HArray1OfInteger) aGroups[5];
3306 if (isGenerateGroups) {
3310 aShape = CreatePipeWithDifferentSections
3311 (aWirePath, aHSeqBases, aHSeqLocs,
3312 aWithContact, aWithCorrect, isBySteps, pGroups);
3314 if (isGenerateGroups) {
3315 // Store created groups.
3316 GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
3318 StoreGroups(&aPipeDS, aGroups);
3322 //building pipe with shell sections
3323 else if (aType == PIPE_SHELL_SECTIONS) {
3324 aShape = CreatePipeForShellSections(aWirePath,aCI);
3327 //building pipe shell sections without path
3328 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
3329 aShape = CreatePipeShellsWithoutPath(aCI);
3332 //building a pipe with constant bi-normal along given vector
3333 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
3334 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
3342 if (aShape.IsNull()) return 0;
3344 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
3345 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
3347 if (aType != PIPE_BASE_PATH &&
3348 aType != PIPE_SHELLS_WITHOUT_PATH) {
3349 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
3350 if (anExpV.More()) {
3351 Standard_Real aVertMaxTol = -RealLast();
3352 for (; anExpV.More(); anExpV.Next()) {
3353 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
3354 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
3355 if (aTol > aVertMaxTol)
3358 aVertMaxTol += Precision::Confusion();
3360 TopTools_DataMapOfShapeListOfShape aMapModif;
3361 TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
3363 if (isGenerateGroups) {
3364 pMapModif = &aMapModif;
3367 TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
3368 (aShape, aVertMaxTol, Standard_True, pMapModif);
3370 if (isGenerateGroups && !aMapModif.IsEmpty()) {
3372 GEOMImpl_IPipe aCI(aFunction);
3373 Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
3374 { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
3375 aCI.GetGroupSide2(), aCI.GetGroupOther() };
3376 TopTools_IndexedMapOfShape anIndices;
3377 TopTools_IndexedMapOfShape aNewIndices;
3378 TopTools_SequenceOfShape aNewShapes[5];
3379 TopTools_MapOfShape aMapReplaced;
3380 TopTools_MapOfShape aMapGlued;
3381 Standard_Integer iGrp;
3384 TopExp::MapShapes(aShape, anIndices);
3385 TopExp::MapShapes(aNewShape, aNewIndices);
3387 for (iGrp = 0; iGrp < 5; ++iGrp) {
3388 if (aGroupIDs[iGrp].IsNull() == Standard_False) {
3389 const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
3390 const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
3392 for (i = aLower; i <= anUpper; ++i) {
3393 const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
3394 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
3396 if (aMapModif.IsBound(aSubShape)) {
3397 const TopTools_ListOfShape &aListModif =
3398 aMapModif.Find(aSubShape);
3399 TopTools_ListIteratorOfListOfShape anIter(aListModif);
3401 for (; anIter.More(); anIter.Next()) {
3402 const TopoDS_Shape &aNewShape = anIter.Value();
3404 if (aMapReplaced.Add(aNewShape)) {
3405 aNewShapes[iGrp].Append(aNewShape);
3407 // This is a glued shape. It means that it is internal
3408 // one and should be removed from groups later.
3409 aMapGlued.Add(aNewShape);
3413 // Shape is not modified.
3414 aNewShapes[iGrp].Append(aSubShape);
3420 if (!aMapGlued.IsEmpty()) {
3421 // Remove glued (internal) shapes from groups.
3422 for (iGrp = 0; iGrp < 5; ++iGrp) {
3423 Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
3425 for (i = 1; i < aNbShapes; ++i) {
3426 const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
3428 if (aMapGlued.Contains(aNewShape)) {
3429 aNewShapes[iGrp].Remove(i);
3437 // Store modified groups.
3438 Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
3440 if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
3441 Standard_ConstructionError::Raise("Generate groups failure");
3444 StoreGroups(&aCI, aNewGroupIDs);
3451 // Note: group indices should not be changed after the next call.
3452 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
3453 aFunction->SetValue(aRes);
3455 log->SetTouched(Label());
3459 //================================================================================
3461 * \brief Returns a name of creation operation and names and values of creation parameters
3463 //================================================================================
3465 bool GEOMImpl_PipeDriver::
3466 GetCreationInformation(std::string& theOperationName,
3467 std::vector<GEOM_Param>& theParams)
3469 if (Label().IsNull()) return 0;
3470 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
3471 Standard_Integer aType = function->GetType();
3474 case PIPE_BASE_PATH:
3476 theOperationName = "PIPE";
3477 GEOMImpl_IPipe aCI( function );
3478 AddParam( theParams, "Base Object", aCI.GetBase() );
3479 AddParam( theParams, "Path Object", aCI.GetPath() );
3482 case PIPE_BI_NORMAL_ALONG_VECTOR:
3484 theOperationName = "PIPE";
3485 GEOMImpl_IPipeBiNormal aCI( function );
3486 AddParam( theParams, "Base Object", aCI.GetBase() );
3487 AddParam( theParams, "Path Object", aCI.GetPath() );
3488 AddParam( theParams, "BiNormal", aCI.GetVector() );
3491 case PIPE_DIFFERENT_SECTIONS:
3493 theOperationName = "PIPE";
3494 GEOMImpl_IPipeDiffSect aCI( function );
3495 AddParam( theParams, "Bases", aCI.GetBases() );
3496 AddParam( theParams, "Locations", aCI.GetLocations() );
3497 AddParam( theParams, "Path", aCI.GetPath() );
3499 if (!aCI.GetIsBySteps()) {
3500 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3501 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3504 AddParam( theParams, "Step by step", aCI.GetIsBySteps() );
3507 case PIPE_SHELL_SECTIONS:
3509 theOperationName = "PIPE";
3510 GEOMImpl_IPipeShellSect aCI( function );
3511 AddParam( theParams, "Bases", aCI.GetBases() );
3512 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
3513 AddParam( theParams, "Locations", aCI.GetLocations() );
3514 AddParam( theParams, "Path", aCI.GetPath() );
3515 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3516 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3519 case PIPE_SHELLS_WITHOUT_PATH:
3521 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
3522 GEOMImpl_IPipeShellSect aCI( function );
3523 AddParam( theParams, "Bases", aCI.GetBases() );
3524 AddParam( theParams, "Locations", aCI.GetLocations() );
3534 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver)