1 // Copyright (C) 2007-2024 CEA, EDF, 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 <Basics_OCCTVersion.hxx>
39 #include <ShapeAnalysis_FreeBounds.hxx>
40 #include <ShapeAnalysis_Edge.hxx>
41 #include <ShapeFix_Face.hxx>
42 #include <ShapeFix_Shell.hxx>
44 #include <BRep_Tool.hxx>
45 #include <BRep_Builder.hxx>
46 #include <BRepBuilderAPI_Copy.hxx>
47 #include <BRepBuilderAPI_MakeFace.hxx>
48 #include <BRepBuilderAPI_MakeSolid.hxx>
49 #include <BRepBuilderAPI_MakeWire.hxx>
50 #include <BRepBuilderAPI_Sewing.hxx>
51 #include <BRepClass3d_SolidClassifier.hxx>
52 #include <BRepGProp.hxx>
53 #include <GeomFill_Trihedron.hxx>
54 #include <GeomFill_CorrectedFrenet.hxx>
55 #include <BRepOffsetAPI_MakePipe.hxx>
56 #include <BRepOffsetAPI_MakePipeShell.hxx>
57 #include <BRepOffsetAPI_ThruSections.hxx>
61 #include <TopExp_Explorer.hxx>
63 #include <TopoDS_Wire.hxx>
64 #include <TopoDS_Edge.hxx>
65 #include <TopoDS_Shape.hxx>
66 #include <TopoDS_Solid.hxx>
67 #include <TopoDS_Shell.hxx>
68 #include <TopoDS_Face.hxx>
69 #include <TopoDS_Compound.hxx>
70 #include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
71 #include <TopTools_SequenceOfShape.hxx>
72 #include <TopTools_HSequenceOfShape.hxx>
73 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
74 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
75 #include <TopTools_ListIteratorOfListOfShape.hxx>
76 #include <TopTools_MapIteratorOfMapOfShape.hxx>
78 #include <GProp_GProps.hxx>
80 #include <GeomAPI_ProjectPointOnCurve.hxx>
81 #include <GeomAPI_Interpolate.hxx>
82 #include <Geom_TrimmedCurve.hxx>
83 #include <Geom_Plane.hxx>
84 #include <Geom_RectangularTrimmedSurface.hxx>
85 #include <Geom_BezierSurface.hxx>
86 #include <Geom_Line.hxx>
87 #include <Geom_Conic.hxx>
88 #include <Geom_BSplineCurve.hxx>
89 #include <Geom_BSplineSurface.hxx>
90 #if OCC_VERSION_LARGE < 0x07070000
91 #include <GeomAdaptor_HCurve.hxx>
93 #include <GeomAdaptor_Curve.hxx>
95 #include <GeomFill_BSplineCurves.hxx>
96 #include <GeomConvert_ApproxCurve.hxx>
97 #include <GeomConvert.hxx>
99 #include <TColgp_SequenceOfPnt.hxx>
100 #include <TColgp_HArray1OfPnt.hxx>
101 #include <TColgp_Array2OfPnt.hxx>
102 #include <TColStd_HSequenceOfTransient.hxx>
104 #include <Precision.hxx>
106 #include <Standard_NullObject.hxx>
107 #include <Standard_TypeMismatch.hxx>
108 #include <Standard_ConstructionError.hxx>
110 #include "utilities.h"
114 #define GROUP_SIDE1 2
115 #define GROUP_SIDE2 3
116 #define GROUP_OTHER 4
118 static const Standard_Real TolPipeSurf = 5.e-4;
120 static bool FillGroups(const TopTools_SequenceOfShape *theGroups,
121 const TopTools_IndexedMapOfShape &theIndices,
122 Handle(TColStd_HArray1OfInteger) *theGroupIds);
124 static void StoreGroups(GEOMImpl_IPipe *theCI,
125 Handle(TColStd_HArray1OfInteger) *theGroups);
127 // after OCCT improvement
128 static bool DoGroups1(const TopoDS_Shape &theProfile,
129 BRepOffsetAPI_MakePipeShell &theSweep,
130 TopTools_SequenceOfShape *theGroups);
132 static bool CreateGroups1(const TopoDS_Shape &theProfile,
133 BRepOffsetAPI_MakePipeShell &theSweep,
134 GEOMImpl_IPipe *theCI);
136 //=======================================================================
139 //=======================================================================
140 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
142 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
146 //=======================================================================
147 //function : GEOMImpl_PipeDriver
149 //=======================================================================
150 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
154 //=======================================================================
155 //function : EvaluateBestSweepMode
156 //purpose : auxiliary for right call of MakePipe and MakePipeShell
157 //=======================================================================
158 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
160 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
162 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
163 for (; Explo.More(); Explo.Next())
165 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
166 Standard_Real fpar, lpar;
167 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
168 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
169 #if OCC_VERSION_LARGE < 0x07070000
170 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
172 Handle(GeomAdaptor_Curve) GAHcurve = new GeomAdaptor_Curve(GAcurve);
175 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
176 aCorrFrenet->SetCurve(GAHcurve);
177 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
178 if (aMode == GeomFill_IsDiscreteTrihedron)
183 if (aMode == GeomFill_IsCorrectedFrenet)
190 //=======================================================================
191 //function : BuildPipeShell
192 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
193 // mode. Returns Standard_True if the building is done successfully.
194 //=======================================================================
195 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
197 // Commented out for bos #20438
198 //theBuilder.SetForceApproxC1(Standard_True);
202 Standard_Boolean isDone = theBuilder.IsDone();
205 theBuilder.ErrorOnSurface() > TolPipeSurf) {
206 // Try to use Descrete Trihedron mode.
207 theBuilder.SetDiscreteMode();
209 isDone = theBuilder.IsDone();
215 //=======================================================================
216 //function : FillForOtherEdges
217 //purpose : auxiliary for CreatePipeForShellSections()
218 //=======================================================================
219 static bool FillForOtherEdges(const TopoDS_Shape& F1,
220 const TopoDS_Shape& E1,
221 const TopoDS_Shape& V1,
222 TopTools_IndexedDataMapOfShapeShape& FF)
224 // find other pairs for vertexes and edges
225 // creating map of vertex edges for both faces
226 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
227 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
228 if (!FF.Contains(F1)) MESSAGE(" FillForOtherEdges: map FF not contains key F1");
229 if (!FF.Contains(E1)) MESSAGE(" FillForOtherEdges: map FF not contains key E1");
230 if (!FF.Contains(V1)) MESSAGE(" FillForOtherEdges: map FF not contains key V1");
231 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
232 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
233 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
234 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
235 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
237 TopoDS_Edge ES1 = TopoDS::Edge(E1);
238 TopoDS_Edge ES2 = TopoDS::Edge(E2);
239 TopoDS_Shape VS1 = V1;
240 TopoDS_Shape VS2 = V2;
242 ShapeAnalysis_Edge sae;
244 if (!aMapVertEdge1.Contains(VS1)) MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
245 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
246 TopTools_ListIteratorOfListOfShape anIter1(aList1);
247 if (anIter1.Value().IsSame(ES1)) {
250 if (!aMapVertEdge2.Contains(VS2)) MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
251 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
252 TopTools_ListIteratorOfListOfShape anIter2(aList2);
253 if (anIter2.Value().IsSame(ES2)) {
256 ES1 = TopoDS::Edge(anIter1.Value());
257 ES2 = TopoDS::Edge(anIter2.Value());
258 if (!FF.Contains(ES1)) {
261 if (VS1.IsSame(sae.FirstVertex(ES1)))
262 VS1 = sae.LastVertex(ES1);
264 VS1 = sae.FirstVertex(ES1);
265 if (VS2.IsSame(sae.FirstVertex(ES2)))
266 VS2 = sae.LastVertex(ES2);
268 VS2 = sae.FirstVertex(ES2);
271 if (!FF.Contains(VS1)) {
279 //=======================================================================
280 //function : FillCorrespondingEdges
281 //purpose : auxiliary for CreatePipeForShellSections()
282 //=======================================================================
283 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
284 const TopoDS_Shape& FS2,
285 const TopoDS_Vertex& aLoc1,
286 const TopoDS_Vertex& aLoc2,
287 const TopoDS_Wire& aWirePath,
288 TopTools_IndexedDataMapOfShapeShape& FF)
290 // find corresponding edges
291 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
292 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
293 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
294 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
295 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
296 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
297 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
298 if (theBestMode == GeomFill_IsDiscreteTrihedron)
299 aBuilder.SetDiscreteMode();
300 aBuilder.Add(aWire1, aLoc1);
301 aBuilder.Add(aWire2, aLoc2);
302 if (!aBuilder.IsReady()) {
306 BuildPipeShell(aBuilder);
308 TopoDS_Shape aShape = aBuilder.Shape();
309 ShapeAnalysis_Edge sae;
310 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
311 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
312 TopTools_MapOfShape Vs1,Vs2;
314 exp.Init(FS1, TopAbs_EDGE);
315 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
316 TopoDS_Vertex V11 = sae.FirstVertex(E1);
317 TopoDS_Vertex V21 = sae.LastVertex(E1);
318 gp_Pnt P11 = BRep_Tool::Pnt(V11);
319 gp_Pnt P21 = BRep_Tool::Pnt(V21);
320 // find corresponding vertexes from created shape
321 TopoDS_Vertex VN11,VN21;
322 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
323 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
324 gp_Pnt P = BRep_Tool::Pnt(V);
325 if (P.Distance(P11)<tol) {
328 if (P.Distance(P21)<tol) {
332 // find edge contains VN11 and VN21 and corresponding vertexes
333 TopoDS_Vertex VN12,VN22;
334 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
335 TopoDS_Shape F = exp.Current();
336 TopExp_Explorer expe;
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)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
348 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
349 TopoDS_Edge E = TopoDS::Edge(expe.Current());
350 TopoDS_Vertex VF = sae.FirstVertex(E);
351 TopoDS_Vertex VL = sae.LastVertex(E);
352 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
354 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
356 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
358 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
364 // find vertexes from FS2 corresponded to VN12 and VN22
365 // and find edge from FS2 contains V12 and V22,
366 // this edge will be corresponded to edge E1
367 TopoDS_Vertex V12,V22;
368 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
369 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
371 TopExp_Explorer expe;
372 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
373 TopoDS_Edge E = TopoDS::Edge(expe.Current());
374 TopoDS_Vertex VF = sae.FirstVertex(E);
375 TopoDS_Vertex VL = sae.LastVertex(E);
376 gp_Pnt PF = BRep_Tool::Pnt(VF);
377 gp_Pnt PL = BRep_Tool::Pnt(VL);
378 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
384 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
395 // find other pairs for vertexes and edges
396 // creating map of vertex edges for both faces
397 return FillForOtherEdges(FS1,E1,V21,FF);
402 //=======================================================================
403 //function : FillCorrespondingEdges
404 //purpose : auxiliary for CreatePipeShellsWithoutPath()
405 //=======================================================================
406 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
407 const TopoDS_Shape& FS2,
408 const TopoDS_Vertex& aLoc1,
409 const TopoDS_Vertex& aLoc2,
410 TopTools_IndexedDataMapOfShapeShape& FF)
412 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
413 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
416 ShapeAnalysis_Edge sae;
417 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
418 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
419 TopTools_MapOfShape Vs1,Vs2;
421 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
424 TopExp_Explorer exp1;
425 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
426 E1 = TopoDS::Edge(exp1.Current());
427 TopoDS_Vertex V1 = sae.FirstVertex(E1);
428 TopoDS_Vertex V2 = sae.LastVertex(E1);
429 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
430 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
431 if (P1.Distance(Ptmp1)<tol) {
435 if (P1.Distance(Ptmp2)<tol) {
442 TopoDS_Vertex VE21,VE22;
444 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
445 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
446 TopoDS_Vertex V1 = sae.FirstVertex(E);
447 TopoDS_Vertex V2 = sae.LastVertex(E);
448 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
449 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
450 if (P2.Distance(Ptmp1)<tol) {
462 if (P2.Distance(Ptmp2)<tol) {
476 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
477 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
478 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
479 gp_Vec aDir1(PV21,PE21);
480 gp_Vec aDir2(PV21,PE22);
481 double ang1 = aDir.Angle(aDir1);
482 double ang2 = aDir.Angle(aDir2);
483 if (fabs(ang1)<fabs(ang2)) {
496 // find other pairs for vertexes and edges
497 return FillForOtherEdges(FS1,E1,V21,FF);
500 //=======================================================================
501 //function : FindNextPairOfFaces
502 //purpose : auxiliary for CreatePipeForShellSections()
503 //=======================================================================
504 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
505 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
506 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
507 TopTools_IndexedDataMapOfShapeShape& FF,
510 TopExp_Explorer anExp;
511 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
512 TopoDS_Shape E1 = anExp.Current();
513 if (!FF.Contains(E1)) {
515 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
517 if (!FF.Contains(E1)) MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
518 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
519 TopExp_Explorer anExpV;
520 anExpV.Init(E1, TopAbs_VERTEX);
521 TopoDS_Shape V1 = anExpV.Current();
522 if (!FF.Contains(V1)) {
524 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
527 if (!aMapEdgeFaces1.Contains(E1)) MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
528 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
529 if (aList1.Extent()<2)
531 TopTools_ListIteratorOfListOfShape anIter(aList1);
532 if (anIter.Value().IsEqual(aCurFace)) {
535 TopoDS_Shape F1other = anIter.Value();
536 if (FF.Contains(F1other))
539 if (!FF.Contains(aCurFace)) MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
540 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
541 if (!aMapEdgeFaces2.Contains(E2)) MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
542 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
543 if (aList2.Extent()<2) {
545 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
547 TopTools_ListIteratorOfListOfShape anIter2(aList2);
548 if (anIter2.Value().IsEqual(F2)) {
551 TopoDS_Shape F2other = anIter2.Value();
552 FF.Add(F1other,F2other);
554 // add pairs of edges to FF
555 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
558 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not map other edges");
561 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
565 //=======================================================================
566 //function : FindFirstPairFaces
567 //purpose : auxiliary for Execute()
568 //=======================================================================
569 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
570 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
571 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
573 // check if vertexes are sub-shapes of sections
574 gp_Pnt P1 = BRep_Tool::Pnt(V1);
575 gp_Pnt P2 = BRep_Tool::Pnt(V2);
576 TopoDS_Vertex V1new,V2new;
578 double mindist = 1.e10;
579 for (exp.Init(S1, 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 = P1.Distance(P);
589 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
590 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
591 gp_Pnt P = BRep_Tool::Pnt(V);
592 double dist = P2.Distance(P);
599 // replace vertexes if it is needed
600 if (!V1.IsSame(V1new)) {
602 P1 = BRep_Tool::Pnt(V1);
603 MESSAGE (" replace V1");
606 MESSAGE (" not replace V1");
607 if (!V2.IsSame(V2new)) {
609 P2 = BRep_Tool::Pnt(V2);
610 MESSAGE (" replace V2");
613 MESSAGE (" not replace V2");
615 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
616 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
617 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
618 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
620 if (!aMapVertFaces1.Contains(V1))
621 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
622 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
623 TopTools_ListIteratorOfListOfShape anIter1(aList1);
624 FS1 = anIter1.Value();
626 double x1=0., y1=0., z1=0.;
628 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
629 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
630 gp_Pnt P = BRep_Tool::Pnt(V);
636 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
638 TColgp_SequenceOfPnt Ps;
639 TopTools_SequenceOfShape Fs;
640 if (!aMapVertFaces2.Contains(V2))
641 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
642 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
643 TopTools_ListIteratorOfListOfShape anIter2(aList2);
644 for (; anIter2.More(); anIter2.Next()) {
645 TopoDS_Shape F = anIter2.Value();
646 double x2=0., y2=0., z2=0.;
648 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
649 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
650 gp_Pnt P = BRep_Tool::Pnt(V);
656 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
663 double MinAng = M_PI;
665 for (; i<=Fs.Length(); i++) {
666 gp_Vec tmpDir(PM1,Ps(i));
667 double ang = fabs(aDir.Angle(tmpDir));
676 //=======================================================================
677 //function : RemoveFaces
678 //purpose : This function returns theShapeFrom without faces of the shape
679 // theFacesToRm. It returns a shell if theShapeFrom is a solid or
680 // a compound otherwise. Auxiliary for CreatePipeWithDifferentSections
682 //=======================================================================
683 static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom,
684 const TopoDS_Shape &theFacesToRm)
686 TopTools_IndexedMapOfShape aMapFaces;
687 TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE);
688 BRep_Builder aBuilder;
689 TopoDS_Shape aResult;
691 if (theShapeFrom.ShapeType() == TopAbs_SOLID) {
693 aBuilder.MakeShell(TopoDS::Shell(aResult));
696 aBuilder.MakeCompound(TopoDS::Compound(aResult));
699 TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces);
701 for (; anExp.More(); anExp.Next()) {
702 const TopoDS_Shape &aFace = anExp.Current();
704 if (!aMapFaces.Contains(aFace)) {
705 aBuilder.Add(aResult, aFace);
712 //=======================================================================
713 //function : makeSolid
714 //purpose : auxiliary for CreatePipeWithDifferentSections
715 //=======================================================================
716 Standard_Boolean makeSolid(
717 BRepOffsetAPI_MakePipeShell aBuilder,
718 const TopoDS_Shape& aSh1,
719 const TopoDS_Shape& aSh2,
720 TopoDS_Shape& aShape)
722 Standard_Boolean isDone = Standard_True;
723 Standard_Integer nbPlanar = 0;
724 if (aSh1.ShapeType() == TopAbs_FACE && aSh2.ShapeType() == TopAbs_FACE)
726 Handle(Geom_Surface) aS = BRep_Tool::Surface(TopoDS::Face(aSh1));
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))) {
736 aS = BRep_Tool::Surface(TopoDS::Face(aSh2));
737 if (aS->IsKind(STANDARD_TYPE(Geom_Plane))) {
740 else if (aS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
741 Handle(Geom_RectangularTrimmedSurface) aTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
742 if (aTS->BasisSurface()->IsKind(STANDARD_TYPE(Geom_Plane))) {
748 TopoDS_Shape aPipe = aBuilder.Shape();
749 // make sewing for result
750 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
751 Standard_Real aTol = Precision::Confusion();
752 aSewing->SetTolerance(aTol);
753 aSewing->SetFaceMode(Standard_True);
754 aSewing->SetFloatingEdgesMode(Standard_False);
755 aSewing->SetNonManifoldMode(Standard_False);
756 TopExp_Explorer anExp;
757 for (anExp.Init(aPipe, TopAbs_FACE); anExp.More(); anExp.Next()) {
758 aSewing->Add(anExp.Current());
763 aShape = aSewing->SewedShape();
764 if (aShape.ShapeType() == TopAbs_SHELL) {
766 BRepBuilderAPI_MakeSolid aMkSolid;
767 aMkSolid.Add(TopoDS::Shell(aShape));
768 if (!aMkSolid.IsDone()) {
769 isDone = Standard_False;
772 TopoDS_Solid aSolid = aMkSolid.Solid();
773 BRepClass3d_SolidClassifier aSC(aSolid);
774 aSC.PerformInfinitePoint(Precision::Confusion());
775 if (aSC.State() == TopAbs_IN) {
776 aShape = aSolid.Reversed();
784 isDone = Standard_False;
788 isDone = Standard_False;
791 isDone = aBuilder.MakeSolid();
793 aShape = aBuilder.Shape();
799 //=======================================================================
800 //function : CreatePipeWithDifferentSections
802 //=======================================================================
803 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
804 (const TopoDS_Wire &theWirePath,
805 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
806 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
807 const Standard_Boolean theWithContact,
808 const Standard_Boolean theWithCorrect,
809 const Standard_Boolean IsBySteps,
810 Handle(TColStd_HArray1OfInteger) *theGroups)
814 TopoDS_Wire aWirePath = theWirePath;
816 Standard_Integer nbBases = theHSeqBases->Length();
817 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
819 if (nbLocs && nbLocs != nbBases) {
820 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
823 TopTools_SequenceOfShape aSeqBases;
824 TopTools_SequenceOfShape aSeqLocs;
825 TopTools_SequenceOfShape aSeqFaces;
826 Standard_Boolean NeedCreateSolid = Standard_False;
828 Standard_Integer i = 1;
829 for (i = 1; i <= nbBases; i++) {
830 if (theHSeqBases->Value(i).IsNull())
833 // Make copy to prevent modifying of base object 0020766 : EDF 1320
834 TopoDS_Shape aShapeBase;
835 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
837 aShapeBase = Copy.Shape();
839 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
841 //if for section was specified face with a few wires then a few
842 // pipes were build and make solid
843 if (aTypeBase == TopAbs_SHELL) {
844 // create wire as boundary contour if shell is no closed
845 // get free boundary shapes
846 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
847 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
848 TopExp_Explorer anExp;
850 Standard_Integer NbWires = 0;
851 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
853 aWire = anExp.Current();
857 Standard_ConstructionError::Raise("Bad shell is used as section ");
859 NeedCreateSolid = Standard_True;
860 aSeqFaces.Append(aShapeBase);
861 aSeqBases.Append(aWire);
863 else if (aTypeBase == TopAbs_FACE) {
864 NeedCreateSolid = Standard_True;
865 //for case one path should be used other type function
866 aSeqFaces.Append(aShapeBase);
867 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
868 for (; aExpW.More(); aExpW.Next()) {
869 TopoDS_Shape aWireProf = aExpW.Current();
870 aSeqBases.Append(aWireProf);
873 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
874 aSeqBases.Append(aShapeBase);
876 else if (aTypeBase == TopAbs_EDGE) {
877 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
878 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
879 aSeqBases.Append(aWireProf);
882 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
883 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
885 aSeqLocs.Append(aShapeLoc);
889 nbLocs = aSeqLocs.Length();
892 TopTools_SequenceOfShape Edges;
894 // we have to check that each location shape is a vertex from
895 // path and update aSeqLocs if it is needed (and possible)
896 TColgp_SequenceOfPnt PLocs;
897 for (i=1; i<=nbLocs; i++) {
898 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
899 PLocs.Append(BRep_Tool::Pnt(V));
901 //TopTools_SequenceOfShape Edges;
902 TopExp_Explorer anExp;
903 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
904 Edges.Append(anExp.Current());
906 int nbEdges = Edges.Length();
907 ShapeAnalysis_Edge sae;
908 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
909 double tol = BRep_Tool::Tolerance(edge);
910 TopoDS_Vertex VF = sae.FirstVertex(edge);
911 gp_Pnt PF = BRep_Tool::Pnt(VF);
912 if (PF.Distance(PLocs.First()) > tol) {
913 Standard_ConstructionError::Raise
914 ("First location shapes is not coincided with first vertex of aWirePath");
916 aSeqLocs.ChangeValue(1) = VF;
917 edge = TopoDS::Edge(Edges.Last());
918 tol = BRep_Tool::Tolerance(edge);
919 TopoDS_Vertex VL = sae.LastVertex(edge);
920 gp_Pnt PL = BRep_Tool::Pnt(VL);
921 if (PL.Distance(PLocs.Last()) > tol) {
922 Standard_ConstructionError::Raise
923 ("Last location shapes is not coincided with last vertex of aWirePath");
925 aSeqLocs.ChangeValue(nbLocs) = VL;
927 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
928 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
929 tol = BRep_Tool::Tolerance(edge);
930 TopoDS_Vertex V1 = sae.FirstVertex(E);
931 TopoDS_Vertex V2 = sae.LastVertex(E);
932 gp_Pnt P1 = BRep_Tool::Pnt(V1);
933 gp_Pnt P2 = BRep_Tool::Pnt(V2);
934 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
935 aSeqLocs.ChangeValue(jcurr) = V2;
939 // find distance between E and aLocs(jcurr)
941 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
942 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
943 if (PPCurve.NbPoints()>0 &&
944 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
945 double param = PPCurve.Parameter(1);
948 // split current edge
949 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
950 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
955 if (Pfp.Distance(P1)<tol) {
956 B.MakeEdge(E1,tc1,tol);
958 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
959 B.Add(E1,TopoDS::Vertex(tmpV));
960 B.MakeEdge(E2,tc2,tol);
961 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
962 B.Add(E2,TopoDS::Vertex(tmpV));
966 B.MakeEdge(E1,tc2,tol);
967 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
968 B.Add(E1,TopoDS::Vertex(tmpV));
971 B.MakeEdge(E2,tc1,tol);
973 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
974 B.Add(E2,TopoDS::Vertex(tmpV));
979 Edges.InsertAfter(i-1,E1);
980 Edges.InsertAfter(i,E2);
984 if (nbEdges<Edges.Length()) {
985 // one of edges was split => we have to update WirePath
989 for (i=1; i<=Edges.Length(); i++) {
990 B.Add(W,TopoDS::Edge(Edges.Value(i)));
996 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
999 // Fill SplitEdgeNums and SplitLocNums with intermediate location indices
1000 // and corresponding edge indices.
1001 Standard_Integer i = 1;
1003 TopoDS_Vertex aVert;
1006 for (j = 2; j < aSeqLocs.Length(); j++) {
1007 SplitLocNums.Append(j);
1008 aVert = TopoDS::Vertex(aSeqLocs.Value(j));
1009 aP = BRep_Tool::Pnt(aVert);
1011 while (i < Edges.Length()) {
1014 TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i));
1015 Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
1016 Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp);
1019 aC->D0(aLp, aPLast);
1022 if (aP.Distance(aPLast) < aTol) {
1023 SplitEdgeNums.Append(i - 1);
1029 // check curvature of wire for condition that
1030 // max summary angle between directions along
1031 // wire path must be < 4*PI. If not - split wire
1032 // and seguences of shapes, perform pipe for each
1033 // and make sewing after that
1038 if ( Edges.Length() > 0 ) {
1039 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
1042 SumAng = fabs(Vec1.Angle(Vec2));
1047 for (i=2; i<=Edges.Length(); i++) {
1048 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
1049 double tol = BRep_Tool::Tolerance(edge);
1050 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
1052 double ang = fabs(Vec1.Angle(Vec2));
1054 if (SumAng>4*M_PI) {
1056 SplitEdgeNums.Append(i-1);
1058 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
1059 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
1060 gp_Pnt P = BRep_Tool::Pnt(aVert);
1061 if (P1.Distance(P) < tol) {
1062 SplitLocNums.Append(j);
1073 bool isCreateGroups = (theGroups != NULL);
1075 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
1076 TopTools_SequenceOfShape aSeqRes;
1077 TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
1078 Standard_Integer iGrp;
1079 int nn, num1 = 1, num2 = 1;
1080 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
1081 // create wirepath and sequences of shapes
1085 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
1086 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1088 num1 = SplitEdgeNums.Value(nn) + 1;
1089 TopTools_SequenceOfShape aTmpSeqBases;
1090 TopTools_SequenceOfShape aTmpSeqLocs;
1091 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
1092 aTmpSeqBases.Append(aSeqBases.Value(i));
1093 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1095 num2 = SplitLocNums.Value(nn);
1097 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1098 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1099 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1100 aBuilder.SetDiscreteMode();
1101 Standard_Integer nbShapes = aTmpSeqBases.Length();
1102 for (i=1; i<=nbShapes; i++) {
1103 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1104 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1105 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1107 if (!aBuilder.IsReady()) {
1108 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1111 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1113 if (isDone && NeedCreateSolid && nn == 1) {
1114 // Make solid for the first step.
1115 isDone = aBuilder.MakeSolid();
1119 Standard_ConstructionError::Raise("Pipe construction failure");
1122 TopoDS_Shape resShape = aBuilder.Shape();
1124 if (NeedCreateSolid && nn == 1) {
1125 // Remove top lid from the result.
1126 resShape = RemoveFaces(resShape, aBuilder.LastShape());
1129 aSeqRes.Append(resShape);
1132 if (isCreateGroups) {
1134 TopTools_SequenceOfShape aGroups[5];
1136 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1137 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1138 Standard_ConstructionError::Raise("Generate groups failure");
1141 // Get shapes from all groups.
1142 for (iGrp = 0; iGrp < 5; ++iGrp) {
1143 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1147 // create wirepath and sequences of shapes for last part
1151 for (i=num1; i<=Edges.Length(); i++) {
1152 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1154 TopTools_SequenceOfShape aTmpSeqBases;
1155 TopTools_SequenceOfShape aTmpSeqLocs;
1156 for (i=num2; i<=aSeqLocs.Length(); i++) {
1157 aTmpSeqBases.Append(aSeqBases.Value(i));
1158 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1160 // make pipe for last part
1161 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1162 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1163 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1164 aBuilder.SetDiscreteMode();
1165 Standard_Integer nbShapes = aTmpSeqBases.Length();
1166 for (i=1; i<=nbShapes; i++) {
1167 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1168 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1169 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1171 if (!aBuilder.IsReady()) {
1172 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1175 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1177 if (isDone && NeedCreateSolid) {
1178 isDone = aBuilder.MakeSolid();
1182 Standard_ConstructionError::Raise("Pipe construction failure");
1185 TopoDS_Shape resShape = aBuilder.Shape();
1187 if (NeedCreateSolid) {
1188 // Remove bottom lid from the result.
1189 resShape = RemoveFaces(resShape, aBuilder.FirstShape());
1192 aSeqRes.Append(resShape);
1195 if (isCreateGroups) {
1197 TopTools_SequenceOfShape aGroups[5];
1199 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1200 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1201 Standard_ConstructionError::Raise("Generate groups failure");
1204 // Get shapes from all groups.
1205 for (iGrp = 0; iGrp < 5; ++iGrp) {
1206 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1210 // make sewing for result
1211 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1212 aSewing->SetTolerance(Precision::Confusion());
1213 aSewing->SetFaceMode(Standard_True);
1214 aSewing->SetFloatingEdgesMode(Standard_False);
1215 aSewing->SetNonManifoldMode(Standard_False);
1216 for (i=1; i<=aSeqRes.Length(); i++) {
1217 aSewing->Add(aSeqRes.Value(i));
1220 aShape = aSewing->SewedShape();
1222 if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) {
1224 BRepBuilderAPI_MakeSolid aMkSolid;
1226 aMkSolid.Add(TopoDS::Shell(aShape));
1228 if (!aMkSolid.IsDone()) {
1229 Standard_ConstructionError::Raise("Can't create solid pipe");
1232 TopoDS_Solid aSolid = aMkSolid.Solid();
1233 BRepClass3d_SolidClassifier aSC(aSolid);
1235 aSC.PerformInfinitePoint(Precision::Confusion());
1237 if (aSC.State() == TopAbs_IN) {
1238 aShape = aSolid.Reversed();
1244 if (isCreateGroups) {
1245 // Replase Group shapes by modified ones.
1246 TopTools_SequenceOfShape aSeqGroups[5];
1249 for (iGrp = 0; iGrp < 5; ++iGrp) {
1251 for (i = 1; i <= aSeqRes.Length(); ++i) {
1252 if (iGrp == GROUP_DOWN && i > 1) {
1253 // For DOWN group we use only the first pipe.
1257 if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
1258 // For UP group we use only the last pipe.
1262 const TopTools_SequenceOfShape &aShapes =
1263 aMapResGroups[iGrp].Find(aSeqRes.Value(i));
1266 // For each sub-shape of pipe
1267 for (j = 1; j <= aShapes.Length(); ++j) {
1268 const TopoDS_Shape &aGrpShape = aShapes.Value(j);
1270 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1271 // Use the shape modified by sewing.
1272 const TopoDS_Shape &aModifGrpShape =
1273 aSewing->ModifiedSubShape(aGrpShape);
1275 aSeqGroups[iGrp].Append(aModifGrpShape);
1277 // Use the shape as it is.
1278 aSeqGroups[iGrp].Append(aGrpShape);
1285 TopTools_IndexedMapOfShape anIndices;
1287 TopExp::MapShapes(aShape, anIndices);
1289 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1290 Standard_ConstructionError::Raise("Generate groups failure");
1295 // old implementation without splitting
1297 // Generally, we should better use BRepOffsetAPI_ThruSections algorithm if
1298 // 1) the path is a polyline, and
1299 // 2) all break points of the path have correspondent sections
1300 bool doThruSections = false;
1301 if (!theWithContact && !theWithCorrect && theGroups == NULL &&
1302 nbBases == Edges.Length() + 1) {
1303 doThruSections = true;
1304 // check if all edges are lines
1305 Standard_Real aFP, aLP;
1306 for (int ie = 1; ie <= Edges.Length() && doThruSections; ie++) {
1307 TopoDS_Edge anE = TopoDS::Edge(Edges.Value(ie));
1308 Handle(Geom_Curve) aC = BRep_Tool::Curve(anE, aFP, aLP);
1310 while(aC->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
1311 Handle(Geom_TrimmedCurve) aTc = Handle(Geom_TrimmedCurve)::DownCast(aC);
1312 aC = aTc->BasisCurve();
1314 if (!aC->IsKind(STANDARD_TYPE(Geom_Line)))
1315 doThruSections = false;
1320 if (doThruSections) {
1321 BRepOffsetAPI_ThruSections aBuilder (NeedCreateSolid, Standard_True, Precision::Confusion()*10.0);
1322 aBuilder.CheckCompatibility(Standard_False);
1324 for (int ibase = 1; ibase <= nbBases; ibase++) {
1325 TopoDS_Shape aBase = aSeqBases.Value(ibase);
1326 aBuilder.AddWire(TopoDS::Wire(aBase));
1330 aShape = aBuilder.Shape();
1333 // old implementation without splitting
1334 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1335 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1336 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1337 aBuilder.SetDiscreteMode();
1339 Standard_Integer nbShapes = aSeqBases.Length();
1340 Standard_Integer step = nbShapes/nbBases;
1342 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1343 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1345 Standard_Integer ind =0;
1346 Standard_Real aTolConf = Precision::Confusion();
1347 Standard_Real aTolAng = Precision::Angular();
1349 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1350 TopTools_SequenceOfShape usedBases;
1351 Standard_Integer j = 1;
1352 for (; j <= nbBases; j++) {
1353 ind = i + (j-1)*step;
1354 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1355 usedBases.Append(aWireProf);
1357 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1358 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1359 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1362 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1364 if (!aBuilder.IsReady()) {
1365 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1368 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1370 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1373 if (NeedCreateSolid) {
1374 TopoDS_Shape aSh1 = aSeqFaces.Value(1);
1375 TopoDS_Shape aSh2 = aSeqFaces.Value(aSeqFaces.Length());
1376 isDone = makeSolid(aBuilder, aSh1, aSh2, aShape);
1379 aShape = aBuilder.Shape();
1384 Standard_ConstructionError::Raise("Pipe construction failure");
1387 if (isCreateGroups) {
1389 TopTools_SequenceOfShape aSeqGroups[5];
1391 TopoDS_Shape aProfile = usedBases.Value(1);
1392 if (!DoGroups1(aProfile, aBuilder, aSeqGroups)) {
1393 Standard_ConstructionError::Raise("Generate groups failure");
1397 //Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1398 TopTools_IndexedMapOfShape anIndices;
1399 const TopoDS_Shape aResult = aBuilder.Shape();
1401 TopExp::MapShapes(aResult, anIndices);
1403 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1404 Standard_ConstructionError::Raise("Generate groups failure");
1407 aSeqFaces.Append(aShape);
1408 for (j = 1; j <=usedBases.Length(); j++)
1409 aBuilder.Delete(usedBases.Value(j));
1417 //=======================================================================
1418 //function : CreatePipeForShellSections
1419 //purpose : auxiliary for Execute()
1420 //=======================================================================
1421 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1422 GEOMImpl_IPipe* aCI)
1427 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1428 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1429 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1430 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1431 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1432 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1433 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1435 Standard_Integer nbBases = aBasesObjs->Length(),
1436 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1437 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1439 if (nbLocs != nbBases) {
1440 if (aCI) delete aCI;
1441 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1443 if (nbSubBases && nbSubBases != nbBases) {
1444 if (aCI) delete aCI;
1445 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1448 TopTools_SequenceOfShape VLocs;
1449 for (i=1; i<=nbBases; i++) {
1450 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1451 if (anItemLoc.IsNull())
1453 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1454 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1455 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1457 VLocs.Append(aShapeLoc);
1459 nbLocs = VLocs.Length();
1460 if (nbLocs != nbBases) {
1461 if (aCI) delete aCI;
1462 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1464 // split wire path by location points
1465 TColgp_SequenceOfPnt PLocs;
1466 for (i=1; i<=nbLocs; i++) {
1467 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1468 PLocs.Append(BRep_Tool::Pnt(V));
1471 TopTools_SequenceOfShape Edges;
1472 TopTools_SequenceOfShape Wires;
1473 ShapeAnalysis_Edge sae;
1476 TopExp_Explorer anExp;
1477 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1478 Edges.Append(anExp.Current());
1480 Standard_Integer Num1 = 0;
1481 Standard_Integer Num2 = 0;
1482 for (i=1; i<=Edges.Length(); i++) {
1483 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1484 double tol = BRep_Tool::Tolerance(E);
1485 TopoDS_Vertex V1 = sae.FirstVertex(E);
1486 TopoDS_Vertex V2 = sae.LastVertex(E);
1487 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1488 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1489 if (P1.Distance(PLocs.First()) < tol) {
1492 if (P2.Distance(PLocs.Last()) < tol) {
1496 if (Num1>0 && Num2>0) {
1499 for (i=Num1; i<=Num2; i++) {
1500 B.Add(W,Edges.Value(i));
1505 Wires.Append(aWirePath);
1509 TopExp_Explorer anExp;
1510 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1511 Edges.Append(anExp.Current());
1513 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1514 double tol = BRep_Tool::Tolerance(edge);
1515 TopoDS_Vertex VF = sae.FirstVertex(edge);
1516 gp_Pnt PF = BRep_Tool::Pnt(VF);
1517 if (PF.Distance(PLocs.First()) > tol) {
1518 if (aCI) delete aCI;
1519 Standard_ConstructionError::Raise
1520 ("First location shapes is not coincided with first vertex of aWirePath");
1522 VLocs.ChangeValue(1) = VF;
1523 edge = TopoDS::Edge(Edges.Last());
1524 tol = BRep_Tool::Tolerance(edge);
1525 TopoDS_Vertex VL = sae.LastVertex(edge);
1526 gp_Pnt PL = BRep_Tool::Pnt(VL);
1527 if (PL.Distance(PLocs.Last()) > tol) {
1528 if (aCI) delete aCI;
1529 Standard_ConstructionError::Raise
1530 ("Last location shapes is not coincided with last vertex of aWirePath");
1532 VLocs.ChangeValue(nbLocs) = VL;
1534 TopTools_SequenceOfShape tmpEdges;
1535 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1536 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1537 tol = BRep_Tool::Tolerance(E);
1538 TopoDS_Vertex V1 = sae.FirstVertex(E);
1539 TopoDS_Vertex V2 = sae.LastVertex(E);
1540 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1541 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1542 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1543 // make wire from current edge and add created
1547 for (j=1; j<=tmpEdges.Length(); j++)
1548 B.Add(W,tmpEdges.Value(j));
1551 VLocs.ChangeValue(jcurr) = V2;
1556 // find distance between E and aLocs(jcurr)
1558 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1559 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1560 if (PPCurve.NbPoints()>0 &&
1561 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1562 double param = PPCurve.Parameter(1);
1565 // split current edge
1566 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1567 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1571 if (Pfp.Distance(P1)<tol) {
1572 B.MakeEdge(E1,tc1,tol);
1574 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1575 B.Add(E1,TopoDS::Vertex(tmpV));
1576 tmpEdges.Append(E1);
1577 B.MakeEdge(E2,tc2,tol);
1578 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1579 B.Add(E2,TopoDS::Vertex(tmpV));
1583 B.MakeEdge(E1,tc2,tol);
1584 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1585 B.Add(E1,TopoDS::Vertex(tmpV));
1588 tmpEdges.Append(E1);
1589 B.MakeEdge(E2,tc1,tol);
1591 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1592 B.Add(E2,TopoDS::Vertex(tmpV));
1595 // create wire from tmpEdges
1598 for (j=1; j<=tmpEdges.Length(); j++)
1599 B.Add(W,tmpEdges.Value(j));
1604 Edges.InsertAfter(i-1,E1);
1605 Edges.InsertAfter(i,E2);
1612 // create wire from other edges
1615 for (; i<=Edges.Length(); i++)
1616 B.Add(W,Edges.Value(i));
1620 if (Wires.Length() != nbLocs-1) {
1621 if (aCI) delete aCI;
1622 Standard_ConstructionError::Raise
1623 ("One of location shapes is not lied on the path");
1626 TopTools_SequenceOfShape aGroups[5];
1627 TopoDS_Compound aComp;
1628 B.MakeCompound(aComp);
1629 for (i = 1; i < nbBases; i++) {
1630 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1632 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1633 if (anItem1.IsNull())
1635 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1636 if (aRefBase1.IsNull())
1638 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1639 if (aShBase1.IsNull())
1641 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1643 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1644 if (anItem2.IsNull())
1646 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1647 if (aRefBase2.IsNull())
1649 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1650 if (aShBase2.IsNull())
1652 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1654 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1655 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1657 if (aCI) delete aCI;
1658 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1661 bool CreateFewSolids = false;
1663 TopExp_Explorer anExp;
1664 Standard_Integer nbf1 = 0;
1665 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1668 Standard_Integer nbf2 = 0;
1669 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1673 CreateFewSolids = true;
1676 if (!CreateFewSolids) {
1677 // we can create only one solid
1678 TopoDS_Shape aWire1, aWire2;
1680 if (aType1==TopAbs_SHELL) {
1681 // create wire as boundary contour if shell is no closed
1682 // get free boundary shapes
1683 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1684 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1685 //TopExp_Explorer anExp;
1686 Standard_Integer NbWires = 0;
1687 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1689 aWire1 = anExp.Current();
1693 if (aCI) delete aCI;
1694 Standard_ConstructionError::Raise("Bad shell is used as section ");
1697 else { // aType1==TopAbs_FACE
1698 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1699 aWire1 = aExpW.Current();
1702 if (aType2==TopAbs_SHELL) {
1703 // create wire as boundary contour if shell is no closed
1704 // get free boundary shapes
1705 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1706 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1707 //TopExp_Explorer anExp;
1708 Standard_Integer NbWires = 0;
1709 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1711 aWire2 = anExp.Current();
1715 if (aCI) delete aCI;
1716 Standard_ConstructionError::Raise("Bad shell is used as section ");
1719 else { // aType2==TopAbs_FACE
1720 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1721 aWire2 = aExpW.Current();
1723 // make pipe using aWire1 and aWire2
1724 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1725 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1726 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1727 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1728 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1729 aBuilder.SetDiscreteMode();
1730 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1731 aWithContact, aWithCorrect);
1732 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1733 aWithContact, aWithCorrect);
1734 if (!aBuilder.IsReady()) {
1735 if (aCI) delete aCI;
1736 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1739 BuildPipeShell(aBuilder);
1741 TopoDS_Shape aShape = aBuilder.Shape();
1742 TopTools_SequenceOfShape aLocalGroups[5];
1745 if (isGenerateGroups) {
1747 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
1748 if (aCI) delete aCI;
1749 Standard_ConstructionError::Raise("Generate groups failure");
1752 // Clear the groups Down and Up.
1753 aLocalGroups[GROUP_DOWN].Clear();
1754 aLocalGroups[GROUP_UP].Clear();
1757 TopoDS_Shell aShell;
1758 B.MakeShell(aShell);
1759 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1760 B.Add(aShell,anExp.Current());
1762 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1763 B.Add(aShell,anExp.Current());
1765 if (isGenerateGroups && i == 1) {
1766 aLocalGroups[GROUP_DOWN].Append(anExp.Current());
1769 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1770 B.Add(aShell,anExp.Current());
1772 if (isGenerateGroups && i == nbBases - 1) {
1773 aLocalGroups[GROUP_UP].Append(anExp.Current());
1776 // make sewing for this shell
1777 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1778 aSewing->SetTolerance(Precision::Confusion());
1779 aSewing->SetFaceMode(Standard_True);
1780 aSewing->SetFloatingEdgesMode(Standard_False);
1781 aSewing->SetNonManifoldMode(Standard_False);
1782 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1783 aSewing->Add(anExp.Current());
1786 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1787 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1788 aShell = TopoDS::Shell(aSewShape);
1789 GProp_GProps aSystem;
1790 BRepGProp::VolumeProperties(aShell, aSystem);
1791 if (aSystem.Mass()<0) {
1794 if (BRep_Tool::IsClosed(aShell)) {
1795 TopoDS_Solid aSolid;
1796 B.MakeSolid(aSolid);
1797 B.Add(aSolid,aShell);
1798 B.Add(aComp,aSolid);
1801 B.Add(aComp,aShell);
1805 B.Add(aComp,aShell);
1808 if (isGenerateGroups) {
1809 Standard_Integer iGrp;
1811 for (iGrp = 0; iGrp < 5; ++iGrp) {
1814 // For each sub-shape of pipe
1815 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1816 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1818 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1819 // Use the shape modified by sewing.
1820 const TopoDS_Shape &aModifGrpShape =
1821 aSewing->ModifiedSubShape(aGrpShape);
1823 aGroups[iGrp].Append(aModifGrpShape);
1825 // Use the shape as it is.
1826 aGroups[iGrp].Append(aGrpShape);
1834 // main block - creation few solids (for each pair of faces)
1835 TopTools_MapOfShape aFaces1,aFaces2;
1836 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1837 aFaces1.Add(anExp.Current());
1839 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1840 aFaces2.Add(anExp.Current());
1842 // creating map of edge faces
1843 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1844 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1845 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1846 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1848 // construct map face->face
1849 TopTools_IndexedDataMapOfShapeShape FF;
1850 TopoDS_Shape FS1,FS2;
1851 if (nbSubBases==0) {
1852 // find edge the most distant from location point
1853 // (this edge is not shared by two faces)
1854 double maxdist = 0.;
1856 TopoDS_Vertex V11,V21;
1857 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1858 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1859 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1860 if (aList.Extent()>1)
1862 TopExp_Explorer expv;
1863 expv.Init(tmp, TopAbs_VERTEX);
1864 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1866 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1867 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1868 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1869 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1874 TopTools_ListIteratorOfListOfShape anIter(aList);
1875 FS1 = anIter.Value();
1879 // main direction for comparing
1880 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1881 // find corresponding edge from next section
1882 double minang = M_PI;
1883 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1884 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1886 TopoDS_Vertex V12,V22;
1887 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1888 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1889 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1890 if (aList.Extent()>1)
1892 TopExp_Explorer expv;
1893 expv.Init(tmp, TopAbs_VERTEX);
1894 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1896 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1897 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1898 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1899 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1900 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1901 TopoDS_Vertex V1,V2;
1904 V1 = V2tmp; P1 = P2tmp;
1905 V2 = V1tmp; P2 = P1tmp;
1908 V1 = V1tmp; P1 = P1tmp;
1909 V2 = V2tmp; P2 = P2tmp;
1911 gp_Vec Vec1(P11,P1);
1912 gp_Vec Vec2(P21,P2);
1913 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1918 TopTools_ListIteratorOfListOfShape anIter(aList);
1919 FS2 = anIter.Value();
1923 // put all pairs to map FF
1929 // add pairs of edges to FF
1930 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1932 if (aCI) delete aCI;
1933 Standard_ConstructionError::Raise("FindForOtherEdges: Can not map other edges");
1939 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1940 if (anItem.IsNull()) {
1941 if (aCI) delete aCI;
1942 Standard_ConstructionError::Raise("Invalid subbase shape");
1944 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1945 if (aRefBase.IsNull()) {
1946 if (aCI) delete aCI;
1947 Standard_ConstructionError::Raise("Invalid subbase shape");
1949 TopoDS_Shape aSh = aRefBase->GetValue();
1951 if (aCI) delete aCI;
1952 Standard_ConstructionError::Raise("Invalid subbase shape");
1954 if (aSh.ShapeType()!=TopAbs_FACE) {
1955 if (aCI) delete aCI;
1956 Standard_ConstructionError::Raise("Invalid subbase shape");
1961 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1962 if (anItem.IsNull()) {
1963 if (aCI) delete aCI;
1964 Standard_ConstructionError::Raise("Invalid subbase shape");
1966 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1967 if (aRefBase.IsNull()) {
1968 if (aCI) delete aCI;
1969 Standard_ConstructionError::Raise("Invalid subbase shape");
1971 TopoDS_Shape aSh = aRefBase->GetValue();
1973 if (aCI) delete aCI;
1974 Standard_ConstructionError::Raise("Invalid subbase shape");
1976 if (aSh.ShapeType()!=TopAbs_FACE) {
1977 if (aCI) delete aCI;
1978 Standard_ConstructionError::Raise("Invalid subbase shape");
1983 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1984 if (aCI) delete aCI;
1985 Standard_ConstructionError::Raise("Invalid subbase shape");
1990 // add pairs of edges to FF
1991 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1992 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1994 if (aCI) delete aCI;
1995 Standard_ConstructionError::Raise("Can not create correct pipe");
1999 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2001 // make pipe for each pair of faces
2002 for (j=1; j<=FF.Extent(); j++) {
2003 TopoDS_Shape F1 = FF.FindKey(j);
2004 if (F1.ShapeType() != TopAbs_FACE)
2006 TopoDS_Shape F2 = FF.FindFromIndex(j);
2007 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
2008 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
2009 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
2010 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
2011 // make pipe using aWire1 and aWire2
2012 if (!aWire1.IsNull() && !aWire2.IsNull()) {
2013 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
2014 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
2015 if (theBestMode == GeomFill_IsDiscreteTrihedron)
2016 aBuilder.SetDiscreteMode();
2017 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
2018 aWithContact, aWithCorrect);
2019 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
2020 aWithContact, aWithCorrect);
2021 if (!aBuilder.IsReady()) {
2022 if (aCI) delete aCI;
2023 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
2026 BuildPipeShell(aBuilder);
2028 TopoDS_Shape aShape = aBuilder.Shape();
2029 TopTools_SequenceOfShape aLocalGroups[5];
2032 if (isGenerateGroups) {
2034 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
2035 if (aCI) delete aCI;
2036 Standard_ConstructionError::Raise("Generate groups failure");
2039 // Clear the groups Down and Up.
2040 aLocalGroups[GROUP_DOWN].Clear();
2041 aLocalGroups[GROUP_UP].Clear();
2044 aLocalGroups[GROUP_DOWN].Append(F1);
2047 if (i == nbBases - 1) {
2048 aLocalGroups[GROUP_UP].Append(F2);
2052 TopoDS_Shell aShell;
2053 B.MakeShell(aShell);
2054 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
2055 B.Add(aShell,anExp.Current());
2060 // make sewing for this shell
2061 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2062 aSewing->SetTolerance(Precision::Confusion());
2063 aSewing->SetFaceMode(Standard_True);
2064 aSewing->SetFloatingEdgesMode(Standard_False);
2065 aSewing->SetNonManifoldMode(Standard_False);
2066 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2067 aSewing->Add(anExp.Current());
2070 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2071 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2072 aShell = TopoDS::Shell(aSewShape);
2073 GProp_GProps aSystem;
2074 BRepGProp::VolumeProperties(aShell, aSystem);
2075 if (aSystem.Mass() < 0) {
2078 if (BRep_Tool::IsClosed(aShell)) {
2079 TopoDS_Solid aSolid;
2080 B.MakeSolid(aSolid);
2081 B.Add(aSolid,aShell);
2082 B.Add(aComp,aSolid);
2085 B.Add(aComp,aShell);
2089 B.Add(aComp,aShell);
2092 if (isGenerateGroups) {
2093 // Replase Group shapes by modified ones.
2094 Standard_Integer iGrp;
2097 for (iGrp = 0; iGrp < 5; ++iGrp) {
2100 // For each sub-shape of pipe
2101 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2102 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2104 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2105 // Use the shape modified by sewing.
2106 const TopoDS_Shape &aModifGrpShape =
2107 aSewing->ModifiedSubShape(aGrpShape);
2109 aGroups[iGrp].Append(aModifGrpShape);
2111 // Use the shape as it is.
2112 aGroups[iGrp].Append(aGrpShape);
2122 if (isGenerateGroups) {
2124 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2125 TopTools_IndexedMapOfShape anIndices;
2127 TopExp::MapShapes(aComp, anIndices);
2129 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2130 if (aCI) delete aCI;
2131 Standard_ConstructionError::Raise("Generate groups failure");
2134 StoreGroups(aCI, aGroupIds);
2140 //=======================================================================
2141 //function : CreatePipeShellsWithoutPath
2142 //purpose : auxiliary for Execute()
2143 //=======================================================================
2144 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
2149 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
2151 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
2152 // vertex for recognition
2153 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
2154 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
2156 Standard_Integer nbBases = aBasesObjs->Length(),
2157 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
2159 if (nbv != nbBases) {
2160 if (aCI) delete aCI;
2161 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
2164 TopTools_SequenceOfShape aGroups[5];
2165 TopTools_SequenceOfShape SecVs,Bases;
2166 for (i=1; i<=nbBases; i++) {
2168 Handle(Standard_Transient) anItem = VObjs->Value(i);
2169 if (anItem.IsNull())
2171 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
2172 TopoDS_Shape V = aRef->GetValue();
2173 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
2177 anItem = aBasesObjs->Value(i);
2178 if (anItem.IsNull())
2180 aRef = Handle(GEOM_Function)::DownCast(anItem);
2181 TopoDS_Shape aSh = aRef->GetValue();
2186 nbv = SecVs.Length();
2187 nbBases = Bases.Length();
2188 if (nbv != nbBases) {
2189 if (aCI) delete aCI;
2190 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
2193 TopoDS_Compound aComp;
2194 B.MakeCompound(aComp);
2196 for (i = 1; i < nbBases; i++) {
2197 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
2198 TopoDS_Shape aShBase1 = Bases.Value(i);
2199 TopoDS_Shape aShBase2 = Bases.Value(i+1);
2200 TopExp_Explorer anExp;
2201 Standard_Integer nbf1 = 0;
2202 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2205 Standard_Integer nbf2 = 0;
2206 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2210 if (aCI) delete aCI;
2211 Standard_ConstructionError::Raise("Different number of faces in the sections");
2214 TopTools_MapOfShape aFaces1,aFaces2;
2215 TopTools_MapOfShape aBndEdges1;
2217 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2218 const TopoDS_Shape &aBaseFace1 = anExp.Current();
2220 if (aFaces1.Add(aBaseFace1)) {
2221 // Get boundary edges.
2222 TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
2224 for (; anExpE.More(); anExpE.Next()) {
2225 const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
2227 if (!aBndEdges1.Add(aBaseEdge1)) {
2228 aBndEdges1.Remove(aBaseEdge1);
2233 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2234 aFaces2.Add(anExp.Current());
2237 // creating map of edge faces
2238 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
2239 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
2240 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
2241 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
2243 // construct map face->face (and sub-shapes)
2244 TopTools_IndexedDataMapOfShapeShape FF;
2245 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
2246 TopoDS_Shape FS1, FS2;
2247 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
2248 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
2249 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
2252 MESSAGE (" first pair of corresponding faces is found");
2254 // add pairs of edges and vertexes to FF
2255 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
2257 if (aCI) delete aCI;
2258 Standard_ConstructionError::Raise("Can not create correct pipe");
2260 MESSAGE (" correspondences for sub-shapes of first pair of faces found");
2262 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2263 MESSAGE (" other correspondences found, make pipe for all pairs of faces");
2265 // make pipe for each pair of faces
2266 // auxiliary map vertex->edge for created pipe edges
2267 TopTools_IndexedDataMapOfShapeShape VPE;
2268 ShapeAnalysis_Edge sae;
2270 for (j=1; j<=FF.Extent(); j++) {
2271 TopoDS_Shape F1 = FF.FindKey(j);
2272 if (F1.ShapeType() != TopAbs_FACE)
2274 TopoDS_Shape F2 = FF.FindFromIndex(j);
2277 //if (nbff!=3) continue;
2279 MESSAGE (" make pipe for "<<nbff<<" face");
2281 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
2282 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2283 Handle(Geom_RectangularTrimmedSurface) RTS =
2284 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
2285 S1 = RTS->BasisSurface();
2287 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
2288 if (Pln1.IsNull()) {
2289 if (aCI) delete aCI;
2290 Standard_ConstructionError::Raise("Surface from face is not plane");
2292 gp_Vec aDir1(Pln1->Axis().Direction());
2294 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
2295 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2296 Handle(Geom_RectangularTrimmedSurface) RTS =
2297 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
2298 S2 = RTS->BasisSurface();
2300 Handle(Geom_Plane) Pln2 =
2301 Handle(Geom_Plane)::DownCast(S2);
2302 if (Pln2.IsNull()) {
2303 if (aCI) delete aCI;
2304 Standard_ConstructionError::Raise("Surface from face is not plane");
2306 gp_Vec aDir2(Pln2->Axis().Direction());
2308 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
2309 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
2311 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
2313 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
2316 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
2317 TopTools_SequenceOfShape aNewFs;
2318 TopTools_SequenceOfShape aLocalGroups[5];
2321 for (; anExpE.More(); anExpE.Next()) {
2322 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2324 if (!FF.Contains(E1))
2325 MESSAGE ("map FF not contains key E1");
2327 if (VPE.Contains(E1)) {
2328 aNewFs.Append(VPE.FindFromKey(E1));
2330 MESSAGE (" using existing face");
2335 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2336 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2337 TopoDS_Vertex V2 = sae.LastVertex(E1);
2338 if (!FF.Contains(V1))
2339 MESSAGE ("map FF not contains key V1");
2340 if (!FF.Contains(V2))
2341 MESSAGE ("map FF not contains key V2");
2342 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2343 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2344 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2345 if (Vtmp.IsSame(V4))
2347 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2348 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2349 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2350 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2353 Handle(Geom_BSplineCurve) C2;
2354 if (VPE.Contains(V2)) {
2355 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2357 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2360 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2361 HAP->SetValue(1,P2);
2362 HAP->SetValue(2,P3);
2363 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2364 anInt.Load(aDir1,aDir2);
2367 B.MakeEdge(E2,C2,1.e-7);
2368 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2369 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2374 Handle(Geom_BSplineCurve) C4;
2375 if (VPE.Contains(V1)) {
2376 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2378 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2381 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2382 HAP->SetValue(1,P1);
2383 HAP->SetValue(2,P4);
2384 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2385 anInt.Load(aDir1,aDir2);
2388 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2389 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2390 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2399 B.Add(W,E4.Reversed());
2404 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2405 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2406 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2408 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2409 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2410 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2412 Handle(Geom_BSplineCurve) CE1 =
2413 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2414 if (CE1->Degree()<3)
2415 CE1->IncreaseDegree(3);
2416 Handle(Geom_BSplineCurve) CE2 =
2417 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2418 if (CE2->Degree()<3)
2419 CE2->IncreaseDegree(3);
2420 Handle(Geom_BSplineCurve) CE3 =
2421 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2422 if (CE3->Degree()<3)
2423 CE3->IncreaseDegree(3);
2424 Handle(Geom_BSplineCurve) CE4 =
2425 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2426 if (CE4->Degree()<3)
2427 CE4->IncreaseDegree(3);
2429 Handle(Geom_Surface) BS;
2431 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2432 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2436 MESSAGE (" can not create BSplineSurface - create Bezier");
2438 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2439 double fp1,lp1,fp2,lp2;
2440 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2441 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2450 // get points from C1
2451 if (P1.Distance(P1C1)<1.e-6) {
2459 double step = (lp-fp)/(NbP-1);
2460 Points.SetValue(1,1,P1);
2462 for (n1=2; n1<NbP; n1++) {
2466 Points.SetValue(1,n1,P);
2468 Points.SetValue(1,NbP,P2);
2469 // get points from C3
2470 if (P4.Distance(P1C3)<1.e-6) {
2478 step = (lp-fp)/(NbP-1);
2479 Points.SetValue(NbP,1,P4);
2481 for (n1=2; n1<NbP; n1++) {
2485 Points.SetValue(NbP,n1,P);
2487 Points.SetValue(NbP,NbP,P3);
2488 // create isolines and get points from them
2489 for (n1=1; n1<=NbP; n1++) {
2490 gp_Pnt PI1 = Points.Value(1,n1);
2491 gp_Pnt PI2 = Points.Value(NbP,n1);
2492 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2493 HAP->SetValue(1,PI1);
2494 HAP->SetValue(2,PI2);
2495 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2496 anInt.Load(aDir1,aDir2);
2498 const Handle(Geom_BSplineCurve) iso = anInt.Curve();
2499 fp = iso->FirstParameter();
2500 lp = iso->LastParameter();
2501 step = (lp-fp)/(NbP-1);
2503 TopoDS_Compound VComp;
2504 B.MakeCompound(VComp);
2505 for (n2=2; n2<NbP; n2++) {
2509 Points.SetValue(n2,n1,P);
2512 // create surface and face
2513 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2514 BS = new Geom_BezierSurface(Points);
2517 BRepBuilderAPI_MakeFace BB(BS,W);
2518 TopoDS_Face NewF = BB.Face();
2519 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2521 sff->FixOrientation();
2522 TopoDS_Face FixedFace = sff->Face();
2523 aNewFs.Append(FixedFace);
2524 VPE.Add(E1,FixedFace);
2526 if (isGenerateGroups) {
2527 if (aBndEdges1.Contains(E1)) {
2528 // This is a boundary face.
2529 aLocalGroups[GROUP_OTHER].Append(FixedFace);
2534 TopoDS_Shell aShell;
2535 B.MakeShell(aShell);
2536 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2537 B.Add(aShell,aNewFs(nf));
2543 if (isGenerateGroups && i == 1) {
2544 aLocalGroups[GROUP_DOWN].Append(F1);
2547 if (isGenerateGroups && i == nbBases - 1) {
2548 aLocalGroups[GROUP_UP].Append(F2);
2551 // make sewing for this shell
2552 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2553 aSewing->SetTolerance(Precision::Confusion());
2554 aSewing->SetFaceMode(Standard_True);
2555 aSewing->SetFloatingEdgesMode(Standard_False);
2556 aSewing->SetNonManifoldMode(Standard_False);
2557 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2558 aSewing->Add(anExp.Current());
2561 MESSAGE (" shell for face "<<nbff<<" is created");
2562 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2563 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2564 aShell = TopoDS::Shell(aSewShape);
2565 GProp_GProps aSystem;
2566 BRepGProp::VolumeProperties(aShell, aSystem);
2567 if (aSystem.Mass() < 0) {
2570 if (BRep_Tool::IsClosed(aShell)) {
2571 TopoDS_Solid aSolid;
2572 B.MakeSolid(aSolid);
2573 B.Add(aSolid,aShell);
2574 B.Add(aComp,aSolid);
2575 MESSAGE (" solid for face "<<nbff<<" is created");
2578 B.Add(aComp,aShell);
2579 MESSAGE (" solid for face "<<nbff<<" is not created");
2583 B.Add(aComp,aShell);
2584 MESSAGE (" solid for face "<<nbff<<" is not created");
2587 if (isGenerateGroups) {
2588 Standard_Integer iGrp;
2590 for (iGrp = 0; iGrp < 5; ++iGrp) {
2593 // For each sub-shape of pipe
2594 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2595 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2597 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2598 // Use the shape modified by sewing.
2599 const TopoDS_Shape &aModifGrpShape =
2600 aSewing->ModifiedSubShape(aGrpShape);
2602 aGroups[iGrp].Append(aModifGrpShape);
2604 // Use the shape as it is.
2605 aGroups[iGrp].Append(aGrpShape);
2613 if (isGenerateGroups) {
2615 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2616 TopTools_IndexedMapOfShape anIndices;
2618 TopExp::MapShapes(aComp, anIndices);
2620 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2621 if (aCI) delete aCI;
2622 Standard_ConstructionError::Raise("Generate groups failure");
2625 StoreGroups(aCI, aGroupIds);
2631 //=======================================================================
2632 //function : CreatePipeBiNormalAlongVector
2633 //purpose : auxiliary for Execute()
2634 //=======================================================================
2635 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2636 GEOMImpl_IPipe* aCI)
2638 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2640 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2641 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2642 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2643 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2645 if (aShapeBase.IsNull()) {
2646 if (aCIBN) delete aCIBN;
2647 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2650 // Make copy to prevent modifying of base object: 0021525
2651 BRepBuilderAPI_Copy Copy (aShapeBase);
2653 aShapeBase = Copy.Shape();
2656 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2659 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2660 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2662 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2665 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2666 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2667 aProf = wexp.Current();
2670 Standard_TypeMismatch::Raise
2671 ("MakePipe aborted : invalid type of base");
2673 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2674 PipeBuilder.Add(aProf);
2676 if (aShapeVec.IsNull()) {
2677 if (aCIBN) delete aCIBN;
2678 Standard_NullObject::Raise
2679 ("MakePipe aborted : null vector argument");
2681 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2682 Standard_TypeMismatch::Raise
2683 ("MakePipe aborted: invalid type of vector");
2684 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2685 TopoDS_Vertex V1, V2;
2686 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2687 if (V1.IsNull() || V2.IsNull())
2688 Standard_NullObject::Raise
2689 ("MakePipe aborted: vector is not defined");
2690 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2691 gp_Dir BiNormal(aVec);
2692 PipeBuilder.SetMode(BiNormal);
2694 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2696 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2697 PipeBuilder.MakeSolid();
2700 if (!CreateGroups1(aProf, PipeBuilder, aCIBN)) {
2701 if (aCIBN) delete aCIBN;
2702 Standard_ConstructionError::Raise("Generate groups failure");
2705 return PipeBuilder.Shape();
2708 //=======================================================================
2709 //function : FillGroups
2710 //purpose : auxiliary for DoGroups()
2711 //=======================================================================
2712 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
2713 const TopTools_IndexedMapOfShape &theIndices,
2714 Handle(TColStd_HArray1OfInteger) *theGroupIds)
2718 for (i = 0; i < 5; ++i) {
2719 if (!theGroups[i].IsEmpty()) {
2720 const Standard_Integer aNbShapes = theGroups[i].Length();
2723 theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
2725 for (j = 1; j <= aNbShapes; ++j) {
2726 const TopoDS_Shape &aShape = theGroups[i].Value(j);
2727 const Standard_Integer anIndex = theIndices.FindIndex(aShape);
2733 theGroupIds[i]->SetValue(j, anIndex);
2741 //=======================================================================
2742 //function : StoreGroups
2743 //purpose : auxiliary for CreateGroups()
2744 //=======================================================================
2745 void StoreGroups(GEOMImpl_IPipe *theCI,
2746 Handle(TColStd_HArray1OfInteger) *theGroups)
2748 if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
2749 theCI->SetGroupDown(theGroups[GROUP_DOWN]);
2752 if (theGroups[GROUP_UP].IsNull() == Standard_False) {
2753 theCI->SetGroupUp(theGroups[GROUP_UP]);
2756 if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
2757 theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
2760 if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
2761 theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
2764 if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
2765 theCI->SetGroupOther(theGroups[GROUP_OTHER]);
2769 //=======================================================================
2770 //function : CreateDownUpGroups
2771 //purpose : auxiliary for DoGroups()
2772 //=======================================================================
2773 static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
2774 TopTools_SequenceOfShape *theGroups,
2775 Standard_Boolean &IsDoSides)
2777 const TopoDS_Shape aDownShape = theSweep->FirstShape();
2778 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2779 TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
2781 IsDoSides = Standard_False;
2786 anUpDownType = TopAbs_EDGE;
2788 if (GEOMUtils::IsOpenPath(aDownShape)) {
2789 IsDoSides = Standard_True;
2794 anUpDownType = TopAbs_FACE;
2800 if (anUpDownType == TopAbs_SHAPE) {
2801 // Invalid Up and Down group type.
2805 TopExp_Explorer anExp(aDownShape, anUpDownType);
2806 TopTools_MapOfShape aMapFence;
2808 // Create Down group.
2809 for (; anExp.More(); anExp.Next()) {
2810 const TopoDS_Shape &aShape = anExp.Current();
2812 if (aMapFence.Add(aShape)) {
2813 theGroups[GROUP_DOWN].Append(aShape);
2818 const TopoDS_Shape anUpShape = theSweep->LastShape();
2821 anExp.Init(anUpShape, anUpDownType);
2823 for (; anExp.More(); anExp.Next()) {
2824 const TopoDS_Shape &aShape = anExp.Current();
2826 if (aMapFence.Add(aShape)) {
2827 theGroups[GROUP_UP].Append(aShape);
2834 //=======================================================================
2835 //function : DoGroups1
2836 //purpose : auxiliary for CreateGroups1()
2837 //=======================================================================
2838 bool DoGroups1 (const TopoDS_Shape &theProfile,
2839 BRepOffsetAPI_MakePipeShell &theSweep,
2840 TopTools_SequenceOfShape *theGroups)
2842 Standard_Boolean isDoSides = Standard_False;
2844 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2845 // Up and Down groups creation failure
2849 TopoDS_Shape aDownShape = theProfile;
2850 if (aDownShape.IsNull()) aDownShape = theSweep.FirstShape();
2853 // Create Side1 and Side2 groups.
2854 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2855 TopoDS_Vertex aV[2];
2858 if (aType == TopAbs_EDGE) {
2859 TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
2860 } else { // aType == TopAbs_WIRE
2861 TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
2864 for (i = 0; i < 2; ++i) {
2865 if (aV[i].IsNull() == Standard_False) {
2866 const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
2868 if (!aLstSide.IsEmpty()) {
2869 TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
2870 TopTools_MapOfShape aMapFence;
2871 const Standard_Integer anIdSide =
2872 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2874 for (; aSideIt.More(); aSideIt.Next()) {
2875 const TopoDS_Shape &aSideShape = aSideIt.Value();
2877 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2878 if (aMapFence.Add(aSideShape)) {
2879 theGroups[anIdSide].Append(aSideShape);
2881 } else if (aSideShape.ShapeType() == TopAbs_WIRE) {
2882 if (aMapFence.Add(aSideShape)) {
2883 TopExp_Explorer anExpWE (aSideShape, TopAbs_EDGE);
2884 for (; anExpWE.More(); anExpWE.Next()) {
2885 theGroups[anIdSide].Append(anExpWE.Current());
2889 // Only edges can be in Side1 and Side2 groups.
2897 // Create Other group. Get boundary edges of the profile.
2898 TopTools_MapOfShape aMapBndEdges;
2899 TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
2901 for (; anExp.More(); anExp.Next()) {
2902 const TopoDS_Shape &anEdge = anExp.Current();
2904 if (!aMapBndEdges.Add(anEdge)) {
2905 aMapBndEdges.Remove(anEdge);
2909 // Fill the map of faces generated from profile's boundary edges.
2910 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2911 TopTools_MapOfShape aMapFence;
2913 for (; anIter.More(); anIter.Next()) {
2914 const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
2916 if (!aLstOther.IsEmpty()) {
2917 TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
2919 for (; anOtherIt.More(); anOtherIt.Next()) {
2920 const TopoDS_Shape &anOtherShape = anOtherIt.Value();
2922 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2923 if (aMapFence.Add(anOtherShape)) {
2924 theGroups[GROUP_OTHER].Append(anOtherShape);
2926 } else if (anOtherShape.ShapeType() == TopAbs_SHELL) {
2927 if (aMapFence.Add(anOtherShape)) {
2928 TopExp_Explorer anExpSHF (anOtherShape, TopAbs_FACE);
2929 for (; anExpSHF.More(); anExpSHF.Next()) {
2930 theGroups[GROUP_OTHER].Append(anExpSHF.Current());
2934 // Only faces can be in Other group.
2945 //=======================================================================
2946 //function : CreateGroups1
2947 //purpose : auxiliary for Execute()
2948 //=======================================================================
2949 bool CreateGroups1 (const TopoDS_Shape &theProfile,
2950 BRepOffsetAPI_MakePipeShell &theSweep,
2951 GEOMImpl_IPipe *theCI)
2953 if (!theCI->GetGenerateGroups()) {
2959 TopTools_SequenceOfShape aGroups[5];
2961 if (!DoGroups1(theProfile, theSweep, aGroups)) {
2966 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2967 TopTools_IndexedMapOfShape anIndices;
2968 const TopoDS_Shape aResult = theSweep.Shape();
2970 TopExp::MapShapes(aResult, anIndices);
2972 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2977 StoreGroups(theCI, aGroupIds);
2982 //=======================================================================
2983 //function : DoGroups2
2984 //purpose : auxiliary for CreateGroups()
2985 //=======================================================================
2986 static bool DoGroups2(const TopoDS_Shape &theProfile,
2987 const TopoDS_Shape &thePath,
2988 BRepOffsetAPI_MakePipe &theSweep,
2989 TopTools_SequenceOfShape *theGroups)
2991 Standard_Boolean isDoSides = Standard_False;
2993 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2994 // Up and Down groups creation failure
2999 // Create Side1 and Side2 groups.
3000 const TopAbs_ShapeEnum aType = theProfile.ShapeType();
3001 TopoDS_Vertex aV[2];
3004 if (aType == TopAbs_EDGE) {
3005 TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
3006 } else { // aType == TopAbs_WIRE
3007 TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
3010 for (i = 0; i < 2; ++i) {
3011 if (aV[i].IsNull() == Standard_False) {
3012 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
3013 TopTools_MapOfShape aMapFence;
3014 const Standard_Integer anIdSide =
3015 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
3017 for (; anExpP.More(); anExpP.Next()) {
3018 const TopoDS_Shape aSideShape =
3019 theSweep.Generated(anExpP.Current(), aV[i]);
3021 if (aSideShape.ShapeType() == TopAbs_EDGE) {
3022 if (aMapFence.Add(aSideShape)) {
3023 theGroups[anIdSide].Append(aSideShape);
3026 // Only edges can be is Side1 and Side2 groups.
3033 // Create Other group. Get boundary edges of the profile.
3034 TopTools_MapOfShape aMapBndEdges;
3035 TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
3037 for (; anExp.More(); anExp.Next()) {
3038 const TopoDS_Shape &anEdge = anExp.Current();
3040 if (!aMapBndEdges.Add(anEdge)) {
3041 aMapBndEdges.Remove(anEdge);
3045 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
3046 TopTools_MapOfShape aMapFence;
3048 for (; anExpP.More(); anExpP.Next()) {
3049 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
3051 for (; anIter.More(); anIter.Next()) {
3052 const TopoDS_Shape anOtherShape =
3053 theSweep.Generated(anExpP.Current(), anIter.Key());
3055 if (anOtherShape.ShapeType() == TopAbs_FACE) {
3056 if (aMapFence.Add(anOtherShape)) {
3057 theGroups[GROUP_OTHER].Append(anOtherShape);
3060 // Only faces can be in Other group.
3070 //=======================================================================
3071 //function : CreateGroups
3072 //purpose : auxiliary for Execute()
3073 //=======================================================================
3074 static bool CreateGroups2(const TopoDS_Shape &theProfile,
3075 const TopoDS_Shape &thePath,
3076 BRepOffsetAPI_MakePipe &theSweep,
3077 GEOMImpl_IPipe *theCI)
3079 if (!theCI->GetGenerateGroups()) {
3085 TopTools_SequenceOfShape aGroups[5];
3087 if (!DoGroups2(theProfile, thePath, theSweep, aGroups)) {
3092 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
3093 TopTools_IndexedMapOfShape anIndices;
3094 const TopoDS_Shape aResult = theSweep.Shape();
3096 TopExp::MapShapes(aResult, anIndices);
3098 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
3103 StoreGroups(theCI, aGroupIds);
3108 //=======================================================================
3109 //function : Execute
3111 //=======================================================================
3112 Standard_Integer GEOMImpl_PipeDriver::Execute(Handle(TFunction_Logbook)& log) const
3114 if (Label().IsNull()) return 0;
3115 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
3116 Standard_Integer aType = aFunction->GetType();
3118 GEOMImpl_IPipe* aCI = 0;
3119 if (aType == PIPE_BASE_PATH)
3120 aCI = new GEOMImpl_IPipe (aFunction);
3121 else if (aType == PIPE_DIFFERENT_SECTIONS)
3122 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
3123 else if (aType == PIPE_SHELL_SECTIONS)
3124 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3125 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
3126 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3127 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
3128 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
3132 TopoDS_Wire aWirePath;
3133 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
3134 // working with path
3135 Handle(GEOM_Function) aRefPath = aCI->GetPath();
3136 TopoDS_Shape aShapePath = aRefPath->GetValue();
3138 if (aShapePath.IsNull()) {
3139 MESSAGE ("Driver : path is null");
3140 if (aCI) delete aCI;
3141 Standard_NullObject::Raise("MakePipe aborted : null path argument");
3146 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
3147 TopTools_SequenceOfShape anEdges;
3148 TopExp_Explorer anExp;
3152 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
3153 B.Add(W, anExp.Current());
3159 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
3160 aWirePath = TopoDS::Wire(aShapePath);
3164 if (aShapePath.ShapeType() == TopAbs_EDGE) {
3165 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
3166 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
3171 if (aCI) delete aCI;
3172 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
3175 // Check if it is possible to create groups.
3176 if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
3181 Standard_ConstructionError::Raise
3182 ("Can't create groups if the path is closed");
3186 TopoDS_Shape aShape;
3187 const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
3189 if (aType == PIPE_BASE_PATH) {
3190 Handle(GEOM_Function) aRefBase = aCI->GetBase();
3191 TopoDS_Shape aShapeBase;
3193 // Make copy to prevent modifying of base object 0020766 : EDF 1320
3194 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
3196 aShapeBase = Copy.Shape();
3198 if (aShapeBase.IsNull()) {
3199 if (aCI) delete aCI;
3200 Standard_NullObject::Raise("MakePipe aborted : null base argument");
3204 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
3205 aShapeBase.ShapeType() == TopAbs_WIRE)
3207 TopoDS_Wire aProfile;
3208 if (aShapeBase.ShapeType() == TopAbs_WIRE)
3209 aProfile = TopoDS::Wire(aShapeBase);
3213 BB.MakeWire(aProfile);
3214 BB.Add(aProfile, aShapeBase);
3217 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
3218 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
3219 if (FaceBuilder.IsDone())
3220 Sweep.SetMode(FaceBuilder.Face());
3221 Sweep.Add(aProfile);
3223 Standard_Boolean isDone = BuildPipeShell(Sweep);
3227 if (aCI) delete aCI;
3228 Standard_ConstructionError::Raise("MakePipeShell failed");
3231 aShape = Sweep.Shape(); //result is good
3233 if (!CreateGroups1(aProfile, Sweep, aCI)) {
3234 if (aCI) delete aCI;
3235 Standard_ConstructionError::Raise("Generate groups failure");
3240 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
3241 BRepOffsetAPI_MakePipe aMkPipe
3242 (aWirePath, aShapeBase, theBestMode, Standard_True);
3244 if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) {
3245 aShape = aMkPipe.Shape();
3247 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipe, aCI)) {
3248 if (aCI) delete aCI;
3249 Standard_ConstructionError::Raise("Generate groups failure");
3251 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
3252 // Try to use Descrete Trihedron mode.
3253 BRepOffsetAPI_MakePipe aMkPipeDescrete
3254 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron, Standard_True);
3256 if (aMkPipeDescrete.IsDone()) {
3257 aShape = aMkPipeDescrete.Shape();
3259 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
3260 if (aCI) delete aCI;
3261 Standard_ConstructionError::Raise("Generate groups failure");
3268 //building pipe with different sections
3269 else if (aType == PIPE_DIFFERENT_SECTIONS) {
3270 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
3271 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
3272 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
3273 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
3274 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
3275 Standard_Boolean isBySteps = aCIDS->GetIsBySteps();
3282 Standard_Integer nbBases = aBasesObjs->Length();
3283 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
3285 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
3286 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
3289 for (i = 1; i <= nbBases; i++) {
3290 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
3291 if (anItem.IsNull())
3293 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
3294 if (aRefBase.IsNull())
3296 if (aRefBase->GetValue().IsNull())
3299 aHSeqBases->Append(aRefBase->GetValue());
3301 for (i = 1; i <= nbLocs; i++) {
3302 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
3303 if (anItemLoc.IsNull())
3305 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
3306 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
3307 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
3310 aHSeqLocs->Append(aShapeLoc);
3314 Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
3315 Handle(TColStd_HArray1OfInteger) aGroups[5];
3317 if (isGenerateGroups) {
3321 aShape = CreatePipeWithDifferentSections
3322 (aWirePath, aHSeqBases, aHSeqLocs,
3323 aWithContact, aWithCorrect, isBySteps, pGroups);
3325 if (isGenerateGroups) {
3326 // Store created groups.
3327 GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
3329 StoreGroups(&aPipeDS, aGroups);
3333 //building pipe with shell sections
3334 else if (aType == PIPE_SHELL_SECTIONS) {
3335 aShape = CreatePipeForShellSections(aWirePath,aCI);
3338 //building pipe shell sections without path
3339 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
3340 aShape = CreatePipeShellsWithoutPath(aCI);
3343 //building a pipe with constant bi-normal along given vector
3344 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
3345 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
3353 if (aShape.IsNull()) return 0;
3355 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
3356 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
3358 if (aType != PIPE_BASE_PATH &&
3359 aType != PIPE_SHELLS_WITHOUT_PATH) {
3360 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
3361 if (anExpV.More()) {
3362 Standard_Real aVertMaxTol = -RealLast();
3363 for (; anExpV.More(); anExpV.Next()) {
3364 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
3365 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
3366 if (aTol > aVertMaxTol)
3369 aVertMaxTol += Precision::Confusion();
3371 TopTools_DataMapOfShapeListOfShape aMapModif;
3372 TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
3374 if (isGenerateGroups) {
3375 pMapModif = &aMapModif;
3378 TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
3379 (aShape, aVertMaxTol, Standard_True, pMapModif);
3381 if (isGenerateGroups && !aMapModif.IsEmpty()) {
3383 GEOMImpl_IPipe aCI(aFunction);
3384 Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
3385 { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
3386 aCI.GetGroupSide2(), aCI.GetGroupOther() };
3387 TopTools_IndexedMapOfShape anIndices;
3388 TopTools_IndexedMapOfShape aNewIndices;
3389 TopTools_SequenceOfShape aNewShapes[5];
3390 TopTools_MapOfShape aMapReplaced;
3391 TopTools_MapOfShape aMapGlued;
3392 Standard_Integer iGrp;
3395 TopExp::MapShapes(aShape, anIndices);
3396 TopExp::MapShapes(aNewShape, aNewIndices);
3398 for (iGrp = 0; iGrp < 5; ++iGrp) {
3399 if (aGroupIDs[iGrp].IsNull() == Standard_False) {
3400 const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
3401 const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
3403 for (i = aLower; i <= anUpper; ++i) {
3404 const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
3405 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
3407 if (aMapModif.IsBound(aSubShape)) {
3408 const TopTools_ListOfShape &aListModif =
3409 aMapModif.Find(aSubShape);
3410 TopTools_ListIteratorOfListOfShape anIter(aListModif);
3412 for (; anIter.More(); anIter.Next()) {
3413 const TopoDS_Shape &aNewShape = anIter.Value();
3415 if (aMapReplaced.Add(aNewShape)) {
3416 aNewShapes[iGrp].Append(aNewShape);
3418 // This is a glued shape. It means that it is internal
3419 // one and should be removed from groups later.
3420 aMapGlued.Add(aNewShape);
3424 // Shape is not modified.
3425 aNewShapes[iGrp].Append(aSubShape);
3431 if (!aMapGlued.IsEmpty()) {
3432 // Remove glued (internal) shapes from groups.
3433 for (iGrp = 0; iGrp < 5; ++iGrp) {
3434 Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
3436 for (i = 1; i < aNbShapes; ++i) {
3437 const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
3439 if (aMapGlued.Contains(aNewShape)) {
3440 aNewShapes[iGrp].Remove(i);
3448 // Store modified groups.
3449 Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
3451 if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
3452 Standard_ConstructionError::Raise("Generate groups failure");
3455 StoreGroups(&aCI, aNewGroupIDs);
3462 // Note: group indices should not be changed after the next call.
3463 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
3464 aFunction->SetValue(aRes);
3466 log->SetTouched(Label());
3470 //================================================================================
3472 * \brief Returns a name of creation operation and names and values of creation parameters
3474 //================================================================================
3476 bool GEOMImpl_PipeDriver::
3477 GetCreationInformation(std::string& theOperationName,
3478 std::vector<GEOM_Param>& theParams)
3480 if (Label().IsNull()) return 0;
3481 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
3482 Standard_Integer aType = function->GetType();
3485 case PIPE_BASE_PATH:
3487 theOperationName = "PIPE";
3488 GEOMImpl_IPipe aCI( function );
3489 AddParam( theParams, "Base Object", aCI.GetBase() );
3490 AddParam( theParams, "Path Object", aCI.GetPath() );
3493 case PIPE_BI_NORMAL_ALONG_VECTOR:
3495 theOperationName = "PIPE";
3496 GEOMImpl_IPipeBiNormal aCI( function );
3497 AddParam( theParams, "Base Object", aCI.GetBase() );
3498 AddParam( theParams, "Path Object", aCI.GetPath() );
3499 AddParam( theParams, "BiNormal", aCI.GetVector() );
3502 case PIPE_DIFFERENT_SECTIONS:
3504 theOperationName = "PIPE";
3505 GEOMImpl_IPipeDiffSect aCI( function );
3506 AddParam( theParams, "Bases", aCI.GetBases() );
3507 AddParam( theParams, "Locations", aCI.GetLocations() );
3508 AddParam( theParams, "Path", aCI.GetPath() );
3510 if (!aCI.GetIsBySteps()) {
3511 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3512 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3515 AddParam( theParams, "Step by step", aCI.GetIsBySteps() );
3518 case PIPE_SHELL_SECTIONS:
3520 theOperationName = "PIPE";
3521 GEOMImpl_IPipeShellSect aCI( function );
3522 AddParam( theParams, "Bases", aCI.GetBases() );
3523 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
3524 AddParam( theParams, "Locations", aCI.GetLocations() );
3525 AddParam( theParams, "Path", aCI.GetPath() );
3526 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3527 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3530 case PIPE_SHELLS_WITHOUT_PATH:
3532 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
3533 GEOMImpl_IPipeShellSect aCI( function );
3534 AddParam( theParams, "Bases", aCI.GetBases() );
3535 AddParam( theParams, "Locations", aCI.GetLocations() );
3545 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver)