1 // Copyright (C) 2007-2016 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>
58 #include <TopExp_Explorer.hxx>
60 #include <TopoDS_Wire.hxx>
61 #include <TopoDS_Edge.hxx>
62 #include <TopoDS_Shape.hxx>
63 #include <TopoDS_Solid.hxx>
64 #include <TopoDS_Shell.hxx>
65 #include <TopoDS_Face.hxx>
66 #include <TopoDS_Compound.hxx>
67 #include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
68 #include <TopTools_SequenceOfShape.hxx>
69 #include <TopTools_HSequenceOfShape.hxx>
70 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
71 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
72 #include <TopTools_ListIteratorOfListOfShape.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
75 #include <GProp_GProps.hxx>
77 #include <GeomAPI_ProjectPointOnCurve.hxx>
78 #include <GeomAPI_Interpolate.hxx>
79 #include <Geom_TrimmedCurve.hxx>
80 #include <Geom_Plane.hxx>
81 #include <Geom_RectangularTrimmedSurface.hxx>
82 #include <Geom_BezierSurface.hxx>
83 #include <Geom_Line.hxx>
84 #include <Geom_Conic.hxx>
85 #include <Geom_BSplineCurve.hxx>
86 #include <Geom_BSplineSurface.hxx>
87 #include <GeomAdaptor_HCurve.hxx>
88 #include <GeomFill_BSplineCurves.hxx>
89 #include <GeomConvert_ApproxCurve.hxx>
90 #include <GeomConvert.hxx>
92 #include <TColgp_SequenceOfPnt.hxx>
93 #include <TColgp_HArray1OfPnt.hxx>
94 #include <TColgp_Array2OfPnt.hxx>
95 #include <TColStd_HSequenceOfTransient.hxx>
97 #include <Precision.hxx>
99 #include <Standard_NullObject.hxx>
100 #include <Standard_TypeMismatch.hxx>
101 #include <Standard_ConstructionError.hxx>
103 #include "utilities.h"
107 #define GROUP_SIDE1 2
108 #define GROUP_SIDE2 3
109 #define GROUP_OTHER 4
111 static const Standard_Real TolPipeSurf = 5.e-4;
113 static bool FillGroups(const TopTools_SequenceOfShape *theGroups,
114 const TopTools_IndexedMapOfShape &theIndices,
115 Handle(TColStd_HArray1OfInteger) *theGroupIds);
117 static void StoreGroups(GEOMImpl_IPipe *theCI,
118 Handle(TColStd_HArray1OfInteger) *theGroups);
120 // after OCCT improvement
121 static bool DoGroups1(const TopoDS_Shape &theProfile,
122 BRepOffsetAPI_MakePipeShell &theSweep,
123 TopTools_SequenceOfShape *theGroups);
125 static bool CreateGroups1(const TopoDS_Shape &theProfile,
126 BRepOffsetAPI_MakePipeShell &theSweep,
127 GEOMImpl_IPipe *theCI);
129 //=======================================================================
132 //=======================================================================
133 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
135 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
139 //=======================================================================
140 //function : GEOMImpl_PipeDriver
142 //=======================================================================
143 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
147 //=======================================================================
148 //function : EvaluateBestSweepMode
149 //purpose : auxiliary for right call of MakePipe and MakePipeShell
150 //=======================================================================
151 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
153 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
155 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
156 for (; Explo.More(); Explo.Next())
158 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
159 Standard_Real fpar, lpar;
160 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
161 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
162 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
164 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
165 aCorrFrenet->SetCurve(GAHcurve);
166 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
167 if (aMode == GeomFill_IsDiscreteTrihedron)
172 if (aMode == GeomFill_IsCorrectedFrenet)
179 //=======================================================================
180 //function : BuildPipeShell
181 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
182 // mode. Returns Standard_True if the building is done successfully.
183 //=======================================================================
184 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
186 theBuilder.SetForceApproxC1(Standard_True);
190 Standard_Boolean isDone = theBuilder.IsDone();
193 theBuilder.ErrorOnSurface() > TolPipeSurf) {
194 // Try to use Descrete Trihedron mode.
195 theBuilder.SetDiscreteMode();
197 isDone = theBuilder.IsDone();
203 //=======================================================================
204 //function : FillForOtherEdges
205 //purpose : auxiliary for CreatePipeForShellSections()
206 //=======================================================================
207 static bool FillForOtherEdges(const TopoDS_Shape& F1,
208 const TopoDS_Shape& E1,
209 const TopoDS_Shape& V1,
210 TopTools_IndexedDataMapOfShapeShape& FF)
212 // find other pairs for vertexes and edges
213 // creating map of vertex edges for both faces
214 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
215 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
216 if (!FF.Contains(F1)) MESSAGE(" FillForOtherEdges: map FF not contains key F1");
217 if (!FF.Contains(E1)) MESSAGE(" FillForOtherEdges: map FF not contains key E1");
218 if (!FF.Contains(V1)) MESSAGE(" FillForOtherEdges: map FF not contains key V1");
219 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
220 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
221 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
222 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
223 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
225 TopoDS_Edge ES1 = TopoDS::Edge(E1);
226 TopoDS_Edge ES2 = TopoDS::Edge(E2);
227 TopoDS_Shape VS1 = V1;
228 TopoDS_Shape VS2 = V2;
230 ShapeAnalysis_Edge sae;
232 if (!aMapVertEdge1.Contains(VS1)) MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
233 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
234 TopTools_ListIteratorOfListOfShape anIter1(aList1);
235 if (anIter1.Value().IsSame(ES1)) {
238 if (!aMapVertEdge2.Contains(VS2)) MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
239 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
240 TopTools_ListIteratorOfListOfShape anIter2(aList2);
241 if (anIter2.Value().IsSame(ES2)) {
244 ES1 = TopoDS::Edge(anIter1.Value());
245 ES2 = TopoDS::Edge(anIter2.Value());
246 if (!FF.Contains(ES1)) {
249 if (VS1.IsSame(sae.FirstVertex(ES1)))
250 VS1 = sae.LastVertex(ES1);
252 VS1 = sae.FirstVertex(ES1);
253 if (VS2.IsSame(sae.FirstVertex(ES2)))
254 VS2 = sae.LastVertex(ES2);
256 VS2 = sae.FirstVertex(ES2);
259 if (!FF.Contains(VS1)) {
267 //=======================================================================
268 //function : FillCorrespondingEdges
269 //purpose : auxiliary for CreatePipeForShellSections()
270 //=======================================================================
271 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
272 const TopoDS_Shape& FS2,
273 const TopoDS_Vertex& aLoc1,
274 const TopoDS_Vertex& aLoc2,
275 const TopoDS_Wire& aWirePath,
276 TopTools_IndexedDataMapOfShapeShape& FF)
278 // find corresponding edges
279 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
280 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
281 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
282 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
283 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
284 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
285 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
286 if (theBestMode == GeomFill_IsDiscreteTrihedron)
287 aBuilder.SetDiscreteMode();
288 aBuilder.Add(aWire1, aLoc1);
289 aBuilder.Add(aWire2, aLoc2);
290 if (!aBuilder.IsReady()) {
294 BuildPipeShell(aBuilder);
296 TopoDS_Shape aShape = aBuilder.Shape();
297 ShapeAnalysis_Edge sae;
298 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
299 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
300 TopTools_MapOfShape Vs1,Vs2;
302 exp.Init(FS1, TopAbs_EDGE);
303 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
304 TopoDS_Vertex V11 = sae.FirstVertex(E1);
305 TopoDS_Vertex V21 = sae.LastVertex(E1);
306 gp_Pnt P11 = BRep_Tool::Pnt(V11);
307 gp_Pnt P21 = BRep_Tool::Pnt(V21);
308 // find corresponding vertexes from created shape
309 TopoDS_Vertex VN11,VN21;
310 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
311 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
312 gp_Pnt P = BRep_Tool::Pnt(V);
313 if (P.Distance(P11)<tol) {
316 if (P.Distance(P21)<tol) {
320 // find edge contains VN11 and VN21 and corresponding vertexes
321 TopoDS_Vertex VN12,VN22;
322 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
323 TopoDS_Shape F = exp.Current();
324 TopExp_Explorer expe;
326 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
327 TopoDS_Edge E = TopoDS::Edge(expe.Current());
328 TopoDS_Vertex VF = sae.FirstVertex(E);
329 TopoDS_Vertex VL = sae.LastVertex(E);
330 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
336 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
337 TopoDS_Edge E = TopoDS::Edge(expe.Current());
338 TopoDS_Vertex VF = sae.FirstVertex(E);
339 TopoDS_Vertex VL = sae.LastVertex(E);
340 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
342 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
344 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
346 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
352 // find vertexes from FS2 corresponded to VN12 and VN22
353 // and find edge from FS2 contains V12 and V22,
354 // this edge will be corresponded to edge E1
355 TopoDS_Vertex V12,V22;
356 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
357 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
359 TopExp_Explorer expe;
360 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
361 TopoDS_Edge E = TopoDS::Edge(expe.Current());
362 TopoDS_Vertex VF = sae.FirstVertex(E);
363 TopoDS_Vertex VL = sae.LastVertex(E);
364 gp_Pnt PF = BRep_Tool::Pnt(VF);
365 gp_Pnt PL = BRep_Tool::Pnt(VL);
366 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
372 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
383 // find other pairs for vertexes and edges
384 // creating map of vertex edges for both faces
385 return FillForOtherEdges(FS1,E1,V21,FF);
390 //=======================================================================
391 //function : FillCorrespondingEdges
392 //purpose : auxiliary for CreatePipeShellsWithoutPath()
393 //=======================================================================
394 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
395 const TopoDS_Shape& FS2,
396 const TopoDS_Vertex& aLoc1,
397 const TopoDS_Vertex& aLoc2,
398 TopTools_IndexedDataMapOfShapeShape& FF)
400 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
401 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
404 ShapeAnalysis_Edge sae;
405 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
406 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
407 TopTools_MapOfShape Vs1,Vs2;
409 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
412 TopExp_Explorer exp1;
413 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
414 E1 = TopoDS::Edge(exp1.Current());
415 TopoDS_Vertex V1 = sae.FirstVertex(E1);
416 TopoDS_Vertex V2 = sae.LastVertex(E1);
417 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
418 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
419 if (P1.Distance(Ptmp1)<tol) {
423 if (P1.Distance(Ptmp2)<tol) {
430 TopoDS_Vertex VE21,VE22;
432 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
433 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
434 TopoDS_Vertex V1 = sae.FirstVertex(E);
435 TopoDS_Vertex V2 = sae.LastVertex(E);
436 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
437 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
438 if (P2.Distance(Ptmp1)<tol) {
450 if (P2.Distance(Ptmp2)<tol) {
464 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
465 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
466 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
467 gp_Vec aDir1(PV21,PE21);
468 gp_Vec aDir2(PV21,PE22);
469 double ang1 = aDir.Angle(aDir1);
470 double ang2 = aDir.Angle(aDir2);
471 if (fabs(ang1)<fabs(ang2)) {
484 // find other pairs for vertexes and edges
485 return FillForOtherEdges(FS1,E1,V21,FF);
488 //=======================================================================
489 //function : FindNextPairOfFaces
490 //purpose : auxiliary for CreatePipeForShellSections()
491 //=======================================================================
492 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
493 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
494 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
495 TopTools_IndexedDataMapOfShapeShape& FF,
498 TopExp_Explorer anExp;
499 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
500 TopoDS_Shape E1 = anExp.Current();
501 if (!FF.Contains(E1)) {
503 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
505 if (!FF.Contains(E1)) MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
506 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
507 TopExp_Explorer anExpV;
508 anExpV.Init(E1, TopAbs_VERTEX);
509 TopoDS_Shape V1 = anExpV.Current();
510 if (!FF.Contains(V1)) {
512 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
515 if (!aMapEdgeFaces1.Contains(E1)) MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
516 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
517 if (aList1.Extent()<2)
519 TopTools_ListIteratorOfListOfShape anIter(aList1);
520 if (anIter.Value().IsEqual(aCurFace)) {
523 TopoDS_Shape F1other = anIter.Value();
524 if (FF.Contains(F1other))
527 if (!FF.Contains(aCurFace)) MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
528 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
529 if (!aMapEdgeFaces2.Contains(E2)) MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
530 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
531 if (aList2.Extent()<2) {
533 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
535 TopTools_ListIteratorOfListOfShape anIter2(aList2);
536 if (anIter2.Value().IsEqual(F2)) {
539 TopoDS_Shape F2other = anIter2.Value();
540 FF.Add(F1other,F2other);
542 // add pairs of edges to FF
543 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
546 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not map other edges");
549 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
553 //=======================================================================
554 //function : FindFirstPairFaces
555 //purpose : auxiliary for Execute()
556 //=======================================================================
557 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
558 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
559 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
561 // check if vertexes are sub-shapes of sections
562 gp_Pnt P1 = BRep_Tool::Pnt(V1);
563 gp_Pnt P2 = BRep_Tool::Pnt(V2);
564 TopoDS_Vertex V1new,V2new;
566 double mindist = 1.e10;
567 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
568 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
569 gp_Pnt P = BRep_Tool::Pnt(V);
570 double dist = P1.Distance(P);
577 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
578 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
579 gp_Pnt P = BRep_Tool::Pnt(V);
580 double dist = P2.Distance(P);
587 // replace vertexes if it is needed
588 if (!V1.IsSame(V1new)) {
590 P1 = BRep_Tool::Pnt(V1);
591 MESSAGE (" replace V1");
594 MESSAGE (" not replace V1");
595 if (!V2.IsSame(V2new)) {
597 P2 = BRep_Tool::Pnt(V2);
598 MESSAGE (" replace V2");
601 MESSAGE (" not replace V2");
603 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
604 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
605 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
606 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
608 if (!aMapVertFaces1.Contains(V1))
609 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
610 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
611 TopTools_ListIteratorOfListOfShape anIter1(aList1);
612 FS1 = anIter1.Value();
614 double x1=0., y1=0., z1=0.;
616 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
617 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
618 gp_Pnt P = BRep_Tool::Pnt(V);
624 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
626 TColgp_SequenceOfPnt Ps;
627 TopTools_SequenceOfShape Fs;
628 if (!aMapVertFaces2.Contains(V2))
629 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
630 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
631 TopTools_ListIteratorOfListOfShape anIter2(aList2);
632 for (; anIter2.More(); anIter2.Next()) {
633 TopoDS_Shape F = anIter2.Value();
634 double x2=0., y2=0., z2=0.;
636 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
637 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
638 gp_Pnt P = BRep_Tool::Pnt(V);
644 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
651 double MinAng = M_PI;
653 for (; i<=Fs.Length(); i++) {
654 gp_Vec tmpDir(PM1,Ps(i));
655 double ang = fabs(aDir.Angle(tmpDir));
664 //=======================================================================
665 //function : RemoveFaces
666 //purpose : This function returns theShapeFrom without faces of the shape
667 // theFacesToRm. It returns a shell if theShapeFrom is a solid or
668 // a compound otherwise. Auxiliary for CreatePipeWithDifferentSections
670 //=======================================================================
671 static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom,
672 const TopoDS_Shape &theFacesToRm)
674 TopTools_IndexedMapOfShape aMapFaces;
675 TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE);
676 BRep_Builder aBuilder;
677 TopoDS_Shape aResult;
679 if (theShapeFrom.ShapeType() == TopAbs_SOLID) {
681 aBuilder.MakeShell(TopoDS::Shell(aResult));
684 aBuilder.MakeCompound(TopoDS::Compound(aResult));
687 TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces);
689 for (; anExp.More(); anExp.Next()) {
690 const TopoDS_Shape &aFace = anExp.Current();
692 if (!aMapFaces.Contains(aFace)) {
693 aBuilder.Add(aResult, aFace);
700 //=======================================================================
701 //function : makeSolid
702 //purpose : auxilary for CreatePipeWithDifferentSections
703 //=======================================================================
704 Standard_Boolean makeSolid(
705 BRepOffsetAPI_MakePipeShell aBuilder,
706 const TopoDS_Shape& aSh1,
707 const TopoDS_Shape& aSh2,
708 TopoDS_Shape& aShape)
710 Standard_Boolean isDone = Standard_True;
711 Standard_Integer nbPlanar = 0;
712 if (aSh1.ShapeType() == TopAbs_FACE && aSh2.ShapeType() == TopAbs_FACE)
714 Handle(Geom_Surface) aS = BRep_Tool::Surface(TopoDS::Face(aSh1));
715 if (aS->IsKind(STANDARD_TYPE(Geom_Plane))) {
718 else if (aS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
719 Handle(Geom_RectangularTrimmedSurface) aTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
720 if (aTS->BasisSurface()->IsKind(STANDARD_TYPE(Geom_Plane))) {
724 aS = BRep_Tool::Surface(TopoDS::Face(aSh2));
725 if (aS->IsKind(STANDARD_TYPE(Geom_Plane))) {
728 else if (aS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
729 Handle(Geom_RectangularTrimmedSurface) aTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
730 if (aTS->BasisSurface()->IsKind(STANDARD_TYPE(Geom_Plane))) {
736 TopoDS_Shape aPipe = aBuilder.Shape();
737 // make sewing for result
738 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
739 Standard_Real aTol = Precision::Confusion();
740 aSewing->SetTolerance(aTol);
741 aSewing->SetFaceMode(Standard_True);
742 aSewing->SetFloatingEdgesMode(Standard_False);
743 aSewing->SetNonManifoldMode(Standard_False);
744 TopExp_Explorer anExp;
745 for (anExp.Init(aPipe, TopAbs_FACE); anExp.More(); anExp.Next()) {
746 aSewing->Add(anExp.Current());
751 aShape = aSewing->SewedShape();
752 if (aShape.ShapeType() == TopAbs_SHELL) {
754 BRepBuilderAPI_MakeSolid aMkSolid;
755 aMkSolid.Add(TopoDS::Shell(aShape));
756 if (!aMkSolid.IsDone()) {
757 isDone = Standard_False;
760 TopoDS_Solid aSolid = aMkSolid.Solid();
761 BRepClass3d_SolidClassifier aSC(aSolid);
762 aSC.PerformInfinitePoint(Precision::Confusion());
763 if (aSC.State() == TopAbs_IN) {
764 aShape = aSolid.Reversed();
772 isDone = Standard_False;
776 isDone = Standard_False;
779 isDone = aBuilder.MakeSolid();
781 aShape = aBuilder.Shape();
787 //=======================================================================
788 //function : CreatePipeWithDifferentSections
790 //=======================================================================
791 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
792 (const TopoDS_Wire &theWirePath,
793 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
794 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
795 const Standard_Boolean theWithContact,
796 const Standard_Boolean theWithCorrect,
797 const Standard_Boolean IsBySteps,
798 Handle(TColStd_HArray1OfInteger) *theGroups)
802 TopoDS_Wire aWirePath = theWirePath;
804 Standard_Integer nbBases = theHSeqBases->Length();
805 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
807 if (nbLocs && nbLocs != nbBases) {
808 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
811 TopTools_SequenceOfShape aSeqBases;
812 TopTools_SequenceOfShape aSeqLocs;
813 TopTools_SequenceOfShape aSeqFaces;
814 Standard_Boolean NeedCreateSolid = Standard_False;
816 Standard_Integer i = 1;
817 for (i = 1; i <= nbBases; i++) {
818 if (theHSeqBases->Value(i).IsNull())
821 // Make copy to prevent modifying of base object 0020766 : EDF 1320
822 TopoDS_Shape aShapeBase;
823 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
825 aShapeBase = Copy.Shape();
827 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
829 //if for section was specified face with a few wires then a few
830 // pipes were build and make solid
831 if (aTypeBase == TopAbs_SHELL) {
832 // create wire as boundary contour if shell is no closed
833 // get free boundary shapes
834 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
835 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
836 TopExp_Explorer anExp;
838 Standard_Integer NbWires = 0;
839 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
841 aWire = anExp.Current();
845 Standard_ConstructionError::Raise("Bad shell is used as section ");
847 NeedCreateSolid = Standard_True;
848 aSeqFaces.Append(aShapeBase);
849 aSeqBases.Append(aWire);
851 else if (aTypeBase == TopAbs_FACE) {
852 NeedCreateSolid = Standard_True;
853 //for case one path should be used other type function
854 aSeqFaces.Append(aShapeBase);
855 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
856 for (; aExpW.More(); aExpW.Next()) {
857 TopoDS_Shape aWireProf = aExpW.Current();
858 aSeqBases.Append(aWireProf);
861 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
862 aSeqBases.Append(aShapeBase);
864 else if (aTypeBase == TopAbs_EDGE) {
865 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
866 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
867 aSeqBases.Append(aWireProf);
870 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
871 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
873 aSeqLocs.Append(aShapeLoc);
877 nbLocs = aSeqLocs.Length();
880 TopTools_SequenceOfShape Edges;
882 // we have to check that each location shape is a vertex from
883 // path and update aSeqLocs if it is needed (and possible)
884 TColgp_SequenceOfPnt PLocs;
885 for (i=1; i<=nbLocs; i++) {
886 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
887 PLocs.Append(BRep_Tool::Pnt(V));
889 //TopTools_SequenceOfShape Edges;
890 TopExp_Explorer anExp;
891 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
892 Edges.Append(anExp.Current());
894 int nbEdges = Edges.Length();
895 ShapeAnalysis_Edge sae;
896 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
897 double tol = BRep_Tool::Tolerance(edge);
898 TopoDS_Vertex VF = sae.FirstVertex(edge);
899 gp_Pnt PF = BRep_Tool::Pnt(VF);
900 if (PF.Distance(PLocs.First()) > tol) {
901 Standard_ConstructionError::Raise
902 ("First location shapes is not coincided with first vertex of aWirePath");
904 aSeqLocs.ChangeValue(1) = VF;
905 edge = TopoDS::Edge(Edges.Last());
906 tol = BRep_Tool::Tolerance(edge);
907 TopoDS_Vertex VL = sae.LastVertex(edge);
908 gp_Pnt PL = BRep_Tool::Pnt(VL);
909 if (PL.Distance(PLocs.Last()) > tol) {
910 Standard_ConstructionError::Raise
911 ("Last location shapes is not coincided with last vertex of aWirePath");
913 aSeqLocs.ChangeValue(nbLocs) = VL;
915 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
916 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
917 tol = BRep_Tool::Tolerance(edge);
918 TopoDS_Vertex V1 = sae.FirstVertex(E);
919 TopoDS_Vertex V2 = sae.LastVertex(E);
920 gp_Pnt P1 = BRep_Tool::Pnt(V1);
921 gp_Pnt P2 = BRep_Tool::Pnt(V2);
922 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
923 aSeqLocs.ChangeValue(jcurr) = V2;
927 // find distance between E and aLocs(jcurr)
929 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
930 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
931 if (PPCurve.NbPoints()>0 &&
932 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
933 double param = PPCurve.Parameter(1);
936 // split current edge
937 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
938 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
943 if (Pfp.Distance(P1)<tol) {
944 B.MakeEdge(E1,tc1,tol);
946 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
947 B.Add(E1,TopoDS::Vertex(tmpV));
948 B.MakeEdge(E2,tc2,tol);
949 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
950 B.Add(E2,TopoDS::Vertex(tmpV));
954 B.MakeEdge(E1,tc2,tol);
955 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
956 B.Add(E1,TopoDS::Vertex(tmpV));
959 B.MakeEdge(E2,tc1,tol);
961 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
962 B.Add(E2,TopoDS::Vertex(tmpV));
967 Edges.InsertAfter(i-1,E1);
968 Edges.InsertAfter(i,E2);
972 if (nbEdges<Edges.Length()) {
973 // one of edges was split => we have to update WirePath
977 for (i=1; i<=Edges.Length(); i++) {
978 B.Add(W,TopoDS::Edge(Edges.Value(i)));
984 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
987 // Fill SplitEdgeNums and SplitLocNums with intermediate location indices
988 // and corresponding edge indices.
989 Standard_Integer i = 1;
994 for (j = 2; j < aSeqLocs.Length(); j++) {
995 SplitLocNums.Append(j);
996 aVert = TopoDS::Vertex(aSeqLocs.Value(j));
997 aP = BRep_Tool::Pnt(aVert);
999 while (i < Edges.Length()) {
1002 TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i));
1003 Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
1004 Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp);
1007 aC->D0(aLp, aPLast);
1010 if (aP.Distance(aPLast) < aTol) {
1011 SplitEdgeNums.Append(i - 1);
1017 // check curvature of wire for condition that
1018 // max summary angle between directions along
1019 // wire path must be < 4*PI. If not - split wire
1020 // and seguences of shapes, perform pipe for each
1021 // and make sewing after that
1026 if ( Edges.Length() > 0 ) {
1027 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
1030 SumAng = fabs(Vec1.Angle(Vec2));
1035 for (i=2; i<=Edges.Length(); i++) {
1036 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
1037 double tol = BRep_Tool::Tolerance(edge);
1038 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1040 double ang = fabs(Vec1.Angle(Vec2));
1042 if (SumAng>4*M_PI) {
1044 SplitEdgeNums.Append(i-1);
1046 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
1047 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
1048 gp_Pnt P = BRep_Tool::Pnt(aVert);
1049 if (P1.Distance(P) < tol) {
1050 SplitLocNums.Append(j);
1061 bool isCreateGroups = (theGroups != NULL);
1063 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
1064 TopTools_SequenceOfShape aSeqRes;
1065 TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
1066 Standard_Integer iGrp;
1067 int nn, num1 = 1, num2 = 1;
1068 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
1069 // create wirepath and sequences of shapes
1073 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
1074 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1076 num1 = SplitEdgeNums.Value(nn) + 1;
1077 TopTools_SequenceOfShape aTmpSeqBases;
1078 TopTools_SequenceOfShape aTmpSeqLocs;
1079 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
1080 aTmpSeqBases.Append(aSeqBases.Value(i));
1081 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1083 num2 = SplitLocNums.Value(nn);
1085 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1086 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1087 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1088 aBuilder.SetDiscreteMode();
1089 Standard_Integer nbShapes = aTmpSeqBases.Length();
1090 for (i=1; i<=nbShapes; i++) {
1091 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1092 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1093 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1095 if (!aBuilder.IsReady()) {
1096 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1099 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1101 if (isDone && NeedCreateSolid && nn == 1) {
1102 // Make solid for the first step.
1103 isDone = aBuilder.MakeSolid();
1107 Standard_ConstructionError::Raise("Pipe construction failure");
1110 TopoDS_Shape resShape = aBuilder.Shape();
1112 if (NeedCreateSolid && nn == 1) {
1113 // Remove top lid from the result.
1114 resShape = RemoveFaces(resShape, aBuilder.LastShape());
1117 aSeqRes.Append(resShape);
1120 if (isCreateGroups) {
1122 TopTools_SequenceOfShape aGroups[5];
1124 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1125 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1126 Standard_ConstructionError::Raise("Generate groups failure");
1129 // Get shapes from all groups.
1130 for (iGrp = 0; iGrp < 5; ++iGrp) {
1131 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1135 // create wirepath and sequences of shapes for last part
1139 for (i=num1; i<=Edges.Length(); i++) {
1140 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1142 TopTools_SequenceOfShape aTmpSeqBases;
1143 TopTools_SequenceOfShape aTmpSeqLocs;
1144 for (i=num2; i<=aSeqLocs.Length(); i++) {
1145 aTmpSeqBases.Append(aSeqBases.Value(i));
1146 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1148 // make pipe for last part
1149 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1150 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1151 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1152 aBuilder.SetDiscreteMode();
1153 Standard_Integer nbShapes = aTmpSeqBases.Length();
1154 for (i=1; i<=nbShapes; i++) {
1155 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1156 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1157 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1159 if (!aBuilder.IsReady()) {
1160 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1163 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1165 if (isDone && NeedCreateSolid) {
1166 isDone = aBuilder.MakeSolid();
1170 Standard_ConstructionError::Raise("Pipe construction failure");
1173 TopoDS_Shape resShape = aBuilder.Shape();
1175 if (NeedCreateSolid) {
1176 // Remove bottom lid from the result.
1177 resShape = RemoveFaces(resShape, aBuilder.FirstShape());
1180 aSeqRes.Append(resShape);
1183 if (isCreateGroups) {
1185 TopTools_SequenceOfShape aGroups[5];
1187 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1188 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1189 Standard_ConstructionError::Raise("Generate groups failure");
1192 // Get shapes from all groups.
1193 for (iGrp = 0; iGrp < 5; ++iGrp) {
1194 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1198 // make sewing for result
1199 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1200 aSewing->SetTolerance(Precision::Confusion());
1201 aSewing->SetFaceMode(Standard_True);
1202 aSewing->SetFloatingEdgesMode(Standard_False);
1203 aSewing->SetNonManifoldMode(Standard_False);
1204 for (i=1; i<=aSeqRes.Length(); i++) {
1205 aSewing->Add(aSeqRes.Value(i));
1208 aShape = aSewing->SewedShape();
1210 if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) {
1212 BRepBuilderAPI_MakeSolid aMkSolid;
1214 aMkSolid.Add(TopoDS::Shell(aShape));
1216 if (!aMkSolid.IsDone()) {
1217 Standard_ConstructionError::Raise("Can't create solid pipe");
1220 TopoDS_Solid aSolid = aMkSolid.Solid();
1221 BRepClass3d_SolidClassifier aSC(aSolid);
1223 aSC.PerformInfinitePoint(Precision::Confusion());
1225 if (aSC.State() == TopAbs_IN) {
1226 aShape = aSolid.Reversed();
1232 if (isCreateGroups) {
1233 // Replase Group shapes by modified ones.
1234 TopTools_SequenceOfShape aSeqGroups[5];
1237 for (iGrp = 0; iGrp < 5; ++iGrp) {
1239 for (i = 1; i <= aSeqRes.Length(); ++i) {
1240 if (iGrp == GROUP_DOWN && i > 1) {
1241 // For DOWN group we use only the first pipe.
1245 if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
1246 // For UP group we use only the last pipe.
1250 const TopTools_SequenceOfShape &aShapes =
1251 aMapResGroups[iGrp].Find(aSeqRes.Value(i));
1254 // For each sub-shape of pipe
1255 for (j = 1; j <= aShapes.Length(); ++j) {
1256 const TopoDS_Shape &aGrpShape = aShapes.Value(j);
1258 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1259 // Use the shape modified by sewing.
1260 const TopoDS_Shape &aModifGrpShape =
1261 aSewing->ModifiedSubShape(aGrpShape);
1263 aSeqGroups[iGrp].Append(aModifGrpShape);
1265 // Use the shape as it is.
1266 aSeqGroups[iGrp].Append(aGrpShape);
1273 TopTools_IndexedMapOfShape anIndices;
1275 TopExp::MapShapes(aShape, anIndices);
1277 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1278 Standard_ConstructionError::Raise("Generate groups failure");
1283 // old implementation without splitting
1284 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1285 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1286 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1287 aBuilder.SetDiscreteMode();
1289 Standard_Integer nbShapes = aSeqBases.Length();
1290 Standard_Integer step = nbShapes/nbBases;
1292 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1293 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1295 Standard_Integer ind =0;
1296 Standard_Real aTolConf = Precision::Confusion();
1297 Standard_Real aTolAng = Precision::Angular();
1299 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1300 TopTools_SequenceOfShape usedBases;
1301 Standard_Integer j = 1;
1302 for (; j <= nbBases; j++) {
1303 ind = i + (j-1)*step;
1304 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1305 usedBases.Append(aWireProf);
1307 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1308 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1309 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1312 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1314 if (!aBuilder.IsReady()) {
1315 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1318 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1320 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1323 if (NeedCreateSolid) {
1324 TopoDS_Shape aSh1 = aSeqFaces.Value(1);
1325 TopoDS_Shape aSh2 = aSeqFaces.Value(aSeqFaces.Length());
1326 isDone = makeSolid(aBuilder, aSh1, aSh2, aShape);
1329 aShape = aBuilder.Shape();
1334 Standard_ConstructionError::Raise("Pipe construction failure");
1337 if (isCreateGroups) {
1339 TopTools_SequenceOfShape aSeqGroups[5];
1341 TopoDS_Shape aProfile = usedBases.Value(1);
1342 if (!DoGroups1(aProfile, aBuilder, aSeqGroups)) {
1343 Standard_ConstructionError::Raise("Generate groups failure");
1347 //Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1348 TopTools_IndexedMapOfShape anIndices;
1349 const TopoDS_Shape aResult = aBuilder.Shape();
1351 TopExp::MapShapes(aResult, anIndices);
1353 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1354 Standard_ConstructionError::Raise("Generate groups failure");
1357 aSeqFaces.Append(aShape);
1358 for (j = 1; j <=usedBases.Length(); j++)
1359 aBuilder.Delete(usedBases.Value(j));
1366 //=======================================================================
1367 //function : CreatePipeForShellSections
1368 //purpose : auxiliary for Execute()
1369 //=======================================================================
1370 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1371 GEOMImpl_IPipe* aCI)
1376 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1377 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1378 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1379 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1380 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1381 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1382 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1384 Standard_Integer nbBases = aBasesObjs->Length(),
1385 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1386 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1388 if (nbLocs != nbBases) {
1389 if (aCI) delete aCI;
1390 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1392 if (nbSubBases && nbSubBases != nbBases) {
1393 if (aCI) delete aCI;
1394 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1397 TopTools_SequenceOfShape VLocs;
1398 for (i=1; i<=nbBases; i++) {
1399 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1400 if (anItemLoc.IsNull())
1402 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1403 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1404 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1406 VLocs.Append(aShapeLoc);
1408 nbLocs = VLocs.Length();
1409 if (nbLocs != nbBases) {
1410 if (aCI) delete aCI;
1411 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1413 // split wire path by location points
1414 TColgp_SequenceOfPnt PLocs;
1415 for (i=1; i<=nbLocs; i++) {
1416 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1417 PLocs.Append(BRep_Tool::Pnt(V));
1420 TopTools_SequenceOfShape Edges;
1421 TopTools_SequenceOfShape Wires;
1422 ShapeAnalysis_Edge sae;
1425 TopExp_Explorer anExp;
1426 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1427 Edges.Append(anExp.Current());
1429 Standard_Integer Num1 = 0;
1430 Standard_Integer Num2 = 0;
1431 for (i=1; i<=Edges.Length(); i++) {
1432 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1433 double tol = BRep_Tool::Tolerance(E);
1434 TopoDS_Vertex V1 = sae.FirstVertex(E);
1435 TopoDS_Vertex V2 = sae.LastVertex(E);
1436 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1437 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1438 if (P1.Distance(PLocs.First()) < tol) {
1441 if (P2.Distance(PLocs.Last()) < tol) {
1445 if (Num1>0 && Num2>0) {
1448 for (i=Num1; i<=Num2; i++) {
1449 B.Add(W,Edges.Value(i));
1454 Wires.Append(aWirePath);
1458 TopExp_Explorer anExp;
1459 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1460 Edges.Append(anExp.Current());
1462 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1463 double tol = BRep_Tool::Tolerance(edge);
1464 TopoDS_Vertex VF = sae.FirstVertex(edge);
1465 gp_Pnt PF = BRep_Tool::Pnt(VF);
1466 if (PF.Distance(PLocs.First()) > tol) {
1467 if (aCI) delete aCI;
1468 Standard_ConstructionError::Raise
1469 ("First location shapes is not coincided with first vertex of aWirePath");
1471 VLocs.ChangeValue(1) = VF;
1472 edge = TopoDS::Edge(Edges.Last());
1473 tol = BRep_Tool::Tolerance(edge);
1474 TopoDS_Vertex VL = sae.LastVertex(edge);
1475 gp_Pnt PL = BRep_Tool::Pnt(VL);
1476 if (PL.Distance(PLocs.Last()) > tol) {
1477 if (aCI) delete aCI;
1478 Standard_ConstructionError::Raise
1479 ("Last location shapes is not coincided with last vertex of aWirePath");
1481 VLocs.ChangeValue(nbLocs) = VL;
1483 TopTools_SequenceOfShape tmpEdges;
1484 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1485 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1486 tol = BRep_Tool::Tolerance(E);
1487 TopoDS_Vertex V1 = sae.FirstVertex(E);
1488 TopoDS_Vertex V2 = sae.LastVertex(E);
1489 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1490 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1491 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1492 // make wire from current edge and add created
1496 for (j=1; j<=tmpEdges.Length(); j++)
1497 B.Add(W,tmpEdges.Value(j));
1500 VLocs.ChangeValue(jcurr) = V2;
1505 // find distance between E and aLocs(jcurr)
1507 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1508 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1509 if (PPCurve.NbPoints()>0 &&
1510 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1511 double param = PPCurve.Parameter(1);
1514 // split current edge
1515 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1516 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1520 if (Pfp.Distance(P1)<tol) {
1521 B.MakeEdge(E1,tc1,tol);
1523 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1524 B.Add(E1,TopoDS::Vertex(tmpV));
1525 tmpEdges.Append(E1);
1526 B.MakeEdge(E2,tc2,tol);
1527 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1528 B.Add(E2,TopoDS::Vertex(tmpV));
1532 B.MakeEdge(E1,tc2,tol);
1533 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1534 B.Add(E1,TopoDS::Vertex(tmpV));
1537 tmpEdges.Append(E1);
1538 B.MakeEdge(E2,tc1,tol);
1540 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1541 B.Add(E2,TopoDS::Vertex(tmpV));
1544 // create wire from tmpEdges
1547 for (j=1; j<=tmpEdges.Length(); j++)
1548 B.Add(W,tmpEdges.Value(j));
1553 Edges.InsertAfter(i-1,E1);
1554 Edges.InsertAfter(i,E2);
1561 // create wire from other edges
1564 for (; i<=Edges.Length(); i++)
1565 B.Add(W,Edges.Value(i));
1569 if (Wires.Length() != nbLocs-1) {
1570 if (aCI) delete aCI;
1571 Standard_ConstructionError::Raise
1572 ("One of location shapes is not lied on the path");
1575 TopTools_SequenceOfShape aGroups[5];
1576 TopoDS_Compound aComp;
1577 B.MakeCompound(aComp);
1578 for (i = 1; i < nbBases; i++) {
1579 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1581 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1582 if (anItem1.IsNull())
1584 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1585 if (aRefBase1.IsNull())
1587 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1588 if (aShBase1.IsNull())
1590 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1592 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1593 if (anItem2.IsNull())
1595 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1596 if (aRefBase2.IsNull())
1598 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1599 if (aShBase2.IsNull())
1601 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1603 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1604 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1606 if (aCI) delete aCI;
1607 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1610 bool CreateFewSolids = false;
1612 TopExp_Explorer anExp;
1613 Standard_Integer nbf1 = 0;
1614 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1617 Standard_Integer nbf2 = 0;
1618 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1622 CreateFewSolids = true;
1625 if (!CreateFewSolids) {
1626 // we can create only one solid
1627 TopoDS_Shape aWire1, aWire2;
1629 if (aType1==TopAbs_SHELL) {
1630 // create wire as boundary contour if shell is no closed
1631 // get free boundary shapes
1632 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1633 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1634 //TopExp_Explorer anExp;
1635 Standard_Integer NbWires = 0;
1636 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1638 aWire1 = anExp.Current();
1642 if (aCI) delete aCI;
1643 Standard_ConstructionError::Raise("Bad shell is used as section ");
1646 else { // aType1==TopAbs_FACE
1647 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1648 aWire1 = aExpW.Current();
1651 if (aType2==TopAbs_SHELL) {
1652 // create wire as boundary contour if shell is no closed
1653 // get free boundary shapes
1654 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1655 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1656 //TopExp_Explorer anExp;
1657 Standard_Integer NbWires = 0;
1658 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1660 aWire2 = anExp.Current();
1664 if (aCI) delete aCI;
1665 Standard_ConstructionError::Raise("Bad shell is used as section ");
1668 else { // aType2==TopAbs_FACE
1669 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1670 aWire2 = aExpW.Current();
1672 // make pipe using aWire1 and aWire2
1673 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1674 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1675 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1676 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1677 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1678 aBuilder.SetDiscreteMode();
1679 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1680 aWithContact, aWithCorrect);
1681 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1682 aWithContact, aWithCorrect);
1683 if (!aBuilder.IsReady()) {
1684 if (aCI) delete aCI;
1685 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1688 BuildPipeShell(aBuilder);
1690 TopoDS_Shape aShape = aBuilder.Shape();
1691 TopTools_SequenceOfShape aLocalGroups[5];
1694 if (isGenerateGroups) {
1696 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
1697 if (aCI) delete aCI;
1698 Standard_ConstructionError::Raise("Generate groups failure");
1701 // Clear the groups Down and Up.
1702 aLocalGroups[GROUP_DOWN].Clear();
1703 aLocalGroups[GROUP_UP].Clear();
1706 TopoDS_Shell aShell;
1707 B.MakeShell(aShell);
1708 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1709 B.Add(aShell,anExp.Current());
1711 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1712 B.Add(aShell,anExp.Current());
1714 if (isGenerateGroups && i == 1) {
1715 aLocalGroups[GROUP_DOWN].Append(anExp.Current());
1718 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1719 B.Add(aShell,anExp.Current());
1721 if (isGenerateGroups && i == nbBases - 1) {
1722 aLocalGroups[GROUP_UP].Append(anExp.Current());
1725 // make sewing for this shell
1726 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1727 aSewing->SetTolerance(Precision::Confusion());
1728 aSewing->SetFaceMode(Standard_True);
1729 aSewing->SetFloatingEdgesMode(Standard_False);
1730 aSewing->SetNonManifoldMode(Standard_False);
1731 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1732 aSewing->Add(anExp.Current());
1735 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1736 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1737 aShell = TopoDS::Shell(aSewShape);
1738 GProp_GProps aSystem;
1739 BRepGProp::VolumeProperties(aShell, aSystem);
1740 if (aSystem.Mass()<0) {
1743 if (BRep_Tool::IsClosed(aShell)) {
1744 TopoDS_Solid aSolid;
1745 B.MakeSolid(aSolid);
1746 B.Add(aSolid,aShell);
1747 B.Add(aComp,aSolid);
1750 B.Add(aComp,aShell);
1754 B.Add(aComp,aShell);
1757 if (isGenerateGroups) {
1758 Standard_Integer iGrp;
1760 for (iGrp = 0; iGrp < 5; ++iGrp) {
1763 // For each sub-shape of pipe
1764 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1765 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1767 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1768 // Use the shape modified by sewing.
1769 const TopoDS_Shape &aModifGrpShape =
1770 aSewing->ModifiedSubShape(aGrpShape);
1772 aGroups[iGrp].Append(aModifGrpShape);
1774 // Use the shape as it is.
1775 aGroups[iGrp].Append(aGrpShape);
1783 // main block - creation few solids (for each pair of faces)
1784 TopTools_MapOfShape aFaces1,aFaces2;
1785 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1786 aFaces1.Add(anExp.Current());
1788 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1789 aFaces2.Add(anExp.Current());
1791 // creating map of edge faces
1792 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1793 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1794 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1795 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1797 // constuct map face->face
1798 TopTools_IndexedDataMapOfShapeShape FF;
1799 TopoDS_Shape FS1,FS2;
1800 if (nbSubBases==0) {
1801 // find edge the most distant from location point
1802 // (this edge is not shared by two faces)
1803 double maxdist = 0.;
1805 TopoDS_Vertex V11,V21;
1806 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1807 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1808 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1809 if (aList.Extent()>1)
1811 TopExp_Explorer expv;
1812 expv.Init(tmp, TopAbs_VERTEX);
1813 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1815 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1816 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1817 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1818 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1823 TopTools_ListIteratorOfListOfShape anIter(aList);
1824 FS1 = anIter.Value();
1828 // main direction for comparing
1829 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1830 // find corresponding edge from next section
1831 double minang = M_PI;
1832 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1833 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1835 TopoDS_Vertex V12,V22;
1836 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1837 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1838 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1839 if (aList.Extent()>1)
1841 TopExp_Explorer expv;
1842 expv.Init(tmp, TopAbs_VERTEX);
1843 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1845 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1846 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1847 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1848 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1849 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1850 TopoDS_Vertex V1,V2;
1853 V1 = V2tmp; P1 = P2tmp;
1854 V2 = V1tmp; P2 = P1tmp;
1857 V1 = V1tmp; P1 = P1tmp;
1858 V2 = V2tmp; P2 = P2tmp;
1860 gp_Vec Vec1(P11,P1);
1861 gp_Vec Vec2(P21,P2);
1862 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1867 TopTools_ListIteratorOfListOfShape anIter(aList);
1868 FS2 = anIter.Value();
1872 // put all pairs to map FF
1878 // add pairs of edges to FF
1879 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1881 if (aCI) delete aCI;
1882 Standard_ConstructionError::Raise("FindForOtherEdges: Can not map other edges");
1888 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1889 if (anItem.IsNull()) {
1890 if (aCI) delete aCI;
1891 Standard_ConstructionError::Raise("Invalid subbase shape");
1893 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1894 if (aRefBase.IsNull()) {
1895 if (aCI) delete aCI;
1896 Standard_ConstructionError::Raise("Invalid subbase shape");
1898 TopoDS_Shape aSh = aRefBase->GetValue();
1900 if (aCI) delete aCI;
1901 Standard_ConstructionError::Raise("Invalid subbase shape");
1903 if (aSh.ShapeType()!=TopAbs_FACE) {
1904 if (aCI) delete aCI;
1905 Standard_ConstructionError::Raise("Invalid subbase shape");
1910 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1911 if (anItem.IsNull()) {
1912 if (aCI) delete aCI;
1913 Standard_ConstructionError::Raise("Invalid subbase shape");
1915 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1916 if (aRefBase.IsNull()) {
1917 if (aCI) delete aCI;
1918 Standard_ConstructionError::Raise("Invalid subbase shape");
1920 TopoDS_Shape aSh = aRefBase->GetValue();
1922 if (aCI) delete aCI;
1923 Standard_ConstructionError::Raise("Invalid subbase shape");
1925 if (aSh.ShapeType()!=TopAbs_FACE) {
1926 if (aCI) delete aCI;
1927 Standard_ConstructionError::Raise("Invalid subbase shape");
1932 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1933 if (aCI) delete aCI;
1934 Standard_ConstructionError::Raise("Invalid subbase shape");
1939 // add pairs of edges to FF
1940 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1941 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1943 if (aCI) delete aCI;
1944 Standard_ConstructionError::Raise("Can not create correct pipe");
1948 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1950 // make pipe for each pair of faces
1951 for (j=1; j<=FF.Extent(); j++) {
1952 TopoDS_Shape F1 = FF.FindKey(j);
1953 if (F1.ShapeType() != TopAbs_FACE)
1955 TopoDS_Shape F2 = FF.FindFromIndex(j);
1956 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1957 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1958 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1959 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1960 // make pipe using aWire1 and aWire2
1961 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1962 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1963 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1964 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1965 aBuilder.SetDiscreteMode();
1966 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1967 aWithContact, aWithCorrect);
1968 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1969 aWithContact, aWithCorrect);
1970 if (!aBuilder.IsReady()) {
1971 if (aCI) delete aCI;
1972 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1975 BuildPipeShell(aBuilder);
1977 TopoDS_Shape aShape = aBuilder.Shape();
1978 TopTools_SequenceOfShape aLocalGroups[5];
1981 if (isGenerateGroups) {
1983 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
1984 if (aCI) delete aCI;
1985 Standard_ConstructionError::Raise("Generate groups failure");
1988 // Clear the groups Down and Up.
1989 aLocalGroups[GROUP_DOWN].Clear();
1990 aLocalGroups[GROUP_UP].Clear();
1993 aLocalGroups[GROUP_DOWN].Append(F1);
1996 if (i == nbBases - 1) {
1997 aLocalGroups[GROUP_UP].Append(F2);
2001 TopoDS_Shell aShell;
2002 B.MakeShell(aShell);
2003 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
2004 B.Add(aShell,anExp.Current());
2009 // make sewing for this shell
2010 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2011 aSewing->SetTolerance(Precision::Confusion());
2012 aSewing->SetFaceMode(Standard_True);
2013 aSewing->SetFloatingEdgesMode(Standard_False);
2014 aSewing->SetNonManifoldMode(Standard_False);
2015 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2016 aSewing->Add(anExp.Current());
2019 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2020 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2021 aShell = TopoDS::Shell(aSewShape);
2022 GProp_GProps aSystem;
2023 BRepGProp::VolumeProperties(aShell, aSystem);
2024 if (aSystem.Mass() < 0) {
2027 if (BRep_Tool::IsClosed(aShell)) {
2028 TopoDS_Solid aSolid;
2029 B.MakeSolid(aSolid);
2030 B.Add(aSolid,aShell);
2031 B.Add(aComp,aSolid);
2034 B.Add(aComp,aShell);
2038 B.Add(aComp,aShell);
2041 if (isGenerateGroups) {
2042 // Replase Group shapes by modified ones.
2043 Standard_Integer iGrp;
2046 for (iGrp = 0; iGrp < 5; ++iGrp) {
2049 // For each sub-shape of pipe
2050 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2051 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2053 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2054 // Use the shape modified by sewing.
2055 const TopoDS_Shape &aModifGrpShape =
2056 aSewing->ModifiedSubShape(aGrpShape);
2058 aGroups[iGrp].Append(aModifGrpShape);
2060 // Use the shape as it is.
2061 aGroups[iGrp].Append(aGrpShape);
2071 if (isGenerateGroups) {
2073 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2074 TopTools_IndexedMapOfShape anIndices;
2076 TopExp::MapShapes(aComp, anIndices);
2078 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2079 if (aCI) delete aCI;
2080 Standard_ConstructionError::Raise("Generate groups failure");
2083 StoreGroups(aCI, aGroupIds);
2089 //=======================================================================
2090 //function : CreatePipeShellsWithoutPath
2091 //purpose : auxiliary for Execute()
2092 //=======================================================================
2093 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
2098 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
2100 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
2101 // vertex for recognition
2102 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
2103 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
2105 Standard_Integer nbBases = aBasesObjs->Length(),
2106 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
2108 if (nbv != nbBases) {
2109 if (aCI) delete aCI;
2110 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
2113 TopTools_SequenceOfShape aGroups[5];
2114 TopTools_SequenceOfShape SecVs,Bases;
2115 for (i=1; i<=nbBases; i++) {
2117 Handle(Standard_Transient) anItem = VObjs->Value(i);
2118 if (anItem.IsNull())
2120 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
2121 TopoDS_Shape V = aRef->GetValue();
2122 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
2126 anItem = aBasesObjs->Value(i);
2127 if (anItem.IsNull())
2129 aRef = Handle(GEOM_Function)::DownCast(anItem);
2130 TopoDS_Shape aSh = aRef->GetValue();
2135 nbv = SecVs.Length();
2136 nbBases = Bases.Length();
2137 if (nbv != nbBases) {
2138 if (aCI) delete aCI;
2139 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
2142 TopoDS_Compound aComp;
2143 B.MakeCompound(aComp);
2145 for (i = 1; i < nbBases; i++) {
2146 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
2147 TopoDS_Shape aShBase1 = Bases.Value(i);
2148 TopoDS_Shape aShBase2 = Bases.Value(i+1);
2149 TopExp_Explorer anExp;
2150 Standard_Integer nbf1 = 0;
2151 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2154 Standard_Integer nbf2 = 0;
2155 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2159 if (aCI) delete aCI;
2160 Standard_ConstructionError::Raise("Different number of faces in the sections");
2163 TopTools_MapOfShape aFaces1,aFaces2;
2164 TopTools_MapOfShape aBndEdges1;
2166 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2167 const TopoDS_Shape &aBaseFace1 = anExp.Current();
2169 if (aFaces1.Add(aBaseFace1)) {
2170 // Get boundary edges.
2171 TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
2173 for (; anExpE.More(); anExpE.Next()) {
2174 const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
2176 if (!aBndEdges1.Add(aBaseEdge1)) {
2177 aBndEdges1.Remove(aBaseEdge1);
2182 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2183 aFaces2.Add(anExp.Current());
2186 // creating map of edge faces
2187 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
2188 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
2189 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
2190 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
2192 // constuct map face->face (and sub-shapes)
2193 TopTools_IndexedDataMapOfShapeShape FF;
2194 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
2195 TopoDS_Shape FS1, FS2;
2196 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
2197 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
2198 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
2201 MESSAGE (" first pair of corresponding faces is found");
2203 // add pairs of edges and vertexes to FF
2204 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
2206 if (aCI) delete aCI;
2207 Standard_ConstructionError::Raise("Can not create correct pipe");
2209 MESSAGE (" correspondences for sub-shapes of first pair of faces found");
2211 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2212 MESSAGE (" other correspondences found, make pipe for all pairs of faces");
2214 // make pipe for each pair of faces
2215 // auxiliary map vertex->edge for created pipe edges
2216 TopTools_IndexedDataMapOfShapeShape VPE;
2217 ShapeAnalysis_Edge sae;
2219 for (j=1; j<=FF.Extent(); j++) {
2220 TopoDS_Shape F1 = FF.FindKey(j);
2221 if (F1.ShapeType() != TopAbs_FACE)
2223 TopoDS_Shape F2 = FF.FindFromIndex(j);
2226 //if (nbff!=3) continue;
2228 MESSAGE (" make pipe for "<<nbff<<" face");
2230 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
2231 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2232 Handle(Geom_RectangularTrimmedSurface) RTS =
2233 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
2234 S1 = RTS->BasisSurface();
2236 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
2237 if (Pln1.IsNull()) {
2238 if (aCI) delete aCI;
2239 Standard_ConstructionError::Raise("Surface from face is not plane");
2241 gp_Vec aDir1(Pln1->Axis().Direction());
2243 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
2244 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2245 Handle(Geom_RectangularTrimmedSurface) RTS =
2246 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
2247 S2 = RTS->BasisSurface();
2249 Handle(Geom_Plane) Pln2 =
2250 Handle(Geom_Plane)::DownCast(S2);
2251 if (Pln2.IsNull()) {
2252 if (aCI) delete aCI;
2253 Standard_ConstructionError::Raise("Surface from face is not plane");
2255 gp_Vec aDir2(Pln2->Axis().Direction());
2257 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
2258 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
2260 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
2262 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
2265 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
2266 TopTools_SequenceOfShape aNewFs;
2267 TopTools_SequenceOfShape aLocalGroups[5];
2270 for (; anExpE.More(); anExpE.Next()) {
2271 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2273 if (!FF.Contains(E1))
2274 MESSAGE ("map FF not contains key E1");
2276 if (VPE.Contains(E1)) {
2277 aNewFs.Append(VPE.FindFromKey(E1));
2279 MESSAGE (" using existing face");
2284 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2285 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2286 TopoDS_Vertex V2 = sae.LastVertex(E1);
2287 if (!FF.Contains(V1))
2288 MESSAGE ("map FF not contains key V1");
2289 if (!FF.Contains(V2))
2290 MESSAGE ("map FF not contains key V2");
2291 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2292 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2293 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2294 if (Vtmp.IsSame(V4))
2296 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2297 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2298 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2299 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2302 Handle(Geom_BSplineCurve) C2;
2303 if (VPE.Contains(V2)) {
2304 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2306 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2309 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2310 HAP->SetValue(1,P2);
2311 HAP->SetValue(2,P3);
2312 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2313 anInt.Load(aDir1,aDir2);
2316 B.MakeEdge(E2,C2,1.e-7);
2317 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2318 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2323 Handle(Geom_BSplineCurve) C4;
2324 if (VPE.Contains(V1)) {
2325 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2327 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2330 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2331 HAP->SetValue(1,P1);
2332 HAP->SetValue(2,P4);
2333 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2334 anInt.Load(aDir1,aDir2);
2337 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2338 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2339 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2348 B.Add(W,E4.Reversed());
2353 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2354 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2355 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2357 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2358 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2359 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2361 Handle(Geom_BSplineCurve) CE1 =
2362 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2363 if (CE1->Degree()<3)
2364 CE1->IncreaseDegree(3);
2365 Handle(Geom_BSplineCurve) CE2 =
2366 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2367 if (CE2->Degree()<3)
2368 CE2->IncreaseDegree(3);
2369 Handle(Geom_BSplineCurve) CE3 =
2370 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2371 if (CE3->Degree()<3)
2372 CE3->IncreaseDegree(3);
2373 Handle(Geom_BSplineCurve) CE4 =
2374 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2375 if (CE4->Degree()<3)
2376 CE4->IncreaseDegree(3);
2378 Handle(Geom_Surface) BS;
2380 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2381 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2385 MESSAGE (" can not create BSplineSurface - create Bezier");
2387 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2388 double fp1,lp1,fp2,lp2;
2389 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2390 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2399 // get points from C1
2400 if (P1.Distance(P1C1)<1.e-6) {
2408 double step = (lp-fp)/(NbP-1);
2409 Points.SetValue(1,1,P1);
2411 for (n1=2; n1<NbP; n1++) {
2415 Points.SetValue(1,n1,P);
2417 Points.SetValue(1,NbP,P2);
2418 // get points from C3
2419 if (P4.Distance(P1C3)<1.e-6) {
2427 step = (lp-fp)/(NbP-1);
2428 Points.SetValue(NbP,1,P4);
2430 for (n1=2; n1<NbP; n1++) {
2434 Points.SetValue(NbP,n1,P);
2436 Points.SetValue(NbP,NbP,P3);
2437 // create isolines and get points from them
2438 for (n1=1; n1<=NbP; n1++) {
2439 gp_Pnt PI1 = Points.Value(1,n1);
2440 gp_Pnt PI2 = Points.Value(NbP,n1);
2441 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2442 HAP->SetValue(1,PI1);
2443 HAP->SetValue(2,PI2);
2444 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2445 anInt.Load(aDir1,aDir2);
2447 const Handle(Geom_BSplineCurve) iso = anInt.Curve();
2448 fp = iso->FirstParameter();
2449 lp = iso->LastParameter();
2450 step = (lp-fp)/(NbP-1);
2452 TopoDS_Compound VComp;
2453 B.MakeCompound(VComp);
2454 for (n2=2; n2<NbP; n2++) {
2458 Points.SetValue(n2,n1,P);
2461 // create surface and face
2462 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2463 BS = new Geom_BezierSurface(Points);
2466 BRepBuilderAPI_MakeFace BB(BS,W);
2467 TopoDS_Face NewF = BB.Face();
2468 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2470 sff->FixOrientation();
2471 TopoDS_Face FixedFace = sff->Face();
2472 aNewFs.Append(FixedFace);
2473 VPE.Add(E1,FixedFace);
2475 if (isGenerateGroups) {
2476 if (aBndEdges1.Contains(E1)) {
2477 // This is a boundary face.
2478 aLocalGroups[GROUP_OTHER].Append(FixedFace);
2483 TopoDS_Shell aShell;
2484 B.MakeShell(aShell);
2485 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2486 B.Add(aShell,aNewFs(nf));
2492 if (isGenerateGroups && i == 1) {
2493 aLocalGroups[GROUP_DOWN].Append(F1);
2496 if (isGenerateGroups && i == nbBases - 1) {
2497 aLocalGroups[GROUP_UP].Append(F2);
2500 // make sewing for this shell
2501 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2502 aSewing->SetTolerance(Precision::Confusion());
2503 aSewing->SetFaceMode(Standard_True);
2504 aSewing->SetFloatingEdgesMode(Standard_False);
2505 aSewing->SetNonManifoldMode(Standard_False);
2506 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2507 aSewing->Add(anExp.Current());
2510 MESSAGE (" shell for face "<<nbff<<" is created");
2511 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2512 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2513 aShell = TopoDS::Shell(aSewShape);
2514 GProp_GProps aSystem;
2515 BRepGProp::VolumeProperties(aShell, aSystem);
2516 if (aSystem.Mass() < 0) {
2519 if (BRep_Tool::IsClosed(aShell)) {
2520 TopoDS_Solid aSolid;
2521 B.MakeSolid(aSolid);
2522 B.Add(aSolid,aShell);
2523 B.Add(aComp,aSolid);
2524 MESSAGE (" solid for face "<<nbff<<" is created");
2527 B.Add(aComp,aShell);
2528 MESSAGE (" solid for face "<<nbff<<" is not created");
2532 B.Add(aComp,aShell);
2533 MESSAGE (" solid for face "<<nbff<<" is not created");
2536 if (isGenerateGroups) {
2537 Standard_Integer iGrp;
2539 for (iGrp = 0; iGrp < 5; ++iGrp) {
2542 // For each sub-shape of pipe
2543 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2544 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2546 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2547 // Use the shape modified by sewing.
2548 const TopoDS_Shape &aModifGrpShape =
2549 aSewing->ModifiedSubShape(aGrpShape);
2551 aGroups[iGrp].Append(aModifGrpShape);
2553 // Use the shape as it is.
2554 aGroups[iGrp].Append(aGrpShape);
2562 if (isGenerateGroups) {
2564 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2565 TopTools_IndexedMapOfShape anIndices;
2567 TopExp::MapShapes(aComp, anIndices);
2569 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2570 if (aCI) delete aCI;
2571 Standard_ConstructionError::Raise("Generate groups failure");
2574 StoreGroups(aCI, aGroupIds);
2580 //=======================================================================
2581 //function : CreatePipeBiNormalAlongVector
2582 //purpose : auxiliary for Execute()
2583 //=======================================================================
2584 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2585 GEOMImpl_IPipe* aCI)
2587 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2589 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2590 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2591 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2592 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2594 if (aShapeBase.IsNull()) {
2595 if (aCIBN) delete aCIBN;
2596 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2599 // Make copy to prevent modifying of base object: 0021525
2600 BRepBuilderAPI_Copy Copy (aShapeBase);
2602 aShapeBase = Copy.Shape();
2605 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2608 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2609 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2611 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2614 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2615 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2616 aProf = wexp.Current();
2619 Standard_TypeMismatch::Raise
2620 ("MakePipe aborted : invalid type of base");
2622 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2623 PipeBuilder.Add(aProf);
2625 if (aShapeVec.IsNull()) {
2626 if (aCIBN) delete aCIBN;
2627 Standard_NullObject::Raise
2628 ("MakePipe aborted : null vector argument");
2630 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2631 Standard_TypeMismatch::Raise
2632 ("MakePipe aborted: invalid type of vector");
2633 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2634 TopoDS_Vertex V1, V2;
2635 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2636 if (V1.IsNull() || V2.IsNull())
2637 Standard_NullObject::Raise
2638 ("MakePipe aborted: vector is not defined");
2639 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2640 gp_Dir BiNormal(aVec);
2641 PipeBuilder.SetMode(BiNormal);
2643 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2645 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2646 PipeBuilder.MakeSolid();
2649 if (!CreateGroups1(aProf, PipeBuilder, aCIBN)) {
2650 if (aCIBN) delete aCIBN;
2651 Standard_ConstructionError::Raise("Generate groups failure");
2654 return PipeBuilder.Shape();
2657 //=======================================================================
2658 //function : FillGroups
2659 //purpose : auxiliary for DoGroups()
2660 //=======================================================================
2661 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
2662 const TopTools_IndexedMapOfShape &theIndices,
2663 Handle(TColStd_HArray1OfInteger) *theGroupIds)
2667 for (i = 0; i < 5; ++i) {
2668 if (!theGroups[i].IsEmpty()) {
2669 const Standard_Integer aNbShapes = theGroups[i].Length();
2672 theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
2674 for (j = 1; j <= aNbShapes; ++j) {
2675 const TopoDS_Shape &aShape = theGroups[i].Value(j);
2676 const Standard_Integer anIndex = theIndices.FindIndex(aShape);
2682 theGroupIds[i]->SetValue(j, anIndex);
2690 //=======================================================================
2691 //function : StoreGroups
2692 //purpose : auxiliary for CreateGroups()
2693 //=======================================================================
2694 void StoreGroups(GEOMImpl_IPipe *theCI,
2695 Handle(TColStd_HArray1OfInteger) *theGroups)
2697 if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
2698 theCI->SetGroupDown(theGroups[GROUP_DOWN]);
2701 if (theGroups[GROUP_UP].IsNull() == Standard_False) {
2702 theCI->SetGroupUp(theGroups[GROUP_UP]);
2705 if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
2706 theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
2709 if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
2710 theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
2713 if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
2714 theCI->SetGroupOther(theGroups[GROUP_OTHER]);
2718 //=======================================================================
2719 //function : CreateDownUpGroups
2720 //purpose : auxiliary for DoGroups()
2721 //=======================================================================
2722 static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
2723 TopTools_SequenceOfShape *theGroups,
2724 Standard_Boolean &IsDoSides)
2726 const TopoDS_Shape aDownShape = theSweep->FirstShape();
2727 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2728 TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
2730 IsDoSides = Standard_False;
2735 anUpDownType = TopAbs_EDGE;
2737 if (GEOMUtils::IsOpenPath(aDownShape)) {
2738 IsDoSides = Standard_True;
2743 anUpDownType = TopAbs_FACE;
2749 if (anUpDownType == TopAbs_SHAPE) {
2750 // Invalid Up and Down group type.
2754 TopExp_Explorer anExp(aDownShape, anUpDownType);
2755 TopTools_MapOfShape aMapFence;
2757 // Create Down group.
2758 for (; anExp.More(); anExp.Next()) {
2759 const TopoDS_Shape &aShape = anExp.Current();
2761 if (aMapFence.Add(aShape)) {
2762 theGroups[GROUP_DOWN].Append(aShape);
2767 const TopoDS_Shape anUpShape = theSweep->LastShape();
2770 anExp.Init(anUpShape, anUpDownType);
2772 for (; anExp.More(); anExp.Next()) {
2773 const TopoDS_Shape &aShape = anExp.Current();
2775 if (aMapFence.Add(aShape)) {
2776 theGroups[GROUP_UP].Append(aShape);
2783 //=======================================================================
2784 //function : DoGroups1
2785 //purpose : auxiliary for CreateGroups1()
2786 //=======================================================================
2787 bool DoGroups1 (const TopoDS_Shape &theProfile,
2788 BRepOffsetAPI_MakePipeShell &theSweep,
2789 TopTools_SequenceOfShape *theGroups)
2791 Standard_Boolean isDoSides = Standard_False;
2793 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2794 // Up and Down groups creation failure
2798 TopoDS_Shape aDownShape = theProfile;
2799 if (aDownShape.IsNull()) aDownShape = theSweep.FirstShape();
2802 // Create Side1 and Side2 groups.
2803 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2804 TopoDS_Vertex aV[2];
2807 if (aType == TopAbs_EDGE) {
2808 TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
2809 } else { // aType == TopAbs_WIRE
2810 TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
2813 for (i = 0; i < 2; ++i) {
2814 if (aV[i].IsNull() == Standard_False) {
2815 const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
2817 if (!aLstSide.IsEmpty()) {
2818 TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
2819 TopTools_MapOfShape aMapFence;
2820 const Standard_Integer anIdSide =
2821 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2823 for (; aSideIt.More(); aSideIt.Next()) {
2824 const TopoDS_Shape &aSideShape = aSideIt.Value();
2826 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2827 if (aMapFence.Add(aSideShape)) {
2828 theGroups[anIdSide].Append(aSideShape);
2830 } else if (aSideShape.ShapeType() == TopAbs_WIRE) {
2831 if (aMapFence.Add(aSideShape)) {
2832 TopExp_Explorer anExpWE (aSideShape, TopAbs_EDGE);
2833 for (; anExpWE.More(); anExpWE.Next()) {
2834 theGroups[anIdSide].Append(anExpWE.Current());
2838 // Only edges can be in Side1 and Side2 groups.
2846 // Create Other group. Get boundary edges of the profile.
2847 TopTools_MapOfShape aMapBndEdges;
2848 TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
2850 for (; anExp.More(); anExp.Next()) {
2851 const TopoDS_Shape &anEdge = anExp.Current();
2853 if (!aMapBndEdges.Add(anEdge)) {
2854 aMapBndEdges.Remove(anEdge);
2858 // Fill the map of faces generated from profile's boundary edges.
2859 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2860 TopTools_MapOfShape aMapFence;
2862 for (; anIter.More(); anIter.Next()) {
2863 const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
2865 if (!aLstOther.IsEmpty()) {
2866 TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
2868 for (; anOtherIt.More(); anOtherIt.Next()) {
2869 const TopoDS_Shape &anOtherShape = anOtherIt.Value();
2871 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2872 if (aMapFence.Add(anOtherShape)) {
2873 theGroups[GROUP_OTHER].Append(anOtherShape);
2875 } else if (anOtherShape.ShapeType() == TopAbs_SHELL) {
2876 if (aMapFence.Add(anOtherShape)) {
2877 TopExp_Explorer anExpSHF (anOtherShape, TopAbs_FACE);
2878 for (; anExpSHF.More(); anExpSHF.Next()) {
2879 theGroups[GROUP_OTHER].Append(anExpSHF.Current());
2883 // Only faces can be in Other group.
2894 //=======================================================================
2895 //function : CreateGroups1
2896 //purpose : auxiliary for Execute()
2897 //=======================================================================
2898 bool CreateGroups1 (const TopoDS_Shape &theProfile,
2899 BRepOffsetAPI_MakePipeShell &theSweep,
2900 GEOMImpl_IPipe *theCI)
2902 if (!theCI->GetGenerateGroups()) {
2908 TopTools_SequenceOfShape aGroups[5];
2910 if (!DoGroups1(theProfile, theSweep, aGroups)) {
2915 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2916 TopTools_IndexedMapOfShape anIndices;
2917 const TopoDS_Shape aResult = theSweep.Shape();
2919 TopExp::MapShapes(aResult, anIndices);
2921 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2926 StoreGroups(theCI, aGroupIds);
2931 //=======================================================================
2932 //function : DoGroups2
2933 //purpose : auxiliary for CreateGroups()
2934 //=======================================================================
2935 static bool DoGroups2(const TopoDS_Shape &theProfile,
2936 const TopoDS_Shape &thePath,
2937 BRepOffsetAPI_MakePipe &theSweep,
2938 TopTools_SequenceOfShape *theGroups)
2940 Standard_Boolean isDoSides = Standard_False;
2942 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2943 // Up and Down groups creation failure
2948 // Create Side1 and Side2 groups.
2949 const TopAbs_ShapeEnum aType = theProfile.ShapeType();
2950 TopoDS_Vertex aV[2];
2953 if (aType == TopAbs_EDGE) {
2954 TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
2955 } else { // aType == TopAbs_WIRE
2956 TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
2959 for (i = 0; i < 2; ++i) {
2960 if (aV[i].IsNull() == Standard_False) {
2961 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2962 TopTools_MapOfShape aMapFence;
2963 const Standard_Integer anIdSide =
2964 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2966 for (; anExpP.More(); anExpP.Next()) {
2967 const TopoDS_Shape aSideShape =
2968 theSweep.Generated(anExpP.Current(), aV[i]);
2970 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2971 if (aMapFence.Add(aSideShape)) {
2972 theGroups[anIdSide].Append(aSideShape);
2975 // Only edges can be is Side1 and Side2 groups.
2982 // Create Other group. Get boundary edges of the profile.
2983 TopTools_MapOfShape aMapBndEdges;
2984 TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
2986 for (; anExp.More(); anExp.Next()) {
2987 const TopoDS_Shape &anEdge = anExp.Current();
2989 if (!aMapBndEdges.Add(anEdge)) {
2990 aMapBndEdges.Remove(anEdge);
2994 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2995 TopTools_MapOfShape aMapFence;
2997 for (; anExpP.More(); anExpP.Next()) {
2998 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
3000 for (; anIter.More(); anIter.Next()) {
3001 const TopoDS_Shape anOtherShape =
3002 theSweep.Generated(anExpP.Current(), anIter.Key());
3004 if (anOtherShape.ShapeType() == TopAbs_FACE) {
3005 if (aMapFence.Add(anOtherShape)) {
3006 theGroups[GROUP_OTHER].Append(anOtherShape);
3009 // Only faces can be in Other group.
3019 //=======================================================================
3020 //function : CreateGroups
3021 //purpose : auxiliary for Execute()
3022 //=======================================================================
3023 static bool CreateGroups2(const TopoDS_Shape &theProfile,
3024 const TopoDS_Shape &thePath,
3025 BRepOffsetAPI_MakePipe &theSweep,
3026 GEOMImpl_IPipe *theCI)
3028 if (!theCI->GetGenerateGroups()) {
3034 TopTools_SequenceOfShape aGroups[5];
3036 if (!DoGroups2(theProfile, thePath, theSweep, aGroups)) {
3041 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
3042 TopTools_IndexedMapOfShape anIndices;
3043 const TopoDS_Shape aResult = theSweep.Shape();
3045 TopExp::MapShapes(aResult, anIndices);
3047 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
3052 StoreGroups(theCI, aGroupIds);
3057 //=======================================================================
3058 //function : Execute
3060 //=======================================================================
3061 Standard_Integer GEOMImpl_PipeDriver::Execute(Handle(TFunction_Logbook)& log) const
3063 if (Label().IsNull()) return 0;
3064 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
3065 Standard_Integer aType = aFunction->GetType();
3067 GEOMImpl_IPipe* aCI = 0;
3068 if (aType == PIPE_BASE_PATH)
3069 aCI = new GEOMImpl_IPipe (aFunction);
3070 else if (aType == PIPE_DIFFERENT_SECTIONS)
3071 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
3072 else if (aType == PIPE_SHELL_SECTIONS)
3073 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3074 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
3075 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3076 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
3077 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
3081 TopoDS_Wire aWirePath;
3082 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
3083 // working with path
3084 Handle(GEOM_Function) aRefPath = aCI->GetPath();
3085 TopoDS_Shape aShapePath = aRefPath->GetValue();
3087 if (aShapePath.IsNull()) {
3088 MESSAGE ("Driver : path is null");
3089 if (aCI) delete aCI;
3090 Standard_NullObject::Raise("MakePipe aborted : null path argument");
3095 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
3096 TopTools_SequenceOfShape anEdges;
3097 TopExp_Explorer anExp;
3101 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
3102 B.Add(W, anExp.Current());
3108 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
3109 aWirePath = TopoDS::Wire(aShapePath);
3113 if (aShapePath.ShapeType() == TopAbs_EDGE) {
3114 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
3115 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
3120 if (aCI) delete aCI;
3121 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
3124 // Check if it is possible to create groups.
3125 if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
3130 Standard_ConstructionError::Raise
3131 ("Can't create groups if the path is closed");
3135 TopoDS_Shape aShape;
3136 const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
3138 if (aType == PIPE_BASE_PATH) {
3139 Handle(GEOM_Function) aRefBase = aCI->GetBase();
3140 TopoDS_Shape aShapeBase;
3142 // Make copy to prevent modifying of base object 0020766 : EDF 1320
3143 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
3145 aShapeBase = Copy.Shape();
3147 if (aShapeBase.IsNull()) {
3148 if (aCI) delete aCI;
3149 Standard_NullObject::Raise("MakePipe aborted : null base argument");
3153 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
3154 aShapeBase.ShapeType() == TopAbs_WIRE)
3156 TopoDS_Wire aProfile;
3157 if (aShapeBase.ShapeType() == TopAbs_WIRE)
3158 aProfile = TopoDS::Wire(aShapeBase);
3162 BB.MakeWire(aProfile);
3163 BB.Add(aProfile, aShapeBase);
3166 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
3167 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
3168 if (FaceBuilder.IsDone())
3169 Sweep.SetMode(FaceBuilder.Face());
3170 Sweep.Add(aProfile);
3172 Standard_Boolean isDone = BuildPipeShell(Sweep);
3176 if (aCI) delete aCI;
3177 Standard_ConstructionError::Raise("MakePipeShell failed");
3180 aShape = Sweep.Shape(); //result is good
3182 if (!CreateGroups1(aProfile, Sweep, aCI)) {
3183 if (aCI) delete aCI;
3184 Standard_ConstructionError::Raise("Generate groups failure");
3189 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
3190 BRepOffsetAPI_MakePipe aMkPipe
3191 (aWirePath, aShapeBase, theBestMode, Standard_True);
3193 if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) {
3194 aShape = aMkPipe.Shape();
3196 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipe, aCI)) {
3197 if (aCI) delete aCI;
3198 Standard_ConstructionError::Raise("Generate groups failure");
3200 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
3201 // Try to use Descrete Trihedron mode.
3202 BRepOffsetAPI_MakePipe aMkPipeDescrete
3203 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron, Standard_True);
3205 if (aMkPipeDescrete.IsDone()) {
3206 aShape = aMkPipeDescrete.Shape();
3208 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
3209 if (aCI) delete aCI;
3210 Standard_ConstructionError::Raise("Generate groups failure");
3217 //building pipe with different sections
3218 else if (aType == PIPE_DIFFERENT_SECTIONS) {
3219 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
3220 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
3221 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
3222 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
3223 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
3224 Standard_Boolean isBySteps = aCIDS->GetIsBySteps();
3231 Standard_Integer nbBases = aBasesObjs->Length();
3232 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
3234 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
3235 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
3238 for (i = 1; i <= nbBases; i++) {
3239 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
3240 if (anItem.IsNull())
3242 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
3243 if (aRefBase.IsNull())
3245 if (aRefBase->GetValue().IsNull())
3248 aHSeqBases->Append(aRefBase->GetValue());
3250 for (i = 1; i <= nbLocs; i++) {
3251 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
3252 if (anItemLoc.IsNull())
3254 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
3255 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
3256 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
3259 aHSeqLocs->Append(aShapeLoc);
3263 Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
3264 Handle(TColStd_HArray1OfInteger) aGroups[5];
3266 if (isGenerateGroups) {
3270 aShape = CreatePipeWithDifferentSections
3271 (aWirePath, aHSeqBases, aHSeqLocs,
3272 aWithContact, aWithCorrect, isBySteps, pGroups);
3274 if (isGenerateGroups) {
3275 // Store created groups.
3276 GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
3278 StoreGroups(&aPipeDS, aGroups);
3282 //building pipe with shell sections
3283 else if (aType == PIPE_SHELL_SECTIONS) {
3284 aShape = CreatePipeForShellSections(aWirePath,aCI);
3287 //building pipe shell sections without path
3288 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
3289 aShape = CreatePipeShellsWithoutPath(aCI);
3292 //building a pipe with constant bi-normal along given vector
3293 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
3294 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
3302 if (aShape.IsNull()) return 0;
3304 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
3305 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
3307 if (aType != PIPE_BASE_PATH &&
3308 aType != PIPE_SHELLS_WITHOUT_PATH) {
3309 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
3310 if (anExpV.More()) {
3311 Standard_Real aVertMaxTol = -RealLast();
3312 for (; anExpV.More(); anExpV.Next()) {
3313 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
3314 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
3315 if (aTol > aVertMaxTol)
3318 aVertMaxTol += Precision::Confusion();
3320 TopTools_DataMapOfShapeListOfShape aMapModif;
3321 TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
3323 if (isGenerateGroups) {
3324 pMapModif = &aMapModif;
3327 TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
3328 (aShape, aVertMaxTol, Standard_True, pMapModif);
3330 if (isGenerateGroups && !aMapModif.IsEmpty()) {
3332 GEOMImpl_IPipe aCI(aFunction);
3333 Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
3334 { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
3335 aCI.GetGroupSide2(), aCI.GetGroupOther() };
3336 TopTools_IndexedMapOfShape anIndices;
3337 TopTools_IndexedMapOfShape aNewIndices;
3338 TopTools_SequenceOfShape aNewShapes[5];
3339 TopTools_MapOfShape aMapReplaced;
3340 TopTools_MapOfShape aMapGlued;
3341 Standard_Integer iGrp;
3344 TopExp::MapShapes(aShape, anIndices);
3345 TopExp::MapShapes(aNewShape, aNewIndices);
3347 for (iGrp = 0; iGrp < 5; ++iGrp) {
3348 if (aGroupIDs[iGrp].IsNull() == Standard_False) {
3349 const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
3350 const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
3352 for (i = aLower; i <= anUpper; ++i) {
3353 const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
3354 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
3356 if (aMapModif.IsBound(aSubShape)) {
3357 const TopTools_ListOfShape &aListModif =
3358 aMapModif.Find(aSubShape);
3359 TopTools_ListIteratorOfListOfShape anIter(aListModif);
3361 for (; anIter.More(); anIter.Next()) {
3362 const TopoDS_Shape &aNewShape = anIter.Value();
3364 if (aMapReplaced.Add(aNewShape)) {
3365 aNewShapes[iGrp].Append(aNewShape);
3367 // This is a glued shape. It means that it is internal
3368 // one and should be removed from groups later.
3369 aMapGlued.Add(aNewShape);
3373 // Shape is not modified.
3374 aNewShapes[iGrp].Append(aSubShape);
3380 if (!aMapGlued.IsEmpty()) {
3381 // Remove glued (internal) shapes from groups.
3382 for (iGrp = 0; iGrp < 5; ++iGrp) {
3383 Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
3385 for (i = 1; i < aNbShapes; ++i) {
3386 const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
3388 if (aMapGlued.Contains(aNewShape)) {
3389 aNewShapes[iGrp].Remove(i);
3397 // Store modified groups.
3398 Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
3400 if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
3401 Standard_ConstructionError::Raise("Generate groups failure");
3404 StoreGroups(&aCI, aNewGroupIDs);
3411 // Note: group indices should not be changed after the next call.
3412 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
3413 aFunction->SetValue(aRes);
3415 log->SetTouched(Label());
3419 //================================================================================
3421 * \brief Returns a name of creation operation and names and values of creation parameters
3423 //================================================================================
3425 bool GEOMImpl_PipeDriver::
3426 GetCreationInformation(std::string& theOperationName,
3427 std::vector<GEOM_Param>& theParams)
3429 if (Label().IsNull()) return 0;
3430 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
3431 Standard_Integer aType = function->GetType();
3434 case PIPE_BASE_PATH:
3436 theOperationName = "PIPE";
3437 GEOMImpl_IPipe aCI( function );
3438 AddParam( theParams, "Base Object", aCI.GetBase() );
3439 AddParam( theParams, "Path Object", aCI.GetPath() );
3442 case PIPE_BI_NORMAL_ALONG_VECTOR:
3444 theOperationName = "PIPE";
3445 GEOMImpl_IPipeBiNormal aCI( function );
3446 AddParam( theParams, "Base Object", aCI.GetBase() );
3447 AddParam( theParams, "Path Object", aCI.GetPath() );
3448 AddParam( theParams, "BiNormal", aCI.GetVector() );
3451 case PIPE_DIFFERENT_SECTIONS:
3453 theOperationName = "PIPE";
3454 GEOMImpl_IPipeDiffSect aCI( function );
3455 AddParam( theParams, "Bases", aCI.GetBases() );
3456 AddParam( theParams, "Locations", aCI.GetLocations() );
3457 AddParam( theParams, "Path", aCI.GetPath() );
3459 if (!aCI.GetIsBySteps()) {
3460 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3461 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3464 AddParam( theParams, "Step by step", aCI.GetIsBySteps() );
3467 case PIPE_SHELL_SECTIONS:
3469 theOperationName = "PIPE";
3470 GEOMImpl_IPipeShellSect aCI( function );
3471 AddParam( theParams, "Bases", aCI.GetBases() );
3472 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
3473 AddParam( theParams, "Locations", aCI.GetLocations() );
3474 AddParam( theParams, "Path", aCI.GetPath() );
3475 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3476 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3479 case PIPE_SHELLS_WITHOUT_PATH:
3481 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
3482 GEOMImpl_IPipeShellSect aCI( function );
3483 AddParam( theParams, "Bases", aCI.GetBases() );
3484 AddParam( theParams, "Locations", aCI.GetLocations() );
3494 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);