1 // Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <GEOMImpl_PipeDriver.hxx>
25 #include <GEOMImpl_IPipeDiffSect.hxx>
26 #include <GEOMImpl_IPipeShellSect.hxx>
27 #include <GEOMImpl_IPipeBiNormal.hxx>
28 #include <GEOMImpl_IPipe.hxx>
29 #include <GEOMImpl_IPipePath.hxx>
30 #include <GEOMImpl_GlueDriver.hxx>
31 #include <GEOMImpl_Types.hxx>
33 #include <GEOM_Function.hxx>
35 #include <GEOMUtils.hxx>
37 #include <ShapeAnalysis_FreeBounds.hxx>
38 #include <ShapeAnalysis_Edge.hxx>
39 #include <ShapeFix_Face.hxx>
40 #include <ShapeFix_Shell.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BRepBuilderAPI_Copy.hxx>
45 #include <BRepBuilderAPI_MakeFace.hxx>
46 #include <BRepBuilderAPI_MakeSolid.hxx>
47 #include <BRepBuilderAPI_MakeWire.hxx>
48 #include <BRepBuilderAPI_Sewing.hxx>
49 #include <BRepClass3d_SolidClassifier.hxx>
50 #include <BRepGProp.hxx>
51 #include <GeomFill_Trihedron.hxx>
52 #include <GeomFill_CorrectedFrenet.hxx>
53 #include <BRepOffsetAPI_MakePipe.hxx>
54 #include <BRepOffsetAPI_MakePipeShell.hxx>
55 #include <BRepOffsetAPI_ThruSections.hxx>
59 #include <TopExp_Explorer.hxx>
61 #include <TopoDS_Wire.hxx>
62 #include <TopoDS_Edge.hxx>
63 #include <TopoDS_Shape.hxx>
64 #include <TopoDS_Solid.hxx>
65 #include <TopoDS_Shell.hxx>
66 #include <TopoDS_Face.hxx>
67 #include <TopoDS_Compound.hxx>
68 #include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
69 #include <TopTools_SequenceOfShape.hxx>
70 #include <TopTools_HSequenceOfShape.hxx>
71 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
72 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
73 #include <TopTools_ListIteratorOfListOfShape.hxx>
74 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <GProp_GProps.hxx>
78 #include <GeomAPI_ProjectPointOnCurve.hxx>
79 #include <GeomAPI_Interpolate.hxx>
80 #include <Geom_TrimmedCurve.hxx>
81 #include <Geom_Plane.hxx>
82 #include <Geom_RectangularTrimmedSurface.hxx>
83 #include <Geom_BezierSurface.hxx>
84 #include <Geom_Line.hxx>
85 #include <Geom_Conic.hxx>
86 #include <Geom_BSplineCurve.hxx>
87 #include <Geom_BSplineSurface.hxx>
88 #include <GeomAdaptor_HCurve.hxx>
89 #include <GeomFill_BSplineCurves.hxx>
90 #include <GeomConvert_ApproxCurve.hxx>
91 #include <GeomConvert.hxx>
93 #include <TColgp_SequenceOfPnt.hxx>
94 #include <TColgp_HArray1OfPnt.hxx>
95 #include <TColgp_Array2OfPnt.hxx>
96 #include <TColStd_HSequenceOfTransient.hxx>
98 #include <Precision.hxx>
100 #include <Standard_NullObject.hxx>
101 #include <Standard_TypeMismatch.hxx>
102 #include <Standard_ConstructionError.hxx>
104 #include "utilities.h"
108 #define GROUP_SIDE1 2
109 #define GROUP_SIDE2 3
110 #define GROUP_OTHER 4
112 static const Standard_Real TolPipeSurf = 5.e-4;
114 static bool FillGroups(const TopTools_SequenceOfShape *theGroups,
115 const TopTools_IndexedMapOfShape &theIndices,
116 Handle(TColStd_HArray1OfInteger) *theGroupIds);
118 static void StoreGroups(GEOMImpl_IPipe *theCI,
119 Handle(TColStd_HArray1OfInteger) *theGroups);
121 // after OCCT improvement
122 static bool DoGroups1(const TopoDS_Shape &theProfile,
123 BRepOffsetAPI_MakePipeShell &theSweep,
124 TopTools_SequenceOfShape *theGroups);
126 static bool CreateGroups1(const TopoDS_Shape &theProfile,
127 BRepOffsetAPI_MakePipeShell &theSweep,
128 GEOMImpl_IPipe *theCI);
130 //=======================================================================
133 //=======================================================================
134 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
136 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
140 //=======================================================================
141 //function : GEOMImpl_PipeDriver
143 //=======================================================================
144 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
148 //=======================================================================
149 //function : EvaluateBestSweepMode
150 //purpose : auxiliary for right call of MakePipe and MakePipeShell
151 //=======================================================================
152 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
154 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
156 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
157 for (; Explo.More(); Explo.Next())
159 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
160 Standard_Real fpar, lpar;
161 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
162 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
163 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
165 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
166 aCorrFrenet->SetCurve(GAHcurve);
167 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
168 if (aMode == GeomFill_IsDiscreteTrihedron)
173 if (aMode == GeomFill_IsCorrectedFrenet)
180 //=======================================================================
181 //function : BuildPipeShell
182 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
183 // mode. Returns Standard_True if the building is done successfully.
184 //=======================================================================
185 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
187 // Commented out for bos #20438
188 //theBuilder.SetForceApproxC1(Standard_True);
192 Standard_Boolean isDone = theBuilder.IsDone();
195 theBuilder.ErrorOnSurface() > TolPipeSurf) {
196 // Try to use Descrete Trihedron mode.
197 theBuilder.SetDiscreteMode();
199 isDone = theBuilder.IsDone();
205 //=======================================================================
206 //function : FillForOtherEdges
207 //purpose : auxiliary for CreatePipeForShellSections()
208 //=======================================================================
209 static bool FillForOtherEdges(const TopoDS_Shape& F1,
210 const TopoDS_Shape& E1,
211 const TopoDS_Shape& V1,
212 TopTools_IndexedDataMapOfShapeShape& FF)
214 // find other pairs for vertexes and edges
215 // creating map of vertex edges for both faces
216 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
217 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
218 if (!FF.Contains(F1)) MESSAGE(" FillForOtherEdges: map FF not contains key F1");
219 if (!FF.Contains(E1)) MESSAGE(" FillForOtherEdges: map FF not contains key E1");
220 if (!FF.Contains(V1)) MESSAGE(" FillForOtherEdges: map FF not contains key V1");
221 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
222 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
223 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
224 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
225 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
227 TopoDS_Edge ES1 = TopoDS::Edge(E1);
228 TopoDS_Edge ES2 = TopoDS::Edge(E2);
229 TopoDS_Shape VS1 = V1;
230 TopoDS_Shape VS2 = V2;
232 ShapeAnalysis_Edge sae;
234 if (!aMapVertEdge1.Contains(VS1)) MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
235 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
236 TopTools_ListIteratorOfListOfShape anIter1(aList1);
237 if (anIter1.Value().IsSame(ES1)) {
240 if (!aMapVertEdge2.Contains(VS2)) MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
241 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
242 TopTools_ListIteratorOfListOfShape anIter2(aList2);
243 if (anIter2.Value().IsSame(ES2)) {
246 ES1 = TopoDS::Edge(anIter1.Value());
247 ES2 = TopoDS::Edge(anIter2.Value());
248 if (!FF.Contains(ES1)) {
251 if (VS1.IsSame(sae.FirstVertex(ES1)))
252 VS1 = sae.LastVertex(ES1);
254 VS1 = sae.FirstVertex(ES1);
255 if (VS2.IsSame(sae.FirstVertex(ES2)))
256 VS2 = sae.LastVertex(ES2);
258 VS2 = sae.FirstVertex(ES2);
261 if (!FF.Contains(VS1)) {
269 //=======================================================================
270 //function : FillCorrespondingEdges
271 //purpose : auxiliary for CreatePipeForShellSections()
272 //=======================================================================
273 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
274 const TopoDS_Shape& FS2,
275 const TopoDS_Vertex& aLoc1,
276 const TopoDS_Vertex& aLoc2,
277 const TopoDS_Wire& aWirePath,
278 TopTools_IndexedDataMapOfShapeShape& FF)
280 // find corresponding edges
281 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
282 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
283 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
284 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
285 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
286 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
287 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
288 if (theBestMode == GeomFill_IsDiscreteTrihedron)
289 aBuilder.SetDiscreteMode();
290 aBuilder.Add(aWire1, aLoc1);
291 aBuilder.Add(aWire2, aLoc2);
292 if (!aBuilder.IsReady()) {
296 BuildPipeShell(aBuilder);
298 TopoDS_Shape aShape = aBuilder.Shape();
299 ShapeAnalysis_Edge sae;
300 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
301 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
302 TopTools_MapOfShape Vs1,Vs2;
304 exp.Init(FS1, TopAbs_EDGE);
305 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
306 TopoDS_Vertex V11 = sae.FirstVertex(E1);
307 TopoDS_Vertex V21 = sae.LastVertex(E1);
308 gp_Pnt P11 = BRep_Tool::Pnt(V11);
309 gp_Pnt P21 = BRep_Tool::Pnt(V21);
310 // find corresponding vertexes from created shape
311 TopoDS_Vertex VN11,VN21;
312 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
313 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
314 gp_Pnt P = BRep_Tool::Pnt(V);
315 if (P.Distance(P11)<tol) {
318 if (P.Distance(P21)<tol) {
322 // find edge contains VN11 and VN21 and corresponding vertexes
323 TopoDS_Vertex VN12,VN22;
324 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
325 TopoDS_Shape F = exp.Current();
326 TopExp_Explorer expe;
328 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
329 TopoDS_Edge E = TopoDS::Edge(expe.Current());
330 TopoDS_Vertex VF = sae.FirstVertex(E);
331 TopoDS_Vertex VL = sae.LastVertex(E);
332 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
338 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
339 TopoDS_Edge E = TopoDS::Edge(expe.Current());
340 TopoDS_Vertex VF = sae.FirstVertex(E);
341 TopoDS_Vertex VL = sae.LastVertex(E);
342 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
344 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
346 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
348 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
354 // find vertexes from FS2 corresponded to VN12 and VN22
355 // and find edge from FS2 contains V12 and V22,
356 // this edge will be corresponded to edge E1
357 TopoDS_Vertex V12,V22;
358 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
359 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
361 TopExp_Explorer expe;
362 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
363 TopoDS_Edge E = TopoDS::Edge(expe.Current());
364 TopoDS_Vertex VF = sae.FirstVertex(E);
365 TopoDS_Vertex VL = sae.LastVertex(E);
366 gp_Pnt PF = BRep_Tool::Pnt(VF);
367 gp_Pnt PL = BRep_Tool::Pnt(VL);
368 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
374 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
385 // find other pairs for vertexes and edges
386 // creating map of vertex edges for both faces
387 return FillForOtherEdges(FS1,E1,V21,FF);
392 //=======================================================================
393 //function : FillCorrespondingEdges
394 //purpose : auxiliary for CreatePipeShellsWithoutPath()
395 //=======================================================================
396 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
397 const TopoDS_Shape& FS2,
398 const TopoDS_Vertex& aLoc1,
399 const TopoDS_Vertex& aLoc2,
400 TopTools_IndexedDataMapOfShapeShape& FF)
402 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
403 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
406 ShapeAnalysis_Edge sae;
407 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
408 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
409 TopTools_MapOfShape Vs1,Vs2;
411 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
414 TopExp_Explorer exp1;
415 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
416 E1 = TopoDS::Edge(exp1.Current());
417 TopoDS_Vertex V1 = sae.FirstVertex(E1);
418 TopoDS_Vertex V2 = sae.LastVertex(E1);
419 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
420 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
421 if (P1.Distance(Ptmp1)<tol) {
425 if (P1.Distance(Ptmp2)<tol) {
432 TopoDS_Vertex VE21,VE22;
434 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
435 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
436 TopoDS_Vertex V1 = sae.FirstVertex(E);
437 TopoDS_Vertex V2 = sae.LastVertex(E);
438 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
439 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
440 if (P2.Distance(Ptmp1)<tol) {
452 if (P2.Distance(Ptmp2)<tol) {
466 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
467 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
468 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
469 gp_Vec aDir1(PV21,PE21);
470 gp_Vec aDir2(PV21,PE22);
471 double ang1 = aDir.Angle(aDir1);
472 double ang2 = aDir.Angle(aDir2);
473 if (fabs(ang1)<fabs(ang2)) {
486 // find other pairs for vertexes and edges
487 return FillForOtherEdges(FS1,E1,V21,FF);
490 //=======================================================================
491 //function : FindNextPairOfFaces
492 //purpose : auxiliary for CreatePipeForShellSections()
493 //=======================================================================
494 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
495 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
496 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
497 TopTools_IndexedDataMapOfShapeShape& FF,
500 TopExp_Explorer anExp;
501 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
502 TopoDS_Shape E1 = anExp.Current();
503 if (!FF.Contains(E1)) {
505 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
507 if (!FF.Contains(E1)) MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
508 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
509 TopExp_Explorer anExpV;
510 anExpV.Init(E1, TopAbs_VERTEX);
511 TopoDS_Shape V1 = anExpV.Current();
512 if (!FF.Contains(V1)) {
514 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
517 if (!aMapEdgeFaces1.Contains(E1)) MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
518 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
519 if (aList1.Extent()<2)
521 TopTools_ListIteratorOfListOfShape anIter(aList1);
522 if (anIter.Value().IsEqual(aCurFace)) {
525 TopoDS_Shape F1other = anIter.Value();
526 if (FF.Contains(F1other))
529 if (!FF.Contains(aCurFace)) MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
530 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
531 if (!aMapEdgeFaces2.Contains(E2)) MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
532 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
533 if (aList2.Extent()<2) {
535 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
537 TopTools_ListIteratorOfListOfShape anIter2(aList2);
538 if (anIter2.Value().IsEqual(F2)) {
541 TopoDS_Shape F2other = anIter2.Value();
542 FF.Add(F1other,F2other);
544 // add pairs of edges to FF
545 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
548 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not map other edges");
551 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
555 //=======================================================================
556 //function : FindFirstPairFaces
557 //purpose : auxiliary for Execute()
558 //=======================================================================
559 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
560 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
561 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
563 // check if vertexes are sub-shapes of sections
564 gp_Pnt P1 = BRep_Tool::Pnt(V1);
565 gp_Pnt P2 = BRep_Tool::Pnt(V2);
566 TopoDS_Vertex V1new,V2new;
568 double mindist = 1.e10;
569 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
570 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
571 gp_Pnt P = BRep_Tool::Pnt(V);
572 double dist = P1.Distance(P);
579 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
580 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
581 gp_Pnt P = BRep_Tool::Pnt(V);
582 double dist = P2.Distance(P);
589 // replace vertexes if it is needed
590 if (!V1.IsSame(V1new)) {
592 P1 = BRep_Tool::Pnt(V1);
593 MESSAGE (" replace V1");
596 MESSAGE (" not replace V1");
597 if (!V2.IsSame(V2new)) {
599 P2 = BRep_Tool::Pnt(V2);
600 MESSAGE (" replace V2");
603 MESSAGE (" not replace V2");
605 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
606 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
607 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
608 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
610 if (!aMapVertFaces1.Contains(V1))
611 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
612 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
613 TopTools_ListIteratorOfListOfShape anIter1(aList1);
614 FS1 = anIter1.Value();
616 double x1=0., y1=0., z1=0.;
618 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
619 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
620 gp_Pnt P = BRep_Tool::Pnt(V);
626 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
628 TColgp_SequenceOfPnt Ps;
629 TopTools_SequenceOfShape Fs;
630 if (!aMapVertFaces2.Contains(V2))
631 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
632 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
633 TopTools_ListIteratorOfListOfShape anIter2(aList2);
634 for (; anIter2.More(); anIter2.Next()) {
635 TopoDS_Shape F = anIter2.Value();
636 double x2=0., y2=0., z2=0.;
638 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
639 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
640 gp_Pnt P = BRep_Tool::Pnt(V);
646 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
653 double MinAng = M_PI;
655 for (; i<=Fs.Length(); i++) {
656 gp_Vec tmpDir(PM1,Ps(i));
657 double ang = fabs(aDir.Angle(tmpDir));
666 //=======================================================================
667 //function : RemoveFaces
668 //purpose : This function returns theShapeFrom without faces of the shape
669 // theFacesToRm. It returns a shell if theShapeFrom is a solid or
670 // a compound otherwise. Auxiliary for CreatePipeWithDifferentSections
672 //=======================================================================
673 static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom,
674 const TopoDS_Shape &theFacesToRm)
676 TopTools_IndexedMapOfShape aMapFaces;
677 TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE);
678 BRep_Builder aBuilder;
679 TopoDS_Shape aResult;
681 if (theShapeFrom.ShapeType() == TopAbs_SOLID) {
683 aBuilder.MakeShell(TopoDS::Shell(aResult));
686 aBuilder.MakeCompound(TopoDS::Compound(aResult));
689 TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces);
691 for (; anExp.More(); anExp.Next()) {
692 const TopoDS_Shape &aFace = anExp.Current();
694 if (!aMapFaces.Contains(aFace)) {
695 aBuilder.Add(aResult, aFace);
702 //=======================================================================
703 //function : makeSolid
704 //purpose : auxiliary for CreatePipeWithDifferentSections
705 //=======================================================================
706 Standard_Boolean makeSolid(
707 BRepOffsetAPI_MakePipeShell aBuilder,
708 const TopoDS_Shape& aSh1,
709 const TopoDS_Shape& aSh2,
710 TopoDS_Shape& aShape)
712 Standard_Boolean isDone = Standard_True;
713 Standard_Integer nbPlanar = 0;
714 if (aSh1.ShapeType() == TopAbs_FACE && aSh2.ShapeType() == TopAbs_FACE)
716 Handle(Geom_Surface) aS = BRep_Tool::Surface(TopoDS::Face(aSh1));
717 if (aS->IsKind(STANDARD_TYPE(Geom_Plane))) {
720 else if (aS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
721 Handle(Geom_RectangularTrimmedSurface) aTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
722 if (aTS->BasisSurface()->IsKind(STANDARD_TYPE(Geom_Plane))) {
726 aS = BRep_Tool::Surface(TopoDS::Face(aSh2));
727 if (aS->IsKind(STANDARD_TYPE(Geom_Plane))) {
730 else if (aS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
731 Handle(Geom_RectangularTrimmedSurface) aTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
732 if (aTS->BasisSurface()->IsKind(STANDARD_TYPE(Geom_Plane))) {
738 TopoDS_Shape aPipe = aBuilder.Shape();
739 // make sewing for result
740 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
741 Standard_Real aTol = Precision::Confusion();
742 aSewing->SetTolerance(aTol);
743 aSewing->SetFaceMode(Standard_True);
744 aSewing->SetFloatingEdgesMode(Standard_False);
745 aSewing->SetNonManifoldMode(Standard_False);
746 TopExp_Explorer anExp;
747 for (anExp.Init(aPipe, TopAbs_FACE); anExp.More(); anExp.Next()) {
748 aSewing->Add(anExp.Current());
753 aShape = aSewing->SewedShape();
754 if (aShape.ShapeType() == TopAbs_SHELL) {
756 BRepBuilderAPI_MakeSolid aMkSolid;
757 aMkSolid.Add(TopoDS::Shell(aShape));
758 if (!aMkSolid.IsDone()) {
759 isDone = Standard_False;
762 TopoDS_Solid aSolid = aMkSolid.Solid();
763 BRepClass3d_SolidClassifier aSC(aSolid);
764 aSC.PerformInfinitePoint(Precision::Confusion());
765 if (aSC.State() == TopAbs_IN) {
766 aShape = aSolid.Reversed();
774 isDone = Standard_False;
778 isDone = Standard_False;
781 isDone = aBuilder.MakeSolid();
783 aShape = aBuilder.Shape();
789 //=======================================================================
790 //function : CreatePipeWithDifferentSections
792 //=======================================================================
793 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
794 (const TopoDS_Wire &theWirePath,
795 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
796 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
797 const Standard_Boolean theWithContact,
798 const Standard_Boolean theWithCorrect,
799 const Standard_Boolean IsBySteps,
800 Handle(TColStd_HArray1OfInteger) *theGroups)
804 TopoDS_Wire aWirePath = theWirePath;
806 Standard_Integer nbBases = theHSeqBases->Length();
807 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
809 if (nbLocs && nbLocs != nbBases) {
810 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
813 TopTools_SequenceOfShape aSeqBases;
814 TopTools_SequenceOfShape aSeqLocs;
815 TopTools_SequenceOfShape aSeqFaces;
816 Standard_Boolean NeedCreateSolid = Standard_False;
818 Standard_Integer i = 1;
819 for (i = 1; i <= nbBases; i++) {
820 if (theHSeqBases->Value(i).IsNull())
823 // Make copy to prevent modifying of base object 0020766 : EDF 1320
824 TopoDS_Shape aShapeBase;
825 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
827 aShapeBase = Copy.Shape();
829 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
831 //if for section was specified face with a few wires then a few
832 // pipes were build and make solid
833 if (aTypeBase == TopAbs_SHELL) {
834 // create wire as boundary contour if shell is no closed
835 // get free boundary shapes
836 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
837 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
838 TopExp_Explorer anExp;
840 Standard_Integer NbWires = 0;
841 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
843 aWire = anExp.Current();
847 Standard_ConstructionError::Raise("Bad shell is used as section ");
849 NeedCreateSolid = Standard_True;
850 aSeqFaces.Append(aShapeBase);
851 aSeqBases.Append(aWire);
853 else if (aTypeBase == TopAbs_FACE) {
854 NeedCreateSolid = Standard_True;
855 //for case one path should be used other type function
856 aSeqFaces.Append(aShapeBase);
857 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
858 for (; aExpW.More(); aExpW.Next()) {
859 TopoDS_Shape aWireProf = aExpW.Current();
860 aSeqBases.Append(aWireProf);
863 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
864 aSeqBases.Append(aShapeBase);
866 else if (aTypeBase == TopAbs_EDGE) {
867 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
868 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
869 aSeqBases.Append(aWireProf);
872 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
873 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
875 aSeqLocs.Append(aShapeLoc);
879 nbLocs = aSeqLocs.Length();
882 TopTools_SequenceOfShape Edges;
884 // we have to check that each location shape is a vertex from
885 // path and update aSeqLocs if it is needed (and possible)
886 TColgp_SequenceOfPnt PLocs;
887 for (i=1; i<=nbLocs; i++) {
888 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
889 PLocs.Append(BRep_Tool::Pnt(V));
891 //TopTools_SequenceOfShape Edges;
892 TopExp_Explorer anExp;
893 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
894 Edges.Append(anExp.Current());
896 int nbEdges = Edges.Length();
897 ShapeAnalysis_Edge sae;
898 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
899 double tol = BRep_Tool::Tolerance(edge);
900 TopoDS_Vertex VF = sae.FirstVertex(edge);
901 gp_Pnt PF = BRep_Tool::Pnt(VF);
902 if (PF.Distance(PLocs.First()) > tol) {
903 Standard_ConstructionError::Raise
904 ("First location shapes is not coincided with first vertex of aWirePath");
906 aSeqLocs.ChangeValue(1) = VF;
907 edge = TopoDS::Edge(Edges.Last());
908 tol = BRep_Tool::Tolerance(edge);
909 TopoDS_Vertex VL = sae.LastVertex(edge);
910 gp_Pnt PL = BRep_Tool::Pnt(VL);
911 if (PL.Distance(PLocs.Last()) > tol) {
912 Standard_ConstructionError::Raise
913 ("Last location shapes is not coincided with last vertex of aWirePath");
915 aSeqLocs.ChangeValue(nbLocs) = VL;
917 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
918 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
919 tol = BRep_Tool::Tolerance(edge);
920 TopoDS_Vertex V1 = sae.FirstVertex(E);
921 TopoDS_Vertex V2 = sae.LastVertex(E);
922 gp_Pnt P1 = BRep_Tool::Pnt(V1);
923 gp_Pnt P2 = BRep_Tool::Pnt(V2);
924 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
925 aSeqLocs.ChangeValue(jcurr) = V2;
929 // find distance between E and aLocs(jcurr)
931 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
932 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
933 if (PPCurve.NbPoints()>0 &&
934 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
935 double param = PPCurve.Parameter(1);
938 // split current edge
939 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
940 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
945 if (Pfp.Distance(P1)<tol) {
946 B.MakeEdge(E1,tc1,tol);
948 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
949 B.Add(E1,TopoDS::Vertex(tmpV));
950 B.MakeEdge(E2,tc2,tol);
951 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
952 B.Add(E2,TopoDS::Vertex(tmpV));
956 B.MakeEdge(E1,tc2,tol);
957 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
958 B.Add(E1,TopoDS::Vertex(tmpV));
961 B.MakeEdge(E2,tc1,tol);
963 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
964 B.Add(E2,TopoDS::Vertex(tmpV));
969 Edges.InsertAfter(i-1,E1);
970 Edges.InsertAfter(i,E2);
974 if (nbEdges<Edges.Length()) {
975 // one of edges was split => we have to update WirePath
979 for (i=1; i<=Edges.Length(); i++) {
980 B.Add(W,TopoDS::Edge(Edges.Value(i)));
986 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
989 // Fill SplitEdgeNums and SplitLocNums with intermediate location indices
990 // and corresponding edge indices.
991 Standard_Integer i = 1;
996 for (j = 2; j < aSeqLocs.Length(); j++) {
997 SplitLocNums.Append(j);
998 aVert = TopoDS::Vertex(aSeqLocs.Value(j));
999 aP = BRep_Tool::Pnt(aVert);
1001 while (i < Edges.Length()) {
1004 TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i));
1005 Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
1006 Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp);
1009 aC->D0(aLp, aPLast);
1012 if (aP.Distance(aPLast) < aTol) {
1013 SplitEdgeNums.Append(i - 1);
1019 // check curvature of wire for condition that
1020 // max summary angle between directions along
1021 // wire path must be < 4*PI. If not - split wire
1022 // and seguences of shapes, perform pipe for each
1023 // and make sewing after that
1028 if ( Edges.Length() > 0 ) {
1029 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
1032 SumAng = fabs(Vec1.Angle(Vec2));
1037 for (i=2; i<=Edges.Length(); i++) {
1038 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
1039 double tol = BRep_Tool::Tolerance(edge);
1040 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1042 double ang = fabs(Vec1.Angle(Vec2));
1044 if (SumAng>4*M_PI) {
1046 SplitEdgeNums.Append(i-1);
1048 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
1049 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
1050 gp_Pnt P = BRep_Tool::Pnt(aVert);
1051 if (P1.Distance(P) < tol) {
1052 SplitLocNums.Append(j);
1063 bool isCreateGroups = (theGroups != NULL);
1065 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
1066 TopTools_SequenceOfShape aSeqRes;
1067 TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
1068 Standard_Integer iGrp;
1069 int nn, num1 = 1, num2 = 1;
1070 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
1071 // create wirepath and sequences of shapes
1075 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
1076 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1078 num1 = SplitEdgeNums.Value(nn) + 1;
1079 TopTools_SequenceOfShape aTmpSeqBases;
1080 TopTools_SequenceOfShape aTmpSeqLocs;
1081 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
1082 aTmpSeqBases.Append(aSeqBases.Value(i));
1083 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1085 num2 = SplitLocNums.Value(nn);
1087 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1088 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1089 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1090 aBuilder.SetDiscreteMode();
1091 Standard_Integer nbShapes = aTmpSeqBases.Length();
1092 for (i=1; i<=nbShapes; i++) {
1093 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1094 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1095 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1097 if (!aBuilder.IsReady()) {
1098 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1101 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1103 if (isDone && NeedCreateSolid && nn == 1) {
1104 // Make solid for the first step.
1105 isDone = aBuilder.MakeSolid();
1109 Standard_ConstructionError::Raise("Pipe construction failure");
1112 TopoDS_Shape resShape = aBuilder.Shape();
1114 if (NeedCreateSolid && nn == 1) {
1115 // Remove top lid from the result.
1116 resShape = RemoveFaces(resShape, aBuilder.LastShape());
1119 aSeqRes.Append(resShape);
1122 if (isCreateGroups) {
1124 TopTools_SequenceOfShape aGroups[5];
1126 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1127 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1128 Standard_ConstructionError::Raise("Generate groups failure");
1131 // Get shapes from all groups.
1132 for (iGrp = 0; iGrp < 5; ++iGrp) {
1133 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1137 // create wirepath and sequences of shapes for last part
1141 for (i=num1; i<=Edges.Length(); i++) {
1142 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1144 TopTools_SequenceOfShape aTmpSeqBases;
1145 TopTools_SequenceOfShape aTmpSeqLocs;
1146 for (i=num2; i<=aSeqLocs.Length(); i++) {
1147 aTmpSeqBases.Append(aSeqBases.Value(i));
1148 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1150 // make pipe for last part
1151 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1152 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1153 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1154 aBuilder.SetDiscreteMode();
1155 Standard_Integer nbShapes = aTmpSeqBases.Length();
1156 for (i=1; i<=nbShapes; i++) {
1157 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1158 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1159 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1161 if (!aBuilder.IsReady()) {
1162 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1165 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1167 if (isDone && NeedCreateSolid) {
1168 isDone = aBuilder.MakeSolid();
1172 Standard_ConstructionError::Raise("Pipe construction failure");
1175 TopoDS_Shape resShape = aBuilder.Shape();
1177 if (NeedCreateSolid) {
1178 // Remove bottom lid from the result.
1179 resShape = RemoveFaces(resShape, aBuilder.FirstShape());
1182 aSeqRes.Append(resShape);
1185 if (isCreateGroups) {
1187 TopTools_SequenceOfShape aGroups[5];
1189 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1190 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1191 Standard_ConstructionError::Raise("Generate groups failure");
1194 // Get shapes from all groups.
1195 for (iGrp = 0; iGrp < 5; ++iGrp) {
1196 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1200 // make sewing for result
1201 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1202 aSewing->SetTolerance(Precision::Confusion());
1203 aSewing->SetFaceMode(Standard_True);
1204 aSewing->SetFloatingEdgesMode(Standard_False);
1205 aSewing->SetNonManifoldMode(Standard_False);
1206 for (i=1; i<=aSeqRes.Length(); i++) {
1207 aSewing->Add(aSeqRes.Value(i));
1210 aShape = aSewing->SewedShape();
1212 if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) {
1214 BRepBuilderAPI_MakeSolid aMkSolid;
1216 aMkSolid.Add(TopoDS::Shell(aShape));
1218 if (!aMkSolid.IsDone()) {
1219 Standard_ConstructionError::Raise("Can't create solid pipe");
1222 TopoDS_Solid aSolid = aMkSolid.Solid();
1223 BRepClass3d_SolidClassifier aSC(aSolid);
1225 aSC.PerformInfinitePoint(Precision::Confusion());
1227 if (aSC.State() == TopAbs_IN) {
1228 aShape = aSolid.Reversed();
1234 if (isCreateGroups) {
1235 // Replase Group shapes by modified ones.
1236 TopTools_SequenceOfShape aSeqGroups[5];
1239 for (iGrp = 0; iGrp < 5; ++iGrp) {
1241 for (i = 1; i <= aSeqRes.Length(); ++i) {
1242 if (iGrp == GROUP_DOWN && i > 1) {
1243 // For DOWN group we use only the first pipe.
1247 if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
1248 // For UP group we use only the last pipe.
1252 const TopTools_SequenceOfShape &aShapes =
1253 aMapResGroups[iGrp].Find(aSeqRes.Value(i));
1256 // For each sub-shape of pipe
1257 for (j = 1; j <= aShapes.Length(); ++j) {
1258 const TopoDS_Shape &aGrpShape = aShapes.Value(j);
1260 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1261 // Use the shape modified by sewing.
1262 const TopoDS_Shape &aModifGrpShape =
1263 aSewing->ModifiedSubShape(aGrpShape);
1265 aSeqGroups[iGrp].Append(aModifGrpShape);
1267 // Use the shape as it is.
1268 aSeqGroups[iGrp].Append(aGrpShape);
1275 TopTools_IndexedMapOfShape anIndices;
1277 TopExp::MapShapes(aShape, anIndices);
1279 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1280 Standard_ConstructionError::Raise("Generate groups failure");
1285 // old implementation without splitting
1287 // Generally, we should better use BRepOffsetAPI_ThruSections algorithm if
1288 // 1) the path is a polyline, and
1289 // 2) all break points of the path have correspondent sections
1290 bool doThruSections = false;
1291 if (!theWithContact && !theWithCorrect && theGroups == NULL &&
1292 nbBases == Edges.Length() + 1) {
1293 doThruSections = true;
1294 // check if all edges are lines
1295 Standard_Real aFP, aLP;
1296 for (int ie = 1; ie <= Edges.Length() && doThruSections; ie++) {
1297 TopoDS_Edge anE = TopoDS::Edge(Edges.Value(ie));
1298 Handle(Geom_Curve) aC = BRep_Tool::Curve(anE, aFP, aLP);
1300 while(aC->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
1301 Handle(Geom_TrimmedCurve) aTc = Handle(Geom_TrimmedCurve)::DownCast(aC);
1302 aC = aTc->BasisCurve();
1304 if (!aC->IsKind(STANDARD_TYPE(Geom_Line)))
1305 doThruSections = false;
1310 if (doThruSections) {
1311 BRepOffsetAPI_ThruSections aBuilder (NeedCreateSolid, Standard_True, Precision::Confusion()*10.0);
1312 aBuilder.CheckCompatibility(Standard_False);
1314 for (int ibase = 1; ibase <= nbBases; ibase++) {
1315 TopoDS_Shape aBase = aSeqBases.Value(ibase);
1316 aBuilder.AddWire(TopoDS::Wire(aBase));
1320 aShape = aBuilder.Shape();
1323 // old implementation without splitting
1324 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1325 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1326 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1327 aBuilder.SetDiscreteMode();
1329 Standard_Integer nbShapes = aSeqBases.Length();
1330 Standard_Integer step = nbShapes/nbBases;
1332 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1333 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1335 Standard_Integer ind =0;
1336 Standard_Real aTolConf = Precision::Confusion();
1337 Standard_Real aTolAng = Precision::Angular();
1339 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1340 TopTools_SequenceOfShape usedBases;
1341 Standard_Integer j = 1;
1342 for (; j <= nbBases; j++) {
1343 ind = i + (j-1)*step;
1344 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1345 usedBases.Append(aWireProf);
1347 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1348 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1349 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1352 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1354 if (!aBuilder.IsReady()) {
1355 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1358 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1360 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1363 if (NeedCreateSolid) {
1364 TopoDS_Shape aSh1 = aSeqFaces.Value(1);
1365 TopoDS_Shape aSh2 = aSeqFaces.Value(aSeqFaces.Length());
1366 isDone = makeSolid(aBuilder, aSh1, aSh2, aShape);
1369 aShape = aBuilder.Shape();
1374 Standard_ConstructionError::Raise("Pipe construction failure");
1377 if (isCreateGroups) {
1379 TopTools_SequenceOfShape aSeqGroups[5];
1381 TopoDS_Shape aProfile = usedBases.Value(1);
1382 if (!DoGroups1(aProfile, aBuilder, aSeqGroups)) {
1383 Standard_ConstructionError::Raise("Generate groups failure");
1387 //Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1388 TopTools_IndexedMapOfShape anIndices;
1389 const TopoDS_Shape aResult = aBuilder.Shape();
1391 TopExp::MapShapes(aResult, anIndices);
1393 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1394 Standard_ConstructionError::Raise("Generate groups failure");
1397 aSeqFaces.Append(aShape);
1398 for (j = 1; j <=usedBases.Length(); j++)
1399 aBuilder.Delete(usedBases.Value(j));
1407 //=======================================================================
1408 //function : CreatePipeForShellSections
1409 //purpose : auxiliary for Execute()
1410 //=======================================================================
1411 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1412 GEOMImpl_IPipe* aCI)
1417 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1418 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1419 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1420 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1421 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1422 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1423 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1425 Standard_Integer nbBases = aBasesObjs->Length(),
1426 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1427 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1429 if (nbLocs != nbBases) {
1430 if (aCI) delete aCI;
1431 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1433 if (nbSubBases && nbSubBases != nbBases) {
1434 if (aCI) delete aCI;
1435 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1438 TopTools_SequenceOfShape VLocs;
1439 for (i=1; i<=nbBases; i++) {
1440 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1441 if (anItemLoc.IsNull())
1443 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1444 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1445 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1447 VLocs.Append(aShapeLoc);
1449 nbLocs = VLocs.Length();
1450 if (nbLocs != nbBases) {
1451 if (aCI) delete aCI;
1452 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1454 // split wire path by location points
1455 TColgp_SequenceOfPnt PLocs;
1456 for (i=1; i<=nbLocs; i++) {
1457 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1458 PLocs.Append(BRep_Tool::Pnt(V));
1461 TopTools_SequenceOfShape Edges;
1462 TopTools_SequenceOfShape Wires;
1463 ShapeAnalysis_Edge sae;
1466 TopExp_Explorer anExp;
1467 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1468 Edges.Append(anExp.Current());
1470 Standard_Integer Num1 = 0;
1471 Standard_Integer Num2 = 0;
1472 for (i=1; i<=Edges.Length(); i++) {
1473 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1474 double tol = BRep_Tool::Tolerance(E);
1475 TopoDS_Vertex V1 = sae.FirstVertex(E);
1476 TopoDS_Vertex V2 = sae.LastVertex(E);
1477 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1478 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1479 if (P1.Distance(PLocs.First()) < tol) {
1482 if (P2.Distance(PLocs.Last()) < tol) {
1486 if (Num1>0 && Num2>0) {
1489 for (i=Num1; i<=Num2; i++) {
1490 B.Add(W,Edges.Value(i));
1495 Wires.Append(aWirePath);
1499 TopExp_Explorer anExp;
1500 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1501 Edges.Append(anExp.Current());
1503 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1504 double tol = BRep_Tool::Tolerance(edge);
1505 TopoDS_Vertex VF = sae.FirstVertex(edge);
1506 gp_Pnt PF = BRep_Tool::Pnt(VF);
1507 if (PF.Distance(PLocs.First()) > tol) {
1508 if (aCI) delete aCI;
1509 Standard_ConstructionError::Raise
1510 ("First location shapes is not coincided with first vertex of aWirePath");
1512 VLocs.ChangeValue(1) = VF;
1513 edge = TopoDS::Edge(Edges.Last());
1514 tol = BRep_Tool::Tolerance(edge);
1515 TopoDS_Vertex VL = sae.LastVertex(edge);
1516 gp_Pnt PL = BRep_Tool::Pnt(VL);
1517 if (PL.Distance(PLocs.Last()) > tol) {
1518 if (aCI) delete aCI;
1519 Standard_ConstructionError::Raise
1520 ("Last location shapes is not coincided with last vertex of aWirePath");
1522 VLocs.ChangeValue(nbLocs) = VL;
1524 TopTools_SequenceOfShape tmpEdges;
1525 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1526 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1527 tol = BRep_Tool::Tolerance(E);
1528 TopoDS_Vertex V1 = sae.FirstVertex(E);
1529 TopoDS_Vertex V2 = sae.LastVertex(E);
1530 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1531 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1532 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1533 // make wire from current edge and add created
1537 for (j=1; j<=tmpEdges.Length(); j++)
1538 B.Add(W,tmpEdges.Value(j));
1541 VLocs.ChangeValue(jcurr) = V2;
1546 // find distance between E and aLocs(jcurr)
1548 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1549 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1550 if (PPCurve.NbPoints()>0 &&
1551 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1552 double param = PPCurve.Parameter(1);
1555 // split current edge
1556 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1557 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1561 if (Pfp.Distance(P1)<tol) {
1562 B.MakeEdge(E1,tc1,tol);
1564 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1565 B.Add(E1,TopoDS::Vertex(tmpV));
1566 tmpEdges.Append(E1);
1567 B.MakeEdge(E2,tc2,tol);
1568 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1569 B.Add(E2,TopoDS::Vertex(tmpV));
1573 B.MakeEdge(E1,tc2,tol);
1574 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1575 B.Add(E1,TopoDS::Vertex(tmpV));
1578 tmpEdges.Append(E1);
1579 B.MakeEdge(E2,tc1,tol);
1581 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1582 B.Add(E2,TopoDS::Vertex(tmpV));
1585 // create wire from tmpEdges
1588 for (j=1; j<=tmpEdges.Length(); j++)
1589 B.Add(W,tmpEdges.Value(j));
1594 Edges.InsertAfter(i-1,E1);
1595 Edges.InsertAfter(i,E2);
1602 // create wire from other edges
1605 for (; i<=Edges.Length(); i++)
1606 B.Add(W,Edges.Value(i));
1610 if (Wires.Length() != nbLocs-1) {
1611 if (aCI) delete aCI;
1612 Standard_ConstructionError::Raise
1613 ("One of location shapes is not lied on the path");
1616 TopTools_SequenceOfShape aGroups[5];
1617 TopoDS_Compound aComp;
1618 B.MakeCompound(aComp);
1619 for (i = 1; i < nbBases; i++) {
1620 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1622 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1623 if (anItem1.IsNull())
1625 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1626 if (aRefBase1.IsNull())
1628 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1629 if (aShBase1.IsNull())
1631 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1633 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1634 if (anItem2.IsNull())
1636 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1637 if (aRefBase2.IsNull())
1639 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1640 if (aShBase2.IsNull())
1642 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1644 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1645 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1647 if (aCI) delete aCI;
1648 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1651 bool CreateFewSolids = false;
1653 TopExp_Explorer anExp;
1654 Standard_Integer nbf1 = 0;
1655 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1658 Standard_Integer nbf2 = 0;
1659 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1663 CreateFewSolids = true;
1666 if (!CreateFewSolids) {
1667 // we can create only one solid
1668 TopoDS_Shape aWire1, aWire2;
1670 if (aType1==TopAbs_SHELL) {
1671 // create wire as boundary contour if shell is no closed
1672 // get free boundary shapes
1673 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1674 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1675 //TopExp_Explorer anExp;
1676 Standard_Integer NbWires = 0;
1677 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1679 aWire1 = anExp.Current();
1683 if (aCI) delete aCI;
1684 Standard_ConstructionError::Raise("Bad shell is used as section ");
1687 else { // aType1==TopAbs_FACE
1688 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1689 aWire1 = aExpW.Current();
1692 if (aType2==TopAbs_SHELL) {
1693 // create wire as boundary contour if shell is no closed
1694 // get free boundary shapes
1695 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1696 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1697 //TopExp_Explorer anExp;
1698 Standard_Integer NbWires = 0;
1699 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1701 aWire2 = anExp.Current();
1705 if (aCI) delete aCI;
1706 Standard_ConstructionError::Raise("Bad shell is used as section ");
1709 else { // aType2==TopAbs_FACE
1710 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1711 aWire2 = aExpW.Current();
1713 // make pipe using aWire1 and aWire2
1714 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1715 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1716 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1717 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1718 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1719 aBuilder.SetDiscreteMode();
1720 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1721 aWithContact, aWithCorrect);
1722 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1723 aWithContact, aWithCorrect);
1724 if (!aBuilder.IsReady()) {
1725 if (aCI) delete aCI;
1726 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1729 BuildPipeShell(aBuilder);
1731 TopoDS_Shape aShape = aBuilder.Shape();
1732 TopTools_SequenceOfShape aLocalGroups[5];
1735 if (isGenerateGroups) {
1737 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
1738 if (aCI) delete aCI;
1739 Standard_ConstructionError::Raise("Generate groups failure");
1742 // Clear the groups Down and Up.
1743 aLocalGroups[GROUP_DOWN].Clear();
1744 aLocalGroups[GROUP_UP].Clear();
1747 TopoDS_Shell aShell;
1748 B.MakeShell(aShell);
1749 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1750 B.Add(aShell,anExp.Current());
1752 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1753 B.Add(aShell,anExp.Current());
1755 if (isGenerateGroups && i == 1) {
1756 aLocalGroups[GROUP_DOWN].Append(anExp.Current());
1759 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1760 B.Add(aShell,anExp.Current());
1762 if (isGenerateGroups && i == nbBases - 1) {
1763 aLocalGroups[GROUP_UP].Append(anExp.Current());
1766 // make sewing for this shell
1767 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1768 aSewing->SetTolerance(Precision::Confusion());
1769 aSewing->SetFaceMode(Standard_True);
1770 aSewing->SetFloatingEdgesMode(Standard_False);
1771 aSewing->SetNonManifoldMode(Standard_False);
1772 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1773 aSewing->Add(anExp.Current());
1776 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1777 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1778 aShell = TopoDS::Shell(aSewShape);
1779 GProp_GProps aSystem;
1780 BRepGProp::VolumeProperties(aShell, aSystem);
1781 if (aSystem.Mass()<0) {
1784 if (BRep_Tool::IsClosed(aShell)) {
1785 TopoDS_Solid aSolid;
1786 B.MakeSolid(aSolid);
1787 B.Add(aSolid,aShell);
1788 B.Add(aComp,aSolid);
1791 B.Add(aComp,aShell);
1795 B.Add(aComp,aShell);
1798 if (isGenerateGroups) {
1799 Standard_Integer iGrp;
1801 for (iGrp = 0; iGrp < 5; ++iGrp) {
1804 // For each sub-shape of pipe
1805 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1806 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1808 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1809 // Use the shape modified by sewing.
1810 const TopoDS_Shape &aModifGrpShape =
1811 aSewing->ModifiedSubShape(aGrpShape);
1813 aGroups[iGrp].Append(aModifGrpShape);
1815 // Use the shape as it is.
1816 aGroups[iGrp].Append(aGrpShape);
1824 // main block - creation few solids (for each pair of faces)
1825 TopTools_MapOfShape aFaces1,aFaces2;
1826 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1827 aFaces1.Add(anExp.Current());
1829 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1830 aFaces2.Add(anExp.Current());
1832 // creating map of edge faces
1833 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1834 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1835 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1836 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1838 // construct map face->face
1839 TopTools_IndexedDataMapOfShapeShape FF;
1840 TopoDS_Shape FS1,FS2;
1841 if (nbSubBases==0) {
1842 // find edge the most distant from location point
1843 // (this edge is not shared by two faces)
1844 double maxdist = 0.;
1846 TopoDS_Vertex V11,V21;
1847 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1848 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1849 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1850 if (aList.Extent()>1)
1852 TopExp_Explorer expv;
1853 expv.Init(tmp, TopAbs_VERTEX);
1854 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1856 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1857 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1858 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1859 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1864 TopTools_ListIteratorOfListOfShape anIter(aList);
1865 FS1 = anIter.Value();
1869 // main direction for comparing
1870 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1871 // find corresponding edge from next section
1872 double minang = M_PI;
1873 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1874 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1876 TopoDS_Vertex V12,V22;
1877 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1878 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1879 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1880 if (aList.Extent()>1)
1882 TopExp_Explorer expv;
1883 expv.Init(tmp, TopAbs_VERTEX);
1884 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1886 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1887 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1888 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1889 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1890 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1891 TopoDS_Vertex V1,V2;
1894 V1 = V2tmp; P1 = P2tmp;
1895 V2 = V1tmp; P2 = P1tmp;
1898 V1 = V1tmp; P1 = P1tmp;
1899 V2 = V2tmp; P2 = P2tmp;
1901 gp_Vec Vec1(P11,P1);
1902 gp_Vec Vec2(P21,P2);
1903 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1908 TopTools_ListIteratorOfListOfShape anIter(aList);
1909 FS2 = anIter.Value();
1913 // put all pairs to map FF
1919 // add pairs of edges to FF
1920 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1922 if (aCI) delete aCI;
1923 Standard_ConstructionError::Raise("FindForOtherEdges: Can not map other edges");
1929 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1930 if (anItem.IsNull()) {
1931 if (aCI) delete aCI;
1932 Standard_ConstructionError::Raise("Invalid subbase shape");
1934 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1935 if (aRefBase.IsNull()) {
1936 if (aCI) delete aCI;
1937 Standard_ConstructionError::Raise("Invalid subbase shape");
1939 TopoDS_Shape aSh = aRefBase->GetValue();
1941 if (aCI) delete aCI;
1942 Standard_ConstructionError::Raise("Invalid subbase shape");
1944 if (aSh.ShapeType()!=TopAbs_FACE) {
1945 if (aCI) delete aCI;
1946 Standard_ConstructionError::Raise("Invalid subbase shape");
1951 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1952 if (anItem.IsNull()) {
1953 if (aCI) delete aCI;
1954 Standard_ConstructionError::Raise("Invalid subbase shape");
1956 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1957 if (aRefBase.IsNull()) {
1958 if (aCI) delete aCI;
1959 Standard_ConstructionError::Raise("Invalid subbase shape");
1961 TopoDS_Shape aSh = aRefBase->GetValue();
1963 if (aCI) delete aCI;
1964 Standard_ConstructionError::Raise("Invalid subbase shape");
1966 if (aSh.ShapeType()!=TopAbs_FACE) {
1967 if (aCI) delete aCI;
1968 Standard_ConstructionError::Raise("Invalid subbase shape");
1973 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1974 if (aCI) delete aCI;
1975 Standard_ConstructionError::Raise("Invalid subbase shape");
1980 // add pairs of edges to FF
1981 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1982 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1984 if (aCI) delete aCI;
1985 Standard_ConstructionError::Raise("Can not create correct pipe");
1989 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1991 // make pipe for each pair of faces
1992 for (j=1; j<=FF.Extent(); j++) {
1993 TopoDS_Shape F1 = FF.FindKey(j);
1994 if (F1.ShapeType() != TopAbs_FACE)
1996 TopoDS_Shape F2 = FF.FindFromIndex(j);
1997 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1998 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1999 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
2000 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
2001 // make pipe using aWire1 and aWire2
2002 if (!aWire1.IsNull() && !aWire2.IsNull()) {
2003 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
2004 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
2005 if (theBestMode == GeomFill_IsDiscreteTrihedron)
2006 aBuilder.SetDiscreteMode();
2007 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
2008 aWithContact, aWithCorrect);
2009 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
2010 aWithContact, aWithCorrect);
2011 if (!aBuilder.IsReady()) {
2012 if (aCI) delete aCI;
2013 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
2016 BuildPipeShell(aBuilder);
2018 TopoDS_Shape aShape = aBuilder.Shape();
2019 TopTools_SequenceOfShape aLocalGroups[5];
2022 if (isGenerateGroups) {
2024 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
2025 if (aCI) delete aCI;
2026 Standard_ConstructionError::Raise("Generate groups failure");
2029 // Clear the groups Down and Up.
2030 aLocalGroups[GROUP_DOWN].Clear();
2031 aLocalGroups[GROUP_UP].Clear();
2034 aLocalGroups[GROUP_DOWN].Append(F1);
2037 if (i == nbBases - 1) {
2038 aLocalGroups[GROUP_UP].Append(F2);
2042 TopoDS_Shell aShell;
2043 B.MakeShell(aShell);
2044 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
2045 B.Add(aShell,anExp.Current());
2050 // make sewing for this shell
2051 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2052 aSewing->SetTolerance(Precision::Confusion());
2053 aSewing->SetFaceMode(Standard_True);
2054 aSewing->SetFloatingEdgesMode(Standard_False);
2055 aSewing->SetNonManifoldMode(Standard_False);
2056 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2057 aSewing->Add(anExp.Current());
2060 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2061 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2062 aShell = TopoDS::Shell(aSewShape);
2063 GProp_GProps aSystem;
2064 BRepGProp::VolumeProperties(aShell, aSystem);
2065 if (aSystem.Mass() < 0) {
2068 if (BRep_Tool::IsClosed(aShell)) {
2069 TopoDS_Solid aSolid;
2070 B.MakeSolid(aSolid);
2071 B.Add(aSolid,aShell);
2072 B.Add(aComp,aSolid);
2075 B.Add(aComp,aShell);
2079 B.Add(aComp,aShell);
2082 if (isGenerateGroups) {
2083 // Replase Group shapes by modified ones.
2084 Standard_Integer iGrp;
2087 for (iGrp = 0; iGrp < 5; ++iGrp) {
2090 // For each sub-shape of pipe
2091 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2092 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2094 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2095 // Use the shape modified by sewing.
2096 const TopoDS_Shape &aModifGrpShape =
2097 aSewing->ModifiedSubShape(aGrpShape);
2099 aGroups[iGrp].Append(aModifGrpShape);
2101 // Use the shape as it is.
2102 aGroups[iGrp].Append(aGrpShape);
2112 if (isGenerateGroups) {
2114 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2115 TopTools_IndexedMapOfShape anIndices;
2117 TopExp::MapShapes(aComp, anIndices);
2119 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2120 if (aCI) delete aCI;
2121 Standard_ConstructionError::Raise("Generate groups failure");
2124 StoreGroups(aCI, aGroupIds);
2130 //=======================================================================
2131 //function : CreatePipeShellsWithoutPath
2132 //purpose : auxiliary for Execute()
2133 //=======================================================================
2134 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
2139 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
2141 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
2142 // vertex for recognition
2143 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
2144 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
2146 Standard_Integer nbBases = aBasesObjs->Length(),
2147 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
2149 if (nbv != nbBases) {
2150 if (aCI) delete aCI;
2151 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
2154 TopTools_SequenceOfShape aGroups[5];
2155 TopTools_SequenceOfShape SecVs,Bases;
2156 for (i=1; i<=nbBases; i++) {
2158 Handle(Standard_Transient) anItem = VObjs->Value(i);
2159 if (anItem.IsNull())
2161 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
2162 TopoDS_Shape V = aRef->GetValue();
2163 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
2167 anItem = aBasesObjs->Value(i);
2168 if (anItem.IsNull())
2170 aRef = Handle(GEOM_Function)::DownCast(anItem);
2171 TopoDS_Shape aSh = aRef->GetValue();
2176 nbv = SecVs.Length();
2177 nbBases = Bases.Length();
2178 if (nbv != nbBases) {
2179 if (aCI) delete aCI;
2180 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
2183 TopoDS_Compound aComp;
2184 B.MakeCompound(aComp);
2186 for (i = 1; i < nbBases; i++) {
2187 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
2188 TopoDS_Shape aShBase1 = Bases.Value(i);
2189 TopoDS_Shape aShBase2 = Bases.Value(i+1);
2190 TopExp_Explorer anExp;
2191 Standard_Integer nbf1 = 0;
2192 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2195 Standard_Integer nbf2 = 0;
2196 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2200 if (aCI) delete aCI;
2201 Standard_ConstructionError::Raise("Different number of faces in the sections");
2204 TopTools_MapOfShape aFaces1,aFaces2;
2205 TopTools_MapOfShape aBndEdges1;
2207 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2208 const TopoDS_Shape &aBaseFace1 = anExp.Current();
2210 if (aFaces1.Add(aBaseFace1)) {
2211 // Get boundary edges.
2212 TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
2214 for (; anExpE.More(); anExpE.Next()) {
2215 const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
2217 if (!aBndEdges1.Add(aBaseEdge1)) {
2218 aBndEdges1.Remove(aBaseEdge1);
2223 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2224 aFaces2.Add(anExp.Current());
2227 // creating map of edge faces
2228 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
2229 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
2230 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
2231 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
2233 // construct map face->face (and sub-shapes)
2234 TopTools_IndexedDataMapOfShapeShape FF;
2235 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
2236 TopoDS_Shape FS1, FS2;
2237 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
2238 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
2239 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
2242 MESSAGE (" first pair of corresponding faces is found");
2244 // add pairs of edges and vertexes to FF
2245 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
2247 if (aCI) delete aCI;
2248 Standard_ConstructionError::Raise("Can not create correct pipe");
2250 MESSAGE (" correspondences for sub-shapes of first pair of faces found");
2252 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2253 MESSAGE (" other correspondences found, make pipe for all pairs of faces");
2255 // make pipe for each pair of faces
2256 // auxiliary map vertex->edge for created pipe edges
2257 TopTools_IndexedDataMapOfShapeShape VPE;
2258 ShapeAnalysis_Edge sae;
2260 for (j=1; j<=FF.Extent(); j++) {
2261 TopoDS_Shape F1 = FF.FindKey(j);
2262 if (F1.ShapeType() != TopAbs_FACE)
2264 TopoDS_Shape F2 = FF.FindFromIndex(j);
2267 //if (nbff!=3) continue;
2269 MESSAGE (" make pipe for "<<nbff<<" face");
2271 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
2272 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2273 Handle(Geom_RectangularTrimmedSurface) RTS =
2274 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
2275 S1 = RTS->BasisSurface();
2277 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
2278 if (Pln1.IsNull()) {
2279 if (aCI) delete aCI;
2280 Standard_ConstructionError::Raise("Surface from face is not plane");
2282 gp_Vec aDir1(Pln1->Axis().Direction());
2284 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
2285 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2286 Handle(Geom_RectangularTrimmedSurface) RTS =
2287 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
2288 S2 = RTS->BasisSurface();
2290 Handle(Geom_Plane) Pln2 =
2291 Handle(Geom_Plane)::DownCast(S2);
2292 if (Pln2.IsNull()) {
2293 if (aCI) delete aCI;
2294 Standard_ConstructionError::Raise("Surface from face is not plane");
2296 gp_Vec aDir2(Pln2->Axis().Direction());
2298 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
2299 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
2301 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
2303 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
2306 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
2307 TopTools_SequenceOfShape aNewFs;
2308 TopTools_SequenceOfShape aLocalGroups[5];
2311 for (; anExpE.More(); anExpE.Next()) {
2312 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2314 if (!FF.Contains(E1))
2315 MESSAGE ("map FF not contains key E1");
2317 if (VPE.Contains(E1)) {
2318 aNewFs.Append(VPE.FindFromKey(E1));
2320 MESSAGE (" using existing face");
2325 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2326 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2327 TopoDS_Vertex V2 = sae.LastVertex(E1);
2328 if (!FF.Contains(V1))
2329 MESSAGE ("map FF not contains key V1");
2330 if (!FF.Contains(V2))
2331 MESSAGE ("map FF not contains key V2");
2332 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2333 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2334 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2335 if (Vtmp.IsSame(V4))
2337 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2338 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2339 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2340 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2343 Handle(Geom_BSplineCurve) C2;
2344 if (VPE.Contains(V2)) {
2345 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2347 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2350 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2351 HAP->SetValue(1,P2);
2352 HAP->SetValue(2,P3);
2353 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2354 anInt.Load(aDir1,aDir2);
2357 B.MakeEdge(E2,C2,1.e-7);
2358 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2359 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2364 Handle(Geom_BSplineCurve) C4;
2365 if (VPE.Contains(V1)) {
2366 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2368 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2371 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2372 HAP->SetValue(1,P1);
2373 HAP->SetValue(2,P4);
2374 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2375 anInt.Load(aDir1,aDir2);
2378 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2379 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2380 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2389 B.Add(W,E4.Reversed());
2394 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2395 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2396 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2398 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2399 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2400 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2402 Handle(Geom_BSplineCurve) CE1 =
2403 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2404 if (CE1->Degree()<3)
2405 CE1->IncreaseDegree(3);
2406 Handle(Geom_BSplineCurve) CE2 =
2407 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2408 if (CE2->Degree()<3)
2409 CE2->IncreaseDegree(3);
2410 Handle(Geom_BSplineCurve) CE3 =
2411 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2412 if (CE3->Degree()<3)
2413 CE3->IncreaseDegree(3);
2414 Handle(Geom_BSplineCurve) CE4 =
2415 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2416 if (CE4->Degree()<3)
2417 CE4->IncreaseDegree(3);
2419 Handle(Geom_Surface) BS;
2421 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2422 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2426 MESSAGE (" can not create BSplineSurface - create Bezier");
2428 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2429 double fp1,lp1,fp2,lp2;
2430 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2431 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2440 // get points from C1
2441 if (P1.Distance(P1C1)<1.e-6) {
2449 double step = (lp-fp)/(NbP-1);
2450 Points.SetValue(1,1,P1);
2452 for (n1=2; n1<NbP; n1++) {
2456 Points.SetValue(1,n1,P);
2458 Points.SetValue(1,NbP,P2);
2459 // get points from C3
2460 if (P4.Distance(P1C3)<1.e-6) {
2468 step = (lp-fp)/(NbP-1);
2469 Points.SetValue(NbP,1,P4);
2471 for (n1=2; n1<NbP; n1++) {
2475 Points.SetValue(NbP,n1,P);
2477 Points.SetValue(NbP,NbP,P3);
2478 // create isolines and get points from them
2479 for (n1=1; n1<=NbP; n1++) {
2480 gp_Pnt PI1 = Points.Value(1,n1);
2481 gp_Pnt PI2 = Points.Value(NbP,n1);
2482 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2483 HAP->SetValue(1,PI1);
2484 HAP->SetValue(2,PI2);
2485 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2486 anInt.Load(aDir1,aDir2);
2488 const Handle(Geom_BSplineCurve) iso = anInt.Curve();
2489 fp = iso->FirstParameter();
2490 lp = iso->LastParameter();
2491 step = (lp-fp)/(NbP-1);
2493 TopoDS_Compound VComp;
2494 B.MakeCompound(VComp);
2495 for (n2=2; n2<NbP; n2++) {
2499 Points.SetValue(n2,n1,P);
2502 // create surface and face
2503 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2504 BS = new Geom_BezierSurface(Points);
2507 BRepBuilderAPI_MakeFace BB(BS,W);
2508 TopoDS_Face NewF = BB.Face();
2509 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2511 sff->FixOrientation();
2512 TopoDS_Face FixedFace = sff->Face();
2513 aNewFs.Append(FixedFace);
2514 VPE.Add(E1,FixedFace);
2516 if (isGenerateGroups) {
2517 if (aBndEdges1.Contains(E1)) {
2518 // This is a boundary face.
2519 aLocalGroups[GROUP_OTHER].Append(FixedFace);
2524 TopoDS_Shell aShell;
2525 B.MakeShell(aShell);
2526 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2527 B.Add(aShell,aNewFs(nf));
2533 if (isGenerateGroups && i == 1) {
2534 aLocalGroups[GROUP_DOWN].Append(F1);
2537 if (isGenerateGroups && i == nbBases - 1) {
2538 aLocalGroups[GROUP_UP].Append(F2);
2541 // make sewing for this shell
2542 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2543 aSewing->SetTolerance(Precision::Confusion());
2544 aSewing->SetFaceMode(Standard_True);
2545 aSewing->SetFloatingEdgesMode(Standard_False);
2546 aSewing->SetNonManifoldMode(Standard_False);
2547 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2548 aSewing->Add(anExp.Current());
2551 MESSAGE (" shell for face "<<nbff<<" is created");
2552 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2553 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2554 aShell = TopoDS::Shell(aSewShape);
2555 GProp_GProps aSystem;
2556 BRepGProp::VolumeProperties(aShell, aSystem);
2557 if (aSystem.Mass() < 0) {
2560 if (BRep_Tool::IsClosed(aShell)) {
2561 TopoDS_Solid aSolid;
2562 B.MakeSolid(aSolid);
2563 B.Add(aSolid,aShell);
2564 B.Add(aComp,aSolid);
2565 MESSAGE (" solid for face "<<nbff<<" is created");
2568 B.Add(aComp,aShell);
2569 MESSAGE (" solid for face "<<nbff<<" is not created");
2573 B.Add(aComp,aShell);
2574 MESSAGE (" solid for face "<<nbff<<" is not created");
2577 if (isGenerateGroups) {
2578 Standard_Integer iGrp;
2580 for (iGrp = 0; iGrp < 5; ++iGrp) {
2583 // For each sub-shape of pipe
2584 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2585 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2587 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2588 // Use the shape modified by sewing.
2589 const TopoDS_Shape &aModifGrpShape =
2590 aSewing->ModifiedSubShape(aGrpShape);
2592 aGroups[iGrp].Append(aModifGrpShape);
2594 // Use the shape as it is.
2595 aGroups[iGrp].Append(aGrpShape);
2603 if (isGenerateGroups) {
2605 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2606 TopTools_IndexedMapOfShape anIndices;
2608 TopExp::MapShapes(aComp, anIndices);
2610 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2611 if (aCI) delete aCI;
2612 Standard_ConstructionError::Raise("Generate groups failure");
2615 StoreGroups(aCI, aGroupIds);
2621 //=======================================================================
2622 //function : CreatePipeBiNormalAlongVector
2623 //purpose : auxiliary for Execute()
2624 //=======================================================================
2625 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2626 GEOMImpl_IPipe* aCI)
2628 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2630 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2631 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2632 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2633 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2635 if (aShapeBase.IsNull()) {
2636 if (aCIBN) delete aCIBN;
2637 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2640 // Make copy to prevent modifying of base object: 0021525
2641 BRepBuilderAPI_Copy Copy (aShapeBase);
2643 aShapeBase = Copy.Shape();
2646 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2649 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2650 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2652 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2655 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2656 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2657 aProf = wexp.Current();
2660 Standard_TypeMismatch::Raise
2661 ("MakePipe aborted : invalid type of base");
2663 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2664 PipeBuilder.Add(aProf);
2666 if (aShapeVec.IsNull()) {
2667 if (aCIBN) delete aCIBN;
2668 Standard_NullObject::Raise
2669 ("MakePipe aborted : null vector argument");
2671 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2672 Standard_TypeMismatch::Raise
2673 ("MakePipe aborted: invalid type of vector");
2674 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2675 TopoDS_Vertex V1, V2;
2676 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2677 if (V1.IsNull() || V2.IsNull())
2678 Standard_NullObject::Raise
2679 ("MakePipe aborted: vector is not defined");
2680 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2681 gp_Dir BiNormal(aVec);
2682 PipeBuilder.SetMode(BiNormal);
2684 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2686 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2687 PipeBuilder.MakeSolid();
2690 if (!CreateGroups1(aProf, PipeBuilder, aCIBN)) {
2691 if (aCIBN) delete aCIBN;
2692 Standard_ConstructionError::Raise("Generate groups failure");
2695 return PipeBuilder.Shape();
2698 //=======================================================================
2699 //function : FillGroups
2700 //purpose : auxiliary for DoGroups()
2701 //=======================================================================
2702 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
2703 const TopTools_IndexedMapOfShape &theIndices,
2704 Handle(TColStd_HArray1OfInteger) *theGroupIds)
2708 for (i = 0; i < 5; ++i) {
2709 if (!theGroups[i].IsEmpty()) {
2710 const Standard_Integer aNbShapes = theGroups[i].Length();
2713 theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
2715 for (j = 1; j <= aNbShapes; ++j) {
2716 const TopoDS_Shape &aShape = theGroups[i].Value(j);
2717 const Standard_Integer anIndex = theIndices.FindIndex(aShape);
2723 theGroupIds[i]->SetValue(j, anIndex);
2731 //=======================================================================
2732 //function : StoreGroups
2733 //purpose : auxiliary for CreateGroups()
2734 //=======================================================================
2735 void StoreGroups(GEOMImpl_IPipe *theCI,
2736 Handle(TColStd_HArray1OfInteger) *theGroups)
2738 if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
2739 theCI->SetGroupDown(theGroups[GROUP_DOWN]);
2742 if (theGroups[GROUP_UP].IsNull() == Standard_False) {
2743 theCI->SetGroupUp(theGroups[GROUP_UP]);
2746 if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
2747 theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
2750 if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
2751 theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
2754 if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
2755 theCI->SetGroupOther(theGroups[GROUP_OTHER]);
2759 //=======================================================================
2760 //function : CreateDownUpGroups
2761 //purpose : auxiliary for DoGroups()
2762 //=======================================================================
2763 static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
2764 TopTools_SequenceOfShape *theGroups,
2765 Standard_Boolean &IsDoSides)
2767 const TopoDS_Shape aDownShape = theSweep->FirstShape();
2768 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2769 TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
2771 IsDoSides = Standard_False;
2776 anUpDownType = TopAbs_EDGE;
2778 if (GEOMUtils::IsOpenPath(aDownShape)) {
2779 IsDoSides = Standard_True;
2784 anUpDownType = TopAbs_FACE;
2790 if (anUpDownType == TopAbs_SHAPE) {
2791 // Invalid Up and Down group type.
2795 TopExp_Explorer anExp(aDownShape, anUpDownType);
2796 TopTools_MapOfShape aMapFence;
2798 // Create Down group.
2799 for (; anExp.More(); anExp.Next()) {
2800 const TopoDS_Shape &aShape = anExp.Current();
2802 if (aMapFence.Add(aShape)) {
2803 theGroups[GROUP_DOWN].Append(aShape);
2808 const TopoDS_Shape anUpShape = theSweep->LastShape();
2811 anExp.Init(anUpShape, anUpDownType);
2813 for (; anExp.More(); anExp.Next()) {
2814 const TopoDS_Shape &aShape = anExp.Current();
2816 if (aMapFence.Add(aShape)) {
2817 theGroups[GROUP_UP].Append(aShape);
2824 //=======================================================================
2825 //function : DoGroups1
2826 //purpose : auxiliary for CreateGroups1()
2827 //=======================================================================
2828 bool DoGroups1 (const TopoDS_Shape &theProfile,
2829 BRepOffsetAPI_MakePipeShell &theSweep,
2830 TopTools_SequenceOfShape *theGroups)
2832 Standard_Boolean isDoSides = Standard_False;
2834 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2835 // Up and Down groups creation failure
2839 TopoDS_Shape aDownShape = theProfile;
2840 if (aDownShape.IsNull()) aDownShape = theSweep.FirstShape();
2843 // Create Side1 and Side2 groups.
2844 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2845 TopoDS_Vertex aV[2];
2848 if (aType == TopAbs_EDGE) {
2849 TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
2850 } else { // aType == TopAbs_WIRE
2851 TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
2854 for (i = 0; i < 2; ++i) {
2855 if (aV[i].IsNull() == Standard_False) {
2856 const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
2858 if (!aLstSide.IsEmpty()) {
2859 TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
2860 TopTools_MapOfShape aMapFence;
2861 const Standard_Integer anIdSide =
2862 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2864 for (; aSideIt.More(); aSideIt.Next()) {
2865 const TopoDS_Shape &aSideShape = aSideIt.Value();
2867 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2868 if (aMapFence.Add(aSideShape)) {
2869 theGroups[anIdSide].Append(aSideShape);
2871 } else if (aSideShape.ShapeType() == TopAbs_WIRE) {
2872 if (aMapFence.Add(aSideShape)) {
2873 TopExp_Explorer anExpWE (aSideShape, TopAbs_EDGE);
2874 for (; anExpWE.More(); anExpWE.Next()) {
2875 theGroups[anIdSide].Append(anExpWE.Current());
2879 // Only edges can be in Side1 and Side2 groups.
2887 // Create Other group. Get boundary edges of the profile.
2888 TopTools_MapOfShape aMapBndEdges;
2889 TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
2891 for (; anExp.More(); anExp.Next()) {
2892 const TopoDS_Shape &anEdge = anExp.Current();
2894 if (!aMapBndEdges.Add(anEdge)) {
2895 aMapBndEdges.Remove(anEdge);
2899 // Fill the map of faces generated from profile's boundary edges.
2900 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2901 TopTools_MapOfShape aMapFence;
2903 for (; anIter.More(); anIter.Next()) {
2904 const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
2906 if (!aLstOther.IsEmpty()) {
2907 TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
2909 for (; anOtherIt.More(); anOtherIt.Next()) {
2910 const TopoDS_Shape &anOtherShape = anOtherIt.Value();
2912 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2913 if (aMapFence.Add(anOtherShape)) {
2914 theGroups[GROUP_OTHER].Append(anOtherShape);
2916 } else if (anOtherShape.ShapeType() == TopAbs_SHELL) {
2917 if (aMapFence.Add(anOtherShape)) {
2918 TopExp_Explorer anExpSHF (anOtherShape, TopAbs_FACE);
2919 for (; anExpSHF.More(); anExpSHF.Next()) {
2920 theGroups[GROUP_OTHER].Append(anExpSHF.Current());
2924 // Only faces can be in Other group.
2935 //=======================================================================
2936 //function : CreateGroups1
2937 //purpose : auxiliary for Execute()
2938 //=======================================================================
2939 bool CreateGroups1 (const TopoDS_Shape &theProfile,
2940 BRepOffsetAPI_MakePipeShell &theSweep,
2941 GEOMImpl_IPipe *theCI)
2943 if (!theCI->GetGenerateGroups()) {
2949 TopTools_SequenceOfShape aGroups[5];
2951 if (!DoGroups1(theProfile, theSweep, aGroups)) {
2956 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2957 TopTools_IndexedMapOfShape anIndices;
2958 const TopoDS_Shape aResult = theSweep.Shape();
2960 TopExp::MapShapes(aResult, anIndices);
2962 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2967 StoreGroups(theCI, aGroupIds);
2972 //=======================================================================
2973 //function : DoGroups2
2974 //purpose : auxiliary for CreateGroups()
2975 //=======================================================================
2976 static bool DoGroups2(const TopoDS_Shape &theProfile,
2977 const TopoDS_Shape &thePath,
2978 BRepOffsetAPI_MakePipe &theSweep,
2979 TopTools_SequenceOfShape *theGroups)
2981 Standard_Boolean isDoSides = Standard_False;
2983 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2984 // Up and Down groups creation failure
2989 // Create Side1 and Side2 groups.
2990 const TopAbs_ShapeEnum aType = theProfile.ShapeType();
2991 TopoDS_Vertex aV[2];
2994 if (aType == TopAbs_EDGE) {
2995 TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
2996 } else { // aType == TopAbs_WIRE
2997 TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
3000 for (i = 0; i < 2; ++i) {
3001 if (aV[i].IsNull() == Standard_False) {
3002 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
3003 TopTools_MapOfShape aMapFence;
3004 const Standard_Integer anIdSide =
3005 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
3007 for (; anExpP.More(); anExpP.Next()) {
3008 const TopoDS_Shape aSideShape =
3009 theSweep.Generated(anExpP.Current(), aV[i]);
3011 if (aSideShape.ShapeType() == TopAbs_EDGE) {
3012 if (aMapFence.Add(aSideShape)) {
3013 theGroups[anIdSide].Append(aSideShape);
3016 // Only edges can be is Side1 and Side2 groups.
3023 // Create Other group. Get boundary edges of the profile.
3024 TopTools_MapOfShape aMapBndEdges;
3025 TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
3027 for (; anExp.More(); anExp.Next()) {
3028 const TopoDS_Shape &anEdge = anExp.Current();
3030 if (!aMapBndEdges.Add(anEdge)) {
3031 aMapBndEdges.Remove(anEdge);
3035 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
3036 TopTools_MapOfShape aMapFence;
3038 for (; anExpP.More(); anExpP.Next()) {
3039 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
3041 for (; anIter.More(); anIter.Next()) {
3042 const TopoDS_Shape anOtherShape =
3043 theSweep.Generated(anExpP.Current(), anIter.Key());
3045 if (anOtherShape.ShapeType() == TopAbs_FACE) {
3046 if (aMapFence.Add(anOtherShape)) {
3047 theGroups[GROUP_OTHER].Append(anOtherShape);
3050 // Only faces can be in Other group.
3060 //=======================================================================
3061 //function : CreateGroups
3062 //purpose : auxiliary for Execute()
3063 //=======================================================================
3064 static bool CreateGroups2(const TopoDS_Shape &theProfile,
3065 const TopoDS_Shape &thePath,
3066 BRepOffsetAPI_MakePipe &theSweep,
3067 GEOMImpl_IPipe *theCI)
3069 if (!theCI->GetGenerateGroups()) {
3075 TopTools_SequenceOfShape aGroups[5];
3077 if (!DoGroups2(theProfile, thePath, theSweep, aGroups)) {
3082 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
3083 TopTools_IndexedMapOfShape anIndices;
3084 const TopoDS_Shape aResult = theSweep.Shape();
3086 TopExp::MapShapes(aResult, anIndices);
3088 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
3093 StoreGroups(theCI, aGroupIds);
3098 //=======================================================================
3099 //function : Execute
3101 //=======================================================================
3102 Standard_Integer GEOMImpl_PipeDriver::Execute(Handle(TFunction_Logbook)& log) const
3104 if (Label().IsNull()) return 0;
3105 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
3106 Standard_Integer aType = aFunction->GetType();
3108 GEOMImpl_IPipe* aCI = 0;
3109 if (aType == PIPE_BASE_PATH)
3110 aCI = new GEOMImpl_IPipe (aFunction);
3111 else if (aType == PIPE_DIFFERENT_SECTIONS)
3112 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
3113 else if (aType == PIPE_SHELL_SECTIONS)
3114 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3115 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
3116 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3117 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
3118 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
3122 TopoDS_Wire aWirePath;
3123 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
3124 // working with path
3125 Handle(GEOM_Function) aRefPath = aCI->GetPath();
3126 TopoDS_Shape aShapePath = aRefPath->GetValue();
3128 if (aShapePath.IsNull()) {
3129 MESSAGE ("Driver : path is null");
3130 if (aCI) delete aCI;
3131 Standard_NullObject::Raise("MakePipe aborted : null path argument");
3136 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
3137 TopTools_SequenceOfShape anEdges;
3138 TopExp_Explorer anExp;
3142 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
3143 B.Add(W, anExp.Current());
3149 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
3150 aWirePath = TopoDS::Wire(aShapePath);
3154 if (aShapePath.ShapeType() == TopAbs_EDGE) {
3155 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
3156 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
3161 if (aCI) delete aCI;
3162 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
3165 // Check if it is possible to create groups.
3166 if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
3171 Standard_ConstructionError::Raise
3172 ("Can't create groups if the path is closed");
3176 TopoDS_Shape aShape;
3177 const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
3179 if (aType == PIPE_BASE_PATH) {
3180 Handle(GEOM_Function) aRefBase = aCI->GetBase();
3181 TopoDS_Shape aShapeBase;
3183 // Make copy to prevent modifying of base object 0020766 : EDF 1320
3184 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
3186 aShapeBase = Copy.Shape();
3188 if (aShapeBase.IsNull()) {
3189 if (aCI) delete aCI;
3190 Standard_NullObject::Raise("MakePipe aborted : null base argument");
3194 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
3195 aShapeBase.ShapeType() == TopAbs_WIRE)
3197 TopoDS_Wire aProfile;
3198 if (aShapeBase.ShapeType() == TopAbs_WIRE)
3199 aProfile = TopoDS::Wire(aShapeBase);
3203 BB.MakeWire(aProfile);
3204 BB.Add(aProfile, aShapeBase);
3207 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
3208 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
3209 if (FaceBuilder.IsDone())
3210 Sweep.SetMode(FaceBuilder.Face());
3211 Sweep.Add(aProfile);
3213 Standard_Boolean isDone = BuildPipeShell(Sweep);
3217 if (aCI) delete aCI;
3218 Standard_ConstructionError::Raise("MakePipeShell failed");
3221 aShape = Sweep.Shape(); //result is good
3223 if (!CreateGroups1(aProfile, Sweep, aCI)) {
3224 if (aCI) delete aCI;
3225 Standard_ConstructionError::Raise("Generate groups failure");
3230 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
3231 BRepOffsetAPI_MakePipe aMkPipe
3232 (aWirePath, aShapeBase, theBestMode, Standard_True);
3234 if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) {
3235 aShape = aMkPipe.Shape();
3237 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipe, aCI)) {
3238 if (aCI) delete aCI;
3239 Standard_ConstructionError::Raise("Generate groups failure");
3241 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
3242 // Try to use Descrete Trihedron mode.
3243 BRepOffsetAPI_MakePipe aMkPipeDescrete
3244 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron, Standard_True);
3246 if (aMkPipeDescrete.IsDone()) {
3247 aShape = aMkPipeDescrete.Shape();
3249 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
3250 if (aCI) delete aCI;
3251 Standard_ConstructionError::Raise("Generate groups failure");
3258 //building pipe with different sections
3259 else if (aType == PIPE_DIFFERENT_SECTIONS) {
3260 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
3261 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
3262 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
3263 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
3264 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
3265 Standard_Boolean isBySteps = aCIDS->GetIsBySteps();
3272 Standard_Integer nbBases = aBasesObjs->Length();
3273 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
3275 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
3276 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
3279 for (i = 1; i <= nbBases; i++) {
3280 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
3281 if (anItem.IsNull())
3283 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
3284 if (aRefBase.IsNull())
3286 if (aRefBase->GetValue().IsNull())
3289 aHSeqBases->Append(aRefBase->GetValue());
3291 for (i = 1; i <= nbLocs; i++) {
3292 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
3293 if (anItemLoc.IsNull())
3295 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
3296 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
3297 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
3300 aHSeqLocs->Append(aShapeLoc);
3304 Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
3305 Handle(TColStd_HArray1OfInteger) aGroups[5];
3307 if (isGenerateGroups) {
3311 aShape = CreatePipeWithDifferentSections
3312 (aWirePath, aHSeqBases, aHSeqLocs,
3313 aWithContact, aWithCorrect, isBySteps, pGroups);
3315 if (isGenerateGroups) {
3316 // Store created groups.
3317 GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
3319 StoreGroups(&aPipeDS, aGroups);
3323 //building pipe with shell sections
3324 else if (aType == PIPE_SHELL_SECTIONS) {
3325 aShape = CreatePipeForShellSections(aWirePath,aCI);
3328 //building pipe shell sections without path
3329 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
3330 aShape = CreatePipeShellsWithoutPath(aCI);
3333 //building a pipe with constant bi-normal along given vector
3334 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
3335 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
3343 if (aShape.IsNull()) return 0;
3345 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
3346 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
3348 if (aType != PIPE_BASE_PATH &&
3349 aType != PIPE_SHELLS_WITHOUT_PATH) {
3350 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
3351 if (anExpV.More()) {
3352 Standard_Real aVertMaxTol = -RealLast();
3353 for (; anExpV.More(); anExpV.Next()) {
3354 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
3355 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
3356 if (aTol > aVertMaxTol)
3359 aVertMaxTol += Precision::Confusion();
3361 TopTools_DataMapOfShapeListOfShape aMapModif;
3362 TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
3364 if (isGenerateGroups) {
3365 pMapModif = &aMapModif;
3368 TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
3369 (aShape, aVertMaxTol, Standard_True, pMapModif);
3371 if (isGenerateGroups && !aMapModif.IsEmpty()) {
3373 GEOMImpl_IPipe aCI(aFunction);
3374 Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
3375 { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
3376 aCI.GetGroupSide2(), aCI.GetGroupOther() };
3377 TopTools_IndexedMapOfShape anIndices;
3378 TopTools_IndexedMapOfShape aNewIndices;
3379 TopTools_SequenceOfShape aNewShapes[5];
3380 TopTools_MapOfShape aMapReplaced;
3381 TopTools_MapOfShape aMapGlued;
3382 Standard_Integer iGrp;
3385 TopExp::MapShapes(aShape, anIndices);
3386 TopExp::MapShapes(aNewShape, aNewIndices);
3388 for (iGrp = 0; iGrp < 5; ++iGrp) {
3389 if (aGroupIDs[iGrp].IsNull() == Standard_False) {
3390 const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
3391 const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
3393 for (i = aLower; i <= anUpper; ++i) {
3394 const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
3395 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
3397 if (aMapModif.IsBound(aSubShape)) {
3398 const TopTools_ListOfShape &aListModif =
3399 aMapModif.Find(aSubShape);
3400 TopTools_ListIteratorOfListOfShape anIter(aListModif);
3402 for (; anIter.More(); anIter.Next()) {
3403 const TopoDS_Shape &aNewShape = anIter.Value();
3405 if (aMapReplaced.Add(aNewShape)) {
3406 aNewShapes[iGrp].Append(aNewShape);
3408 // This is a glued shape. It means that it is internal
3409 // one and should be removed from groups later.
3410 aMapGlued.Add(aNewShape);
3414 // Shape is not modified.
3415 aNewShapes[iGrp].Append(aSubShape);
3421 if (!aMapGlued.IsEmpty()) {
3422 // Remove glued (internal) shapes from groups.
3423 for (iGrp = 0; iGrp < 5; ++iGrp) {
3424 Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
3426 for (i = 1; i < aNbShapes; ++i) {
3427 const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
3429 if (aMapGlued.Contains(aNewShape)) {
3430 aNewShapes[iGrp].Remove(i);
3438 // Store modified groups.
3439 Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
3441 if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
3442 Standard_ConstructionError::Raise("Generate groups failure");
3445 StoreGroups(&aCI, aNewGroupIDs);
3452 // Note: group indices should not be changed after the next call.
3453 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
3454 aFunction->SetValue(aRes);
3456 log->SetTouched(Label());
3460 //================================================================================
3462 * \brief Returns a name of creation operation and names and values of creation parameters
3464 //================================================================================
3466 bool GEOMImpl_PipeDriver::
3467 GetCreationInformation(std::string& theOperationName,
3468 std::vector<GEOM_Param>& theParams)
3470 if (Label().IsNull()) return 0;
3471 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
3472 Standard_Integer aType = function->GetType();
3475 case PIPE_BASE_PATH:
3477 theOperationName = "PIPE";
3478 GEOMImpl_IPipe aCI( function );
3479 AddParam( theParams, "Base Object", aCI.GetBase() );
3480 AddParam( theParams, "Path Object", aCI.GetPath() );
3483 case PIPE_BI_NORMAL_ALONG_VECTOR:
3485 theOperationName = "PIPE";
3486 GEOMImpl_IPipeBiNormal aCI( function );
3487 AddParam( theParams, "Base Object", aCI.GetBase() );
3488 AddParam( theParams, "Path Object", aCI.GetPath() );
3489 AddParam( theParams, "BiNormal", aCI.GetVector() );
3492 case PIPE_DIFFERENT_SECTIONS:
3494 theOperationName = "PIPE";
3495 GEOMImpl_IPipeDiffSect aCI( function );
3496 AddParam( theParams, "Bases", aCI.GetBases() );
3497 AddParam( theParams, "Locations", aCI.GetLocations() );
3498 AddParam( theParams, "Path", aCI.GetPath() );
3500 if (!aCI.GetIsBySteps()) {
3501 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3502 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3505 AddParam( theParams, "Step by step", aCI.GetIsBySteps() );
3508 case PIPE_SHELL_SECTIONS:
3510 theOperationName = "PIPE";
3511 GEOMImpl_IPipeShellSect aCI( function );
3512 AddParam( theParams, "Bases", aCI.GetBases() );
3513 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
3514 AddParam( theParams, "Locations", aCI.GetLocations() );
3515 AddParam( theParams, "Path", aCI.GetPath() );
3516 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3517 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3520 case PIPE_SHELLS_WITHOUT_PATH:
3522 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
3523 GEOMImpl_IPipeShellSect aCI( function );
3524 AddParam( theParams, "Bases", aCI.GetBases() );
3525 AddParam( theParams, "Locations", aCI.GetLocations() );
3535 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver)