1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <GEOMImpl_PipeDriver.hxx>
25 #include <GEOMImpl_IPipeDiffSect.hxx>
26 #include <GEOMImpl_IPipeShellSect.hxx>
27 #include <GEOMImpl_IPipeBiNormal.hxx>
28 #include <GEOMImpl_IPipe.hxx>
29 #include <GEOMImpl_IPipePath.hxx>
30 #include <GEOMImpl_GlueDriver.hxx>
31 #include <GEOMImpl_Types.hxx>
33 #include <GEOM_Function.hxx>
35 #include <GEOMUtils.hxx>
37 #include <ShapeAnalysis_FreeBounds.hxx>
38 #include <ShapeAnalysis_Edge.hxx>
39 #include <ShapeFix_Face.hxx>
40 #include <ShapeFix_Shell.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BRepBuilderAPI_Copy.hxx>
45 #include <BRepBuilderAPI_MakeFace.hxx>
46 #include <BRepBuilderAPI_MakeSolid.hxx>
47 #include <BRepBuilderAPI_MakeWire.hxx>
48 #include <BRepBuilderAPI_Sewing.hxx>
49 #include <BRepClass3d_SolidClassifier.hxx>
50 #include <BRepGProp.hxx>
51 #include <GeomFill_Trihedron.hxx>
52 #include <GeomFill_CorrectedFrenet.hxx>
53 #include <BRepOffsetAPI_MakePipe.hxx>
54 #include <BRepOffsetAPI_MakePipeShell.hxx>
58 #include <TopExp_Explorer.hxx>
60 #include <TopoDS_Wire.hxx>
61 #include <TopoDS_Edge.hxx>
62 #include <TopoDS_Shape.hxx>
63 #include <TopoDS_Solid.hxx>
64 #include <TopoDS_Shell.hxx>
65 #include <TopoDS_Face.hxx>
66 #include <TopoDS_Compound.hxx>
67 #include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
68 #include <TopTools_SequenceOfShape.hxx>
69 #include <TopTools_HSequenceOfShape.hxx>
70 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
71 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
72 #include <TopTools_ListIteratorOfListOfShape.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
75 #include <GProp_GProps.hxx>
77 #include <GeomAPI_ProjectPointOnCurve.hxx>
78 #include <GeomAPI_Interpolate.hxx>
79 #include <Geom_TrimmedCurve.hxx>
80 #include <Geom_Plane.hxx>
81 #include <Geom_RectangularTrimmedSurface.hxx>
82 #include <Geom_BezierSurface.hxx>
83 #include <Geom_Line.hxx>
84 #include <Geom_Conic.hxx>
85 #include <Geom_BSplineCurve.hxx>
86 #include <Geom_BSplineSurface.hxx>
87 #include <GeomAdaptor_HCurve.hxx>
88 #include <GeomFill_BSplineCurves.hxx>
89 #include <GeomConvert_ApproxCurve.hxx>
90 #include <GeomConvert.hxx>
92 #include <TColgp_SequenceOfPnt.hxx>
93 #include <TColgp_HArray1OfPnt.hxx>
94 #include <TColgp_Array2OfPnt.hxx>
95 #include <TColStd_HSequenceOfTransient.hxx>
97 #include <Precision.hxx>
99 #include <Standard_NullObject.hxx>
100 #include <Standard_TypeMismatch.hxx>
101 #include <Standard_ConstructionError.hxx>
103 #include "utilities.h"
107 #define GROUP_SIDE1 2
108 #define GROUP_SIDE2 3
109 #define GROUP_OTHER 4
111 static const Standard_Real TolPipeSurf = 5.e-4;
113 static bool FillGroups(const TopTools_SequenceOfShape *theGroups,
114 const TopTools_IndexedMapOfShape &theIndices,
115 Handle(TColStd_HArray1OfInteger) *theGroupIds);
117 static void StoreGroups(GEOMImpl_IPipe *theCI,
118 Handle(TColStd_HArray1OfInteger) *theGroups);
120 // after OCCT improvement
121 static bool DoGroups1(const TopoDS_Shape &theProfile,
122 BRepOffsetAPI_MakePipeShell &theSweep,
123 TopTools_SequenceOfShape *theGroups);
125 static bool CreateGroups1(const TopoDS_Shape &theProfile,
126 BRepOffsetAPI_MakePipeShell &theSweep,
127 GEOMImpl_IPipe *theCI);
129 //=======================================================================
132 //=======================================================================
133 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
135 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
139 //=======================================================================
140 //function : GEOMImpl_PipeDriver
142 //=======================================================================
143 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
147 //=======================================================================
148 //function : EvaluateBestSweepMode
149 //purpose : auxilary for right call of MakePipe and MakePipeShell
150 //=======================================================================
151 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
153 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
155 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
156 for (; Explo.More(); Explo.Next())
158 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
159 Standard_Real fpar, lpar;
160 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
161 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
162 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
164 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
165 aCorrFrenet->SetCurve(GAHcurve);
166 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
167 if (aMode == GeomFill_IsDiscreteTrihedron)
172 if (aMode == GeomFill_IsCorrectedFrenet)
179 //=======================================================================
180 //function : BuildPipeShell
181 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
182 // mode. Returns Standard_True if the building is done successfully.
183 //=======================================================================
184 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
186 theBuilder.SetForceApproxC1(Standard_True);
190 Standard_Boolean isDone = theBuilder.IsDone();
193 theBuilder.ErrorOnSurface() > TolPipeSurf) {
194 // Try to use Descrete Trihedron mode.
195 theBuilder.SetDiscreteMode();
197 isDone = theBuilder.IsDone();
203 //=======================================================================
204 //function : FillForOtherEdges
205 //purpose : auxilary for CreatePipeForShellSections()
206 //=======================================================================
207 static bool FillForOtherEdges(const TopoDS_Shape& F1,
208 const TopoDS_Shape& E1,
209 const TopoDS_Shape& V1,
210 TopTools_IndexedDataMapOfShapeShape& FF)
212 //cout<<"FillForOtherEdges"<<endl;
213 // find other pairs for vertexes and edges
214 // creating map of vertex edges for both faces
215 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
216 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
217 if (!FF.Contains(F1))
218 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
219 if (!FF.Contains(E1))
220 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
221 if (!FF.Contains(V1))
222 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
223 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
224 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
225 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
226 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
227 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
229 TopoDS_Edge ES1 = TopoDS::Edge(E1);
230 TopoDS_Edge ES2 = TopoDS::Edge(E2);
231 TopoDS_Shape VS1 = V1;
232 TopoDS_Shape VS2 = V2;
234 ShapeAnalysis_Edge sae;
236 if (!aMapVertEdge1.Contains(VS1))
237 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
238 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
239 //TopoDS_Shape E1next;
240 TopTools_ListIteratorOfListOfShape anIter1(aList1);
241 if (anIter1.Value().IsSame(ES1)) {
244 //E1next = anIter1.Value();
245 if (!aMapVertEdge2.Contains(VS2))
246 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
247 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
248 //TopoDS_Shape E2next;
249 TopTools_ListIteratorOfListOfShape anIter2(aList2);
250 if (anIter2.Value().IsSame(ES2)) {
253 //E2next = anIter2.Value();
254 //ES1 = TopoDS::Edge(E1next);
255 //ES2 = TopoDS::Edge(E2next);
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 : auxilary 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 //cout<<"FillCorrespondingEdges"<<endl;
291 // find corresponding edges
292 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
293 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
294 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
295 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
296 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
297 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
298 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
299 if (theBestMode == GeomFill_IsDiscreteTrihedron)
300 aBuilder.SetDiscreteMode();
301 aBuilder.Add(aWire1, aLoc1);
302 aBuilder.Add(aWire2, aLoc2);
303 if (!aBuilder.IsReady()) {
307 BuildPipeShell(aBuilder);
309 TopoDS_Shape aShape = aBuilder.Shape();
310 ShapeAnalysis_Edge sae;
311 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
312 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
313 TopTools_MapOfShape Vs1,Vs2;
315 exp.Init(FS1, TopAbs_EDGE);
316 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
317 TopoDS_Vertex V11 = sae.FirstVertex(E1);
318 TopoDS_Vertex V21 = sae.LastVertex(E1);
319 gp_Pnt P11 = BRep_Tool::Pnt(V11);
320 gp_Pnt P21 = BRep_Tool::Pnt(V21);
321 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
322 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
323 // find corresponding vertexes from created shape
324 TopoDS_Vertex VN11,VN21;
325 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
326 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
327 gp_Pnt P = BRep_Tool::Pnt(V);
328 if (P.Distance(P11)<tol) {
331 if (P.Distance(P21)<tol) {
335 // find edge contains VN11 and VN21 and corresponding vertexes
336 TopoDS_Vertex VN12,VN22;
337 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
338 TopoDS_Shape F = exp.Current();
339 TopExp_Explorer expe;
341 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
342 TopoDS_Edge E = TopoDS::Edge(expe.Current());
343 TopoDS_Vertex VF = sae.FirstVertex(E);
344 TopoDS_Vertex VL = sae.LastVertex(E);
345 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
351 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
352 TopoDS_Edge E = TopoDS::Edge(expe.Current());
353 TopoDS_Vertex VF = sae.FirstVertex(E);
354 TopoDS_Vertex VL = sae.LastVertex(E);
355 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
357 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
359 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
361 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
367 // find vertexes from FS2 corresponded to VN12 and VN22
368 // and find edge from FS2 contains V12 and V22,
369 // this edge will be corresponded to edge E1
370 TopoDS_Vertex V12,V22;
371 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
372 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
373 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
374 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
376 TopExp_Explorer expe;
377 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
378 TopoDS_Edge E = TopoDS::Edge(expe.Current());
379 TopoDS_Vertex VF = sae.FirstVertex(E);
380 TopoDS_Vertex VL = sae.LastVertex(E);
381 gp_Pnt PF = BRep_Tool::Pnt(VF);
382 gp_Pnt PL = BRep_Tool::Pnt(VL);
383 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
389 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
400 // find other pairs for vertexes and edges
401 // creating map of vertex edges for both faces
402 return FillForOtherEdges(FS1,E1,V21,FF);
407 //=======================================================================
408 //function : FillCorrespondingEdges
409 //purpose : auxilary for CreatePipeShellsWithoutPath()
410 //=======================================================================
411 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
412 const TopoDS_Shape& FS2,
413 const TopoDS_Vertex& aLoc1,
414 const TopoDS_Vertex& aLoc2,
415 TopTools_IndexedDataMapOfShapeShape& FF)
417 //cout<<"FillCorrespondingEdges"<<endl;
419 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
420 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
423 ShapeAnalysis_Edge sae;
424 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
425 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
426 TopTools_MapOfShape Vs1,Vs2;
428 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
431 TopExp_Explorer exp1;
432 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
433 E1 = TopoDS::Edge(exp1.Current());
434 TopoDS_Vertex V1 = sae.FirstVertex(E1);
435 TopoDS_Vertex V2 = sae.LastVertex(E1);
436 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
437 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
438 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
439 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
440 if (P1.Distance(Ptmp1)<tol) {
444 if (P1.Distance(Ptmp2)<tol) {
451 TopoDS_Vertex VE21,VE22;
453 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
454 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
455 TopoDS_Vertex V1 = sae.FirstVertex(E);
456 TopoDS_Vertex V2 = sae.LastVertex(E);
457 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
458 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
459 if (P2.Distance(Ptmp1)<tol) {
471 if (P2.Distance(Ptmp2)<tol) {
485 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
486 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
487 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
488 gp_Vec aDir1(PV21,PE21);
489 gp_Vec aDir2(PV21,PE22);
490 double ang1 = aDir.Angle(aDir1);
491 double ang2 = aDir.Angle(aDir2);
492 if (fabs(ang1)<fabs(ang2)) {
505 // find other pairs for vertexes and edges
506 return FillForOtherEdges(FS1,E1,V21,FF);
509 //=======================================================================
510 //function : FindNextPairOfFaces
511 //purpose : auxilary for CreatePipeForShellSections()
512 //=======================================================================
513 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
514 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
515 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
516 TopTools_IndexedDataMapOfShapeShape& FF,
519 //cout<<"FindNextPairOfFaces"<<endl;
520 TopExp_Explorer anExp;
521 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
522 TopoDS_Shape E1 = anExp.Current();
523 if (!FF.Contains(E1)) {
525 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
527 if (!FF.Contains(E1))
528 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
529 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
530 TopExp_Explorer anExpV;
531 anExpV.Init(E1, TopAbs_VERTEX);
532 TopoDS_Shape V1 = anExpV.Current();
533 if (!FF.Contains(V1)) {
535 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
538 if (!aMapEdgeFaces1.Contains(E1))
539 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
540 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
541 if (aList1.Extent()<2)
543 TopTools_ListIteratorOfListOfShape anIter(aList1);
544 if (anIter.Value().IsEqual(aCurFace)) {
547 TopoDS_Shape F1other = anIter.Value();
548 if (FF.Contains(F1other))
551 if (!FF.Contains(aCurFace))
552 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
553 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
554 if (!aMapEdgeFaces2.Contains(E2))
555 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
556 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
557 if (aList2.Extent()<2) {
559 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
561 TopTools_ListIteratorOfListOfShape anIter2(aList2);
562 if (anIter2.Value().IsEqual(F2)) {
565 TopoDS_Shape F2other = anIter2.Value();
566 FF.Add(F1other,F2other);
568 // add pairs of edges to FF
569 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
572 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
575 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
579 //=======================================================================
580 //function : FindFirstPairFaces
581 //purpose : auxilary for Execute()
582 //=======================================================================
583 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
584 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
585 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
587 //cout<<"FindFirstPairFaces"<<endl;
589 // check if vertexes are sub-shapes of sections
590 gp_Pnt P1 = BRep_Tool::Pnt(V1);
591 gp_Pnt P2 = BRep_Tool::Pnt(V2);
592 TopoDS_Vertex V1new,V2new;
594 double mindist = 1.e10;
595 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
596 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
597 gp_Pnt P = BRep_Tool::Pnt(V);
598 double dist = P1.Distance(P);
605 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
606 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
607 gp_Pnt P = BRep_Tool::Pnt(V);
608 double dist = P2.Distance(P);
615 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
616 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
617 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
618 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
619 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
620 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
622 // replace vertexes if it is needed
623 if (!V1.IsSame(V1new)) {
625 P1 = BRep_Tool::Pnt(V1);
626 MESSAGE (" replace V1");
629 MESSAGE (" not replace V1");
630 if (!V2.IsSame(V2new)) {
632 P2 = BRep_Tool::Pnt(V2);
633 MESSAGE (" replace V2");
636 MESSAGE (" not replace V2");
638 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
639 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
640 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
641 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
643 if (!aMapVertFaces1.Contains(V1))
644 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
645 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
646 TopTools_ListIteratorOfListOfShape anIter1(aList1);
647 FS1 = anIter1.Value();
649 double x1=0., y1=0., z1=0.;
651 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
652 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
653 gp_Pnt P = BRep_Tool::Pnt(V);
659 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
661 TColgp_SequenceOfPnt Ps;
662 TopTools_SequenceOfShape Fs;
663 if (!aMapVertFaces2.Contains(V2))
664 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
665 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
666 TopTools_ListIteratorOfListOfShape anIter2(aList2);
667 for (; anIter2.More(); anIter2.Next()) {
668 TopoDS_Shape F = anIter2.Value();
669 double x2=0., y2=0., z2=0.;
671 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
672 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
673 gp_Pnt P = BRep_Tool::Pnt(V);
679 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
686 double MinAng = M_PI;
688 for (; i<=Fs.Length(); i++) {
689 gp_Vec tmpDir(PM1,Ps(i));
690 double ang = fabs(aDir.Angle(tmpDir));
699 //=======================================================================
700 //function : RemoveFaces
701 //purpose : This function returns theShapeFrom without faces of the shape
702 // theFacesToRm. It returns a shell if theShapeFrom is a solid or
703 // a compound otherwise. Auxilary for CreatePipeWithDifferentSections
705 //=======================================================================
706 static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom,
707 const TopoDS_Shape &theFacesToRm)
709 TopTools_IndexedMapOfShape aMapFaces;
710 TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE);
711 BRep_Builder aBuilder;
712 TopoDS_Shape aResult;
714 if (theShapeFrom.ShapeType() == TopAbs_SOLID) {
716 aBuilder.MakeShell(TopoDS::Shell(aResult));
719 aBuilder.MakeCompound(TopoDS::Compound(aResult));
722 TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces);
724 for (; anExp.More(); anExp.Next()) {
725 const TopoDS_Shape &aFace = anExp.Current();
727 if (!aMapFaces.Contains(aFace)) {
728 aBuilder.Add(aResult, aFace);
735 //=======================================================================
736 //function : CreatePipeWithDifferentSections
738 //=======================================================================
739 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
740 (const TopoDS_Wire &theWirePath,
741 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
742 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
743 const Standard_Boolean theWithContact,
744 const Standard_Boolean theWithCorrect,
745 const Standard_Boolean IsBySteps,
746 Handle(TColStd_HArray1OfInteger) *theGroups)
750 TopoDS_Wire aWirePath = theWirePath;
752 Standard_Integer nbBases = theHSeqBases->Length();
753 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
755 if (nbLocs && nbLocs != nbBases) {
756 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
759 TopTools_SequenceOfShape aSeqBases;
760 TopTools_SequenceOfShape aSeqLocs;
761 TopTools_SequenceOfShape aSeqFaces;
762 Standard_Boolean NeedCreateSolid = Standard_False;
764 Standard_Integer i = 1;
765 for (i = 1; i <= nbBases; i++) {
766 if (theHSeqBases->Value(i).IsNull())
769 // Make copy to prevent modifying of base object 0020766 : EDF 1320
770 TopoDS_Shape aShapeBase;
771 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
773 aShapeBase = Copy.Shape();
775 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
777 //if for section was specified face with a few wires then a few
778 // pipes were build and make solid
779 if (aTypeBase == TopAbs_SHELL) {
780 // create wire as boundary contour if shell is no closed
781 // get free boundary shapes
782 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
783 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
784 TopExp_Explorer anExp;
786 Standard_Integer NbWires = 0;
787 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
789 aWire = anExp.Current();
793 Standard_ConstructionError::Raise("Bad shell is used as section ");
795 NeedCreateSolid = Standard_True;
796 aSeqFaces.Append(aShapeBase);
797 aSeqBases.Append(aWire);
799 else if (aTypeBase == TopAbs_FACE) {
800 NeedCreateSolid = Standard_True;
801 //for case one path should be used other type function
802 aSeqFaces.Append(aShapeBase);
803 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
804 for (; aExpW.More(); aExpW.Next()) {
805 TopoDS_Shape aWireProf = aExpW.Current();
806 aSeqBases.Append(aWireProf);
809 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
810 aSeqBases.Append(aShapeBase);
812 else if (aTypeBase == TopAbs_EDGE) {
813 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
814 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
815 aSeqBases.Append(aWireProf);
818 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
819 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
821 aSeqLocs.Append(aShapeLoc);
825 nbLocs = aSeqLocs.Length();
828 TopTools_SequenceOfShape Edges;
830 // we have to check that each location shape is a vertex from
831 // path and update aSeqLocs if it is needed (and possible)
832 TColgp_SequenceOfPnt PLocs;
833 for (i=1; i<=nbLocs; i++) {
834 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
835 PLocs.Append(BRep_Tool::Pnt(V));
837 //TopTools_SequenceOfShape Edges;
838 TopExp_Explorer anExp;
839 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
840 Edges.Append(anExp.Current());
842 int nbEdges = Edges.Length();
843 ShapeAnalysis_Edge sae;
844 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
845 double tol = BRep_Tool::Tolerance(edge);
846 TopoDS_Vertex VF = sae.FirstVertex(edge);
847 gp_Pnt PF = BRep_Tool::Pnt(VF);
848 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
849 if (PF.Distance(PLocs.First()) > tol) {
850 Standard_ConstructionError::Raise
851 ("First location shapes is not coincided with first vertex of aWirePath");
853 aSeqLocs.ChangeValue(1) = VF;
854 edge = TopoDS::Edge(Edges.Last());
855 tol = BRep_Tool::Tolerance(edge);
856 TopoDS_Vertex VL = sae.LastVertex(edge);
857 gp_Pnt PL = BRep_Tool::Pnt(VL);
858 if (PL.Distance(PLocs.Last()) > tol) {
859 Standard_ConstructionError::Raise
860 ("Last location shapes is not coincided with last vertex of aWirePath");
862 aSeqLocs.ChangeValue(nbLocs) = VL;
864 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
865 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
866 tol = BRep_Tool::Tolerance(edge);
867 TopoDS_Vertex V1 = sae.FirstVertex(E);
868 TopoDS_Vertex V2 = sae.LastVertex(E);
869 gp_Pnt P1 = BRep_Tool::Pnt(V1);
870 gp_Pnt P2 = BRep_Tool::Pnt(V2);
871 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
872 aSeqLocs.ChangeValue(jcurr) = V2;
876 // find distance between E and aLocs(jcurr)
878 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
879 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
880 if (PPCurve.NbPoints()>0 &&
881 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
882 double param = PPCurve.Parameter(1);
885 // split current edge
886 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
887 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
892 if (Pfp.Distance(P1)<tol) {
893 B.MakeEdge(E1,tc1,tol);
895 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
896 B.Add(E1,TopoDS::Vertex(tmpV));
897 B.MakeEdge(E2,tc2,tol);
898 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
899 B.Add(E2,TopoDS::Vertex(tmpV));
903 B.MakeEdge(E1,tc2,tol);
904 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
905 B.Add(E1,TopoDS::Vertex(tmpV));
908 B.MakeEdge(E2,tc1,tol);
910 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
911 B.Add(E2,TopoDS::Vertex(tmpV));
916 Edges.InsertAfter(i-1,E1);
917 Edges.InsertAfter(i,E2);
921 if (nbEdges<Edges.Length()) {
922 // one of edges was splitted => we have to update WirePath
926 for (i=1; i<=Edges.Length(); i++) {
927 B.Add(W,TopoDS::Edge(Edges.Value(i)));
933 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
936 // Fill SplitEdgeNums and SplitLocNums with intermediate location indices
937 // and corresponding edge indices.
938 Standard_Integer i = 1;
943 for (j = 2; j < aSeqLocs.Length(); j++) {
944 SplitLocNums.Append(j);
945 aVert = TopoDS::Vertex(aSeqLocs.Value(j));
946 aP = BRep_Tool::Pnt(aVert);
948 while (i < Edges.Length()) {
951 TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i));
952 Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
953 Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp);
959 if (aP.Distance(aPLast) < aTol) {
960 SplitEdgeNums.Append(i - 1);
966 // check curvature of wire for condition that
967 // max summary angle between directions along
968 // wire path must be < 4*PI. If not - split wire
969 // and seguences of shapes, perform pipe for each
970 // and make sewing after that
975 if ( Edges.Length() > 0 ) {
976 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
979 SumAng = fabs(Vec1.Angle(Vec2));
984 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
985 for (i=2; i<=Edges.Length(); i++) {
986 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
987 double tol = BRep_Tool::Tolerance(edge);
988 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
990 double ang = fabs(Vec1.Angle(Vec2));
994 SplitEdgeNums.Append(i-1);
996 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
997 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
998 gp_Pnt P = BRep_Tool::Pnt(aVert);
999 if (P1.Distance(P) < tol) {
1000 SplitLocNums.Append(j);
1011 bool isCreateGroups = (theGroups != NULL);
1013 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
1014 TopTools_SequenceOfShape aSeqRes;
1015 TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
1016 Standard_Integer iGrp;
1017 int nn, num1 = 1, num2 = 1;
1018 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
1019 // create wirepath and sequences of shapes
1023 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
1024 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1026 num1 = SplitEdgeNums.Value(nn) + 1;
1027 TopTools_SequenceOfShape aTmpSeqBases;
1028 TopTools_SequenceOfShape aTmpSeqLocs;
1029 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
1030 aTmpSeqBases.Append(aSeqBases.Value(i));
1031 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1033 num2 = SplitLocNums.Value(nn);
1035 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1036 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1037 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1038 aBuilder.SetDiscreteMode();
1039 Standard_Integer nbShapes = aTmpSeqBases.Length();
1040 for (i=1; i<=nbShapes; i++) {
1041 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1042 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1043 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1045 if (!aBuilder.IsReady()) {
1046 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1049 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1051 if (isDone && NeedCreateSolid && nn == 1) {
1052 // Make solid for the first step.
1053 isDone = aBuilder.MakeSolid();
1057 Standard_ConstructionError::Raise("Pipe construction failure");
1060 TopoDS_Shape resShape = aBuilder.Shape();
1062 if (NeedCreateSolid && nn == 1) {
1063 // Remove top lid from the result.
1064 resShape = RemoveFaces(resShape, aBuilder.LastShape());
1067 aSeqRes.Append(resShape);
1070 if (isCreateGroups) {
1072 TopTools_SequenceOfShape aGroups[5];
1074 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1075 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1076 Standard_ConstructionError::Raise("Generate groups failure");
1079 // Get shapes from all groups.
1080 for (iGrp = 0; iGrp < 5; ++iGrp) {
1081 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1085 // create wirepath and sequences of shapes for last part
1089 for (i=num1; i<=Edges.Length(); i++) {
1090 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1092 TopTools_SequenceOfShape aTmpSeqBases;
1093 TopTools_SequenceOfShape aTmpSeqLocs;
1094 for (i=num2; i<=aSeqLocs.Length(); i++) {
1095 aTmpSeqBases.Append(aSeqBases.Value(i));
1096 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1098 // make pipe for last part
1099 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1100 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1101 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1102 aBuilder.SetDiscreteMode();
1103 Standard_Integer nbShapes = aTmpSeqBases.Length();
1104 for (i=1; i<=nbShapes; i++) {
1105 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1106 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1107 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1109 if (!aBuilder.IsReady()) {
1110 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1113 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1115 if (isDone && NeedCreateSolid) {
1116 isDone = aBuilder.MakeSolid();
1120 Standard_ConstructionError::Raise("Pipe construction failure");
1123 TopoDS_Shape resShape = aBuilder.Shape();
1125 if (NeedCreateSolid) {
1126 // Remove bottom lid from the result.
1127 resShape = RemoveFaces(resShape, aBuilder.FirstShape());
1130 aSeqRes.Append(resShape);
1133 if (isCreateGroups) {
1135 TopTools_SequenceOfShape aGroups[5];
1137 TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
1138 if (!DoGroups1(aProfile, aBuilder, aGroups)) {
1139 Standard_ConstructionError::Raise("Generate groups failure");
1142 // Get shapes from all groups.
1143 for (iGrp = 0; iGrp < 5; ++iGrp) {
1144 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1148 // make sewing for result
1149 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1150 aSewing->SetTolerance(Precision::Confusion());
1151 aSewing->SetFaceMode(Standard_True);
1152 aSewing->SetFloatingEdgesMode(Standard_False);
1153 aSewing->SetNonManifoldMode(Standard_False);
1154 for (i=1; i<=aSeqRes.Length(); i++) {
1155 aSewing->Add(aSeqRes.Value(i));
1158 aShape = aSewing->SewedShape();
1160 if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) {
1162 BRepBuilderAPI_MakeSolid aMkSolid;
1164 aMkSolid.Add(TopoDS::Shell(aShape));
1166 if (!aMkSolid.IsDone()) {
1167 Standard_ConstructionError::Raise("Can't create solid pipe");
1170 TopoDS_Solid aSolid = aMkSolid.Solid();
1171 BRepClass3d_SolidClassifier aSC(aSolid);
1173 aSC.PerformInfinitePoint(Precision::Confusion());
1175 if (aSC.State() == TopAbs_IN) {
1176 aShape = aSolid.Reversed();
1182 if (isCreateGroups) {
1183 // Replase Group shapes by modified ones.
1184 TopTools_SequenceOfShape aSeqGroups[5];
1187 for (iGrp = 0; iGrp < 5; ++iGrp) {
1189 for (i = 1; i <= aSeqRes.Length(); ++i) {
1190 if (iGrp == GROUP_DOWN && i > 1) {
1191 // For DOWN group we use only the first pipe.
1195 if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
1196 // For UP group we use only the last pipe.
1200 const TopTools_SequenceOfShape &aShapes =
1201 aMapResGroups[iGrp].Find(aSeqRes.Value(i));
1204 // For each sub-shape of pipe
1205 for (j = 1; j <= aShapes.Length(); ++j) {
1206 const TopoDS_Shape &aGrpShape = aShapes.Value(j);
1208 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1209 // Use the shape modified by sewing.
1210 const TopoDS_Shape &aModifGrpShape =
1211 aSewing->ModifiedSubShape(aGrpShape);
1213 aSeqGroups[iGrp].Append(aModifGrpShape);
1215 // Use the shape as it is.
1216 aSeqGroups[iGrp].Append(aGrpShape);
1223 TopTools_IndexedMapOfShape anIndices;
1225 TopExp::MapShapes(aShape, anIndices);
1227 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1228 Standard_ConstructionError::Raise("Generate groups failure");
1233 // old implementation without splitting
1234 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1235 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1236 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1237 aBuilder.SetDiscreteMode();
1239 Standard_Integer nbShapes = aSeqBases.Length();
1240 Standard_Integer step = nbShapes/nbBases;
1242 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1243 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1245 Standard_Integer ind =0;
1246 Standard_Real aTolConf = Precision::Confusion();
1247 Standard_Real aTolAng = Precision::Angular();
1249 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1250 TopTools_SequenceOfShape usedBases;
1251 Standard_Integer j = 1;
1252 for (; j <= nbBases; j++) {
1253 ind = i + (j-1)*step;
1254 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1255 usedBases.Append(aWireProf);
1257 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1258 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1259 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1262 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1264 if (!aBuilder.IsReady()) {
1265 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1268 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1270 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1272 if (isDone && NeedCreateSolid) {
1273 isDone = aBuilder.MakeSolid();
1277 Standard_ConstructionError::Raise("Pipe construction failure");
1279 aShape = aBuilder.Shape();
1281 if (isCreateGroups) {
1283 TopTools_SequenceOfShape aSeqGroups[5];
1285 TopoDS_Shape aProfile = usedBases.Value(1);
1286 if (!DoGroups1(aProfile, aBuilder, aSeqGroups)) {
1287 Standard_ConstructionError::Raise("Generate groups failure");
1291 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1292 TopTools_IndexedMapOfShape anIndices;
1293 const TopoDS_Shape aResult = aBuilder.Shape();
1295 TopExp::MapShapes(aResult, anIndices);
1297 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1298 Standard_ConstructionError::Raise("Generate groups failure");
1301 aSeqFaces.Append(aShape);
1302 for (j = 1; j <=usedBases.Length(); j++)
1303 aBuilder.Delete(usedBases.Value(j));
1310 //=======================================================================
1311 //function : CreatePipeForShellSections
1312 //purpose : auxilary for Execute()
1313 //=======================================================================
1314 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1315 GEOMImpl_IPipe* aCI)
1320 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1321 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1322 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1323 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1324 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1325 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1326 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1328 Standard_Integer nbBases = aBasesObjs->Length(),
1329 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1330 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1332 if (nbLocs != nbBases) {
1333 if (aCI) delete aCI;
1334 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1336 if (nbSubBases && nbSubBases != nbBases) {
1337 if (aCI) delete aCI;
1338 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1341 TopTools_SequenceOfShape VLocs;
1342 for (i=1; i<=nbBases; i++) {
1343 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1344 if (anItemLoc.IsNull())
1346 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1347 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1348 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1350 VLocs.Append(aShapeLoc);
1352 nbLocs = VLocs.Length();
1353 if (nbLocs != nbBases) {
1354 if (aCI) delete aCI;
1355 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1357 // split wire path by location points
1358 TColgp_SequenceOfPnt PLocs;
1359 for (i=1; i<=nbLocs; i++) {
1360 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1361 PLocs.Append(BRep_Tool::Pnt(V));
1364 TopTools_SequenceOfShape Edges;
1365 TopTools_SequenceOfShape Wires;
1366 ShapeAnalysis_Edge sae;
1369 TopExp_Explorer anExp;
1370 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1371 Edges.Append(anExp.Current());
1373 Standard_Integer Num1 = 0;
1374 Standard_Integer Num2 = 0;
1375 for (i=1; i<=Edges.Length(); i++) {
1376 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1377 double tol = BRep_Tool::Tolerance(E);
1378 TopoDS_Vertex V1 = sae.FirstVertex(E);
1379 TopoDS_Vertex V2 = sae.LastVertex(E);
1380 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1381 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1382 if (P1.Distance(PLocs.First()) < tol) {
1385 if (P2.Distance(PLocs.Last()) < tol) {
1389 if (Num1>0 && Num2>0) {
1392 for (i=Num1; i<=Num2; i++) {
1393 B.Add(W,Edges.Value(i));
1398 Wires.Append(aWirePath);
1402 TopExp_Explorer anExp;
1403 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1404 Edges.Append(anExp.Current());
1406 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1407 double tol = BRep_Tool::Tolerance(edge);
1408 TopoDS_Vertex VF = sae.FirstVertex(edge);
1409 gp_Pnt PF = BRep_Tool::Pnt(VF);
1410 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1411 if (PF.Distance(PLocs.First()) > tol) {
1412 if (aCI) delete aCI;
1413 Standard_ConstructionError::Raise
1414 ("First location shapes is not coincided with first vertex of aWirePath");
1416 VLocs.ChangeValue(1) = VF;
1417 edge = TopoDS::Edge(Edges.Last());
1418 tol = BRep_Tool::Tolerance(edge);
1419 TopoDS_Vertex VL = sae.LastVertex(edge);
1420 gp_Pnt PL = BRep_Tool::Pnt(VL);
1421 if (PL.Distance(PLocs.Last()) > tol) {
1422 if (aCI) delete aCI;
1423 Standard_ConstructionError::Raise
1424 ("Last location shapes is not coincided with last vertex of aWirePath");
1426 VLocs.ChangeValue(nbLocs) = VL;
1428 TopTools_SequenceOfShape tmpEdges;
1429 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1430 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1431 tol = BRep_Tool::Tolerance(E);
1432 TopoDS_Vertex V1 = sae.FirstVertex(E);
1433 TopoDS_Vertex V2 = sae.LastVertex(E);
1434 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1435 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1436 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1437 // make wire from current edge and add created
1441 for (j=1; j<=tmpEdges.Length(); j++)
1442 B.Add(W,tmpEdges.Value(j));
1445 VLocs.ChangeValue(jcurr) = V2;
1450 // find distance between E and aLocs(jcurr)
1452 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1453 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1454 if (PPCurve.NbPoints()>0 &&
1455 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1456 double param = PPCurve.Parameter(1);
1459 // split current edge
1460 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1461 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1465 if (Pfp.Distance(P1)<tol) {
1466 B.MakeEdge(E1,tc1,tol);
1468 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1469 B.Add(E1,TopoDS::Vertex(tmpV));
1470 tmpEdges.Append(E1);
1471 B.MakeEdge(E2,tc2,tol);
1472 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1473 B.Add(E2,TopoDS::Vertex(tmpV));
1477 B.MakeEdge(E1,tc2,tol);
1478 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1479 B.Add(E1,TopoDS::Vertex(tmpV));
1482 tmpEdges.Append(E1);
1483 B.MakeEdge(E2,tc1,tol);
1485 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1486 B.Add(E2,TopoDS::Vertex(tmpV));
1489 // create wire from tmpEdges
1492 for (j=1; j<=tmpEdges.Length(); j++)
1493 B.Add(W,tmpEdges.Value(j));
1498 Edges.InsertAfter(i-1,E1);
1499 Edges.InsertAfter(i,E2);
1506 // create wire from other edges
1509 for (; i<=Edges.Length(); i++)
1510 B.Add(W,Edges.Value(i));
1514 if (Wires.Length() != nbLocs-1) {
1515 if (aCI) delete aCI;
1516 Standard_ConstructionError::Raise
1517 ("One of location shapes is not lied on the path");
1520 TopTools_SequenceOfShape aGroups[5];
1521 TopoDS_Compound aComp;
1522 B.MakeCompound(aComp);
1523 for (i = 1; i < nbBases; i++) {
1524 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1526 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1527 if (anItem1.IsNull())
1529 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1530 if (aRefBase1.IsNull())
1532 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1533 if (aShBase1.IsNull())
1535 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1537 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1538 if (anItem2.IsNull())
1540 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1541 if (aRefBase2.IsNull())
1543 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1544 if (aShBase2.IsNull())
1546 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1548 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1549 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1551 if (aCI) delete aCI;
1552 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1555 bool CreateFewSolids = false;
1557 TopExp_Explorer anExp;
1558 Standard_Integer nbf1 = 0;
1559 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1562 Standard_Integer nbf2 = 0;
1563 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1567 CreateFewSolids = true;
1570 if (!CreateFewSolids) {
1571 // we can create only one solid
1572 TopoDS_Shape aWire1, aWire2;
1574 if (aType1==TopAbs_SHELL) {
1575 // create wire as boundary contour if shell is no closed
1576 // get free boundary shapes
1577 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1578 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1579 //TopExp_Explorer anExp;
1580 Standard_Integer NbWires = 0;
1581 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1583 aWire1 = anExp.Current();
1587 if (aCI) delete aCI;
1588 Standard_ConstructionError::Raise("Bad shell is used as section ");
1591 else { // aType1==TopAbs_FACE
1592 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1593 aWire1 = aExpW.Current();
1596 if (aType2==TopAbs_SHELL) {
1597 // create wire as boundary contour if shell is no closed
1598 // get free boundary shapes
1599 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1600 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1601 //TopExp_Explorer anExp;
1602 Standard_Integer NbWires = 0;
1603 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1605 aWire2 = anExp.Current();
1609 if (aCI) delete aCI;
1610 Standard_ConstructionError::Raise("Bad shell is used as section ");
1613 else { // aType2==TopAbs_FACE
1614 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1615 aWire2 = aExpW.Current();
1617 // make pipe using aWire1 and aWire2
1618 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1619 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1620 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1621 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1622 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1623 aBuilder.SetDiscreteMode();
1624 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1625 aWithContact, aWithCorrect);
1626 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1627 aWithContact, aWithCorrect);
1628 if (!aBuilder.IsReady()) {
1629 if (aCI) delete aCI;
1630 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1633 BuildPipeShell(aBuilder);
1635 TopoDS_Shape aShape = aBuilder.Shape();
1636 TopTools_SequenceOfShape aLocalGroups[5];
1639 if (isGenerateGroups) {
1641 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
1642 if (aCI) delete aCI;
1643 Standard_ConstructionError::Raise("Generate groups failure");
1646 // Clear the groups Down and Up.
1647 aLocalGroups[GROUP_DOWN].Clear();
1648 aLocalGroups[GROUP_UP].Clear();
1651 TopoDS_Shell aShell;
1652 B.MakeShell(aShell);
1653 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1654 B.Add(aShell,anExp.Current());
1656 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1657 B.Add(aShell,anExp.Current());
1659 if (isGenerateGroups && i == 1) {
1660 aLocalGroups[GROUP_DOWN].Append(anExp.Current());
1663 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1664 B.Add(aShell,anExp.Current());
1666 if (isGenerateGroups && i == nbBases - 1) {
1667 aLocalGroups[GROUP_UP].Append(anExp.Current());
1670 // make sewing for this shell
1671 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1672 aSewing->SetTolerance(Precision::Confusion());
1673 aSewing->SetFaceMode(Standard_True);
1674 aSewing->SetFloatingEdgesMode(Standard_False);
1675 aSewing->SetNonManifoldMode(Standard_False);
1676 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1677 aSewing->Add(anExp.Current());
1680 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1681 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1682 aShell = TopoDS::Shell(aSewShape);
1683 GProp_GProps aSystem;
1684 BRepGProp::VolumeProperties(aShell, aSystem);
1685 if (aSystem.Mass()<0) {
1688 if (BRep_Tool::IsClosed(aShell)) {
1689 TopoDS_Solid aSolid;
1690 B.MakeSolid(aSolid);
1691 B.Add(aSolid,aShell);
1692 B.Add(aComp,aSolid);
1695 B.Add(aComp,aShell);
1699 B.Add(aComp,aShell);
1702 if (isGenerateGroups) {
1703 Standard_Integer iGrp;
1705 for (iGrp = 0; iGrp < 5; ++iGrp) {
1708 // For each sub-shape of pipe
1709 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1710 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1712 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1713 // Use the shape modified by sewing.
1714 const TopoDS_Shape &aModifGrpShape =
1715 aSewing->ModifiedSubShape(aGrpShape);
1717 aGroups[iGrp].Append(aModifGrpShape);
1719 // Use the shape as it is.
1720 aGroups[iGrp].Append(aGrpShape);
1728 // main block - creation few solids (for each pair of faces)
1729 TopTools_MapOfShape aFaces1,aFaces2;
1730 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1731 aFaces1.Add(anExp.Current());
1733 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1734 aFaces2.Add(anExp.Current());
1736 // creating map of edge faces
1737 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1738 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1739 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1740 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1742 // constuct map face->face
1743 TopTools_IndexedDataMapOfShapeShape FF;
1744 TopoDS_Shape FS1,FS2;
1745 if (nbSubBases==0) {
1746 // find edge the most distant from location point
1747 // (this edge is not shared by two faces)
1748 double maxdist = 0.;
1750 TopoDS_Vertex V11,V21;
1751 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1752 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1753 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1754 if (aList.Extent()>1)
1756 TopExp_Explorer expv;
1757 expv.Init(tmp, TopAbs_VERTEX);
1758 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1760 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1761 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1762 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1763 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1768 TopTools_ListIteratorOfListOfShape anIter(aList);
1769 FS1 = anIter.Value();
1773 // main direction for comparing
1774 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1775 // find corresponding edge from next section
1776 double minang = M_PI;
1777 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1778 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1780 TopoDS_Vertex V12,V22;
1781 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1782 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1783 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1784 if (aList.Extent()>1)
1786 TopExp_Explorer expv;
1787 expv.Init(tmp, TopAbs_VERTEX);
1788 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1790 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1791 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1792 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1793 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1794 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1795 TopoDS_Vertex V1,V2;
1798 V1 = V2tmp; P1 = P2tmp;
1799 V2 = V1tmp; P2 = P1tmp;
1802 V1 = V1tmp; P1 = P1tmp;
1803 V2 = V2tmp; P2 = P2tmp;
1805 gp_Vec Vec1(P11,P1);
1806 gp_Vec Vec2(P21,P2);
1807 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1812 TopTools_ListIteratorOfListOfShape anIter(aList);
1813 FS2 = anIter.Value();
1817 // put all pairs to map FF
1823 // add pairs of edges to FF
1824 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1826 if (aCI) delete aCI;
1827 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1833 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1834 if (anItem.IsNull()) {
1835 if (aCI) delete aCI;
1836 Standard_ConstructionError::Raise("Invalid subbase shape");
1838 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1839 if (aRefBase.IsNull()) {
1840 if (aCI) delete aCI;
1841 Standard_ConstructionError::Raise("Invalid subbase shape");
1843 TopoDS_Shape aSh = aRefBase->GetValue();
1845 if (aCI) delete aCI;
1846 Standard_ConstructionError::Raise("Invalid subbase shape");
1848 if (aSh.ShapeType()!=TopAbs_FACE) {
1849 if (aCI) delete aCI;
1850 Standard_ConstructionError::Raise("Invalid subbase shape");
1855 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1856 if (anItem.IsNull()) {
1857 if (aCI) delete aCI;
1858 Standard_ConstructionError::Raise("Invalid subbase shape");
1860 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1861 if (aRefBase.IsNull()) {
1862 if (aCI) delete aCI;
1863 Standard_ConstructionError::Raise("Invalid subbase shape");
1865 TopoDS_Shape aSh = aRefBase->GetValue();
1867 if (aCI) delete aCI;
1868 Standard_ConstructionError::Raise("Invalid subbase shape");
1870 if (aSh.ShapeType()!=TopAbs_FACE) {
1871 if (aCI) delete aCI;
1872 Standard_ConstructionError::Raise("Invalid subbase shape");
1877 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1878 if (aCI) delete aCI;
1879 Standard_ConstructionError::Raise("Invalid subbase shape");
1884 // add pairs of edges to FF
1885 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1886 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1888 if (aCI) delete aCI;
1889 Standard_ConstructionError::Raise("Can not create correct pipe");
1893 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1895 // make pipe for each pair of faces
1896 for (j=1; j<=FF.Extent(); j++) {
1897 TopoDS_Shape F1 = FF.FindKey(j);
1898 if (F1.ShapeType() != TopAbs_FACE)
1900 TopoDS_Shape F2 = FF.FindFromIndex(j);
1901 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1902 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1903 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1904 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1905 // make pipe using aWire1 and aWire2
1906 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1907 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1908 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1909 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1910 aBuilder.SetDiscreteMode();
1911 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1912 aWithContact, aWithCorrect);
1913 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1914 aWithContact, aWithCorrect);
1915 if (!aBuilder.IsReady()) {
1916 if (aCI) delete aCI;
1917 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1920 BuildPipeShell(aBuilder);
1922 TopoDS_Shape aShape = aBuilder.Shape();
1923 TopTools_SequenceOfShape aLocalGroups[5];
1926 if (isGenerateGroups) {
1928 if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
1929 if (aCI) delete aCI;
1930 Standard_ConstructionError::Raise("Generate groups failure");
1933 // Clear the groups Down and Up.
1934 aLocalGroups[GROUP_DOWN].Clear();
1935 aLocalGroups[GROUP_UP].Clear();
1938 aLocalGroups[GROUP_DOWN].Append(F1);
1941 if (i == nbBases - 1) {
1942 aLocalGroups[GROUP_UP].Append(F2);
1946 TopoDS_Shell aShell;
1947 B.MakeShell(aShell);
1948 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1949 B.Add(aShell,anExp.Current());
1954 // make sewing for this shell
1955 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1956 aSewing->SetTolerance(Precision::Confusion());
1957 aSewing->SetFaceMode(Standard_True);
1958 aSewing->SetFloatingEdgesMode(Standard_False);
1959 aSewing->SetNonManifoldMode(Standard_False);
1960 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1961 aSewing->Add(anExp.Current());
1964 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1965 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1966 aShell = TopoDS::Shell(aSewShape);
1967 GProp_GProps aSystem;
1968 BRepGProp::VolumeProperties(aShell, aSystem);
1969 if (aSystem.Mass()<0) {
1970 //cout<<"aSewShape is reversed"<<endl;
1973 if (BRep_Tool::IsClosed(aShell)) {
1974 TopoDS_Solid aSolid;
1975 B.MakeSolid(aSolid);
1976 B.Add(aSolid,aShell);
1977 B.Add(aComp,aSolid);
1980 B.Add(aComp,aShell);
1984 B.Add(aComp,aShell);
1987 if (isGenerateGroups) {
1988 // Replase Group shapes by modified ones.
1989 Standard_Integer iGrp;
1992 for (iGrp = 0; iGrp < 5; ++iGrp) {
1995 // For each sub-shape of pipe
1996 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1997 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1999 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2000 // Use the shape modified by sewing.
2001 const TopoDS_Shape &aModifGrpShape =
2002 aSewing->ModifiedSubShape(aGrpShape);
2004 aGroups[iGrp].Append(aModifGrpShape);
2006 // Use the shape as it is.
2007 aGroups[iGrp].Append(aGrpShape);
2017 if (isGenerateGroups) {
2019 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2020 TopTools_IndexedMapOfShape anIndices;
2022 TopExp::MapShapes(aComp, anIndices);
2024 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2025 if (aCI) delete aCI;
2026 Standard_ConstructionError::Raise("Generate groups failure");
2029 StoreGroups(aCI, aGroupIds);
2035 //=======================================================================
2036 //function : CreatePipeShellsWithoutPath
2037 //purpose : auxilary for Execute()
2038 //=======================================================================
2039 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
2041 //cout<<"CreatePipeShellsWithoutPath"<<endl;
2045 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
2047 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
2048 // vertex for recognition
2049 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
2050 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
2052 Standard_Integer nbBases = aBasesObjs->Length(),
2053 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
2055 if (nbv != nbBases) {
2056 if (aCI) delete aCI;
2057 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
2060 TopTools_SequenceOfShape aGroups[5];
2061 TopTools_SequenceOfShape SecVs,Bases;
2062 for (i=1; i<=nbBases; i++) {
2064 Handle(Standard_Transient) anItem = VObjs->Value(i);
2065 if (anItem.IsNull())
2067 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
2068 TopoDS_Shape V = aRef->GetValue();
2069 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
2073 anItem = aBasesObjs->Value(i);
2074 if (anItem.IsNull())
2076 aRef = Handle(GEOM_Function)::DownCast(anItem);
2077 TopoDS_Shape aSh = aRef->GetValue();
2082 nbv = SecVs.Length();
2083 nbBases = Bases.Length();
2084 if (nbv != nbBases) {
2085 if (aCI) delete aCI;
2086 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
2089 TopoDS_Compound aComp;
2090 B.MakeCompound(aComp);
2092 for (i = 1; i < nbBases; i++) {
2093 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
2094 TopoDS_Shape aShBase1 = Bases.Value(i);
2095 TopoDS_Shape aShBase2 = Bases.Value(i+1);
2096 TopExp_Explorer anExp;
2097 Standard_Integer nbf1 = 0;
2098 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2101 Standard_Integer nbf2 = 0;
2102 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2105 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
2107 if (aCI) delete aCI;
2108 Standard_ConstructionError::Raise("Different number of faces in the sections");
2111 TopTools_MapOfShape aFaces1,aFaces2;
2112 TopTools_MapOfShape aBndEdges1;
2114 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2115 const TopoDS_Shape &aBaseFace1 = anExp.Current();
2117 if (aFaces1.Add(aBaseFace1)) {
2118 // Get boundary edges.
2119 TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
2121 for (; anExpE.More(); anExpE.Next()) {
2122 const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
2124 if (!aBndEdges1.Add(aBaseEdge1)) {
2125 aBndEdges1.Remove(aBaseEdge1);
2130 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2131 aFaces2.Add(anExp.Current());
2134 // creating map of edge faces
2135 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
2136 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
2137 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
2138 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
2140 // constuct map face->face (and sub-shapes)
2141 TopTools_IndexedDataMapOfShapeShape FF;
2142 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
2143 TopoDS_Shape FS1, FS2;
2144 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
2145 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
2146 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
2149 MESSAGE (" first pair of corresponding faces is found");
2151 // add pairs of edges and vertexes to FF
2152 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
2154 if (aCI) delete aCI;
2155 Standard_ConstructionError::Raise("Can not create correct pipe");
2157 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
2159 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2160 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
2162 // make pipe for each pair of faces
2163 // auxilary map vertex->edge for created pipe edges
2164 TopTools_IndexedDataMapOfShapeShape VPE;
2165 ShapeAnalysis_Edge sae;
2166 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
2168 for (j=1; j<=FF.Extent(); j++) {
2169 TopoDS_Shape F1 = FF.FindKey(j);
2170 if (F1.ShapeType() != TopAbs_FACE)
2172 TopoDS_Shape F2 = FF.FindFromIndex(j);
2175 //if (nbff!=3) continue;
2177 MESSAGE (" make pipe for "<<nbff<<" face");
2179 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
2180 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2181 Handle(Geom_RectangularTrimmedSurface) RTS =
2182 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
2183 S1 = RTS->BasisSurface();
2185 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
2186 if (Pln1.IsNull()) {
2187 if (aCI) delete aCI;
2188 Standard_ConstructionError::Raise("Surface from face is not plane");
2190 gp_Vec aDir1(Pln1->Axis().Direction());
2192 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
2193 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2194 Handle(Geom_RectangularTrimmedSurface) RTS =
2195 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
2196 S2 = RTS->BasisSurface();
2198 Handle(Geom_Plane) Pln2 =
2199 Handle(Geom_Plane)::DownCast(S2);
2200 if (Pln2.IsNull()) {
2201 if (aCI) delete aCI;
2202 Standard_ConstructionError::Raise("Surface from face is not plane");
2204 gp_Vec aDir2(Pln2->Axis().Direction());
2206 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
2207 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
2209 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
2211 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
2214 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
2215 TopTools_SequenceOfShape aNewFs;
2216 TopTools_SequenceOfShape aLocalGroups[5];
2219 for (; anExpE.More(); anExpE.Next()) {
2220 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2222 if (!FF.Contains(E1))
2223 MESSAGE ("map FF not contains key E1");
2225 if (VPE.Contains(E1)) {
2226 aNewFs.Append(VPE.FindFromKey(E1));
2228 MESSAGE (" using existed face");
2233 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2234 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2235 TopoDS_Vertex V2 = sae.LastVertex(E1);
2236 if (!FF.Contains(V1))
2237 MESSAGE ("map FF not contains key V1");
2238 if (!FF.Contains(V2))
2239 MESSAGE ("map FF not contains key V2");
2240 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2241 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2242 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2243 if (Vtmp.IsSame(V4))
2245 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2246 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2247 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2248 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2251 Handle(Geom_BSplineCurve) C2;
2252 if (VPE.Contains(V2)) {
2253 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2255 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2258 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2259 HAP->SetValue(1,P2);
2260 HAP->SetValue(2,P3);
2261 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2262 anInt.Load(aDir1,aDir2);
2265 B.MakeEdge(E2,C2,1.e-7);
2266 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2267 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2272 Handle(Geom_BSplineCurve) C4;
2273 if (VPE.Contains(V1)) {
2274 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2276 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2279 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2280 HAP->SetValue(1,P1);
2281 HAP->SetValue(2,P4);
2282 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2283 anInt.Load(aDir1,aDir2);
2286 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2287 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2288 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2297 B.Add(W,E4.Reversed());
2302 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2303 //bool IsConicC1 = false;
2304 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2305 // IsConicC1 = true;
2306 // cout<<"C1 - Geom_Conic"<<endl;
2308 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2309 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2312 // double tol = BRep_Tool::Tolerance(E1);
2313 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2314 // C1 = ApxC1.Curve();
2316 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2317 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2318 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2323 Handle(Geom_BSplineCurve) CE1 =
2324 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2325 if (CE1->Degree()<3)
2326 CE1->IncreaseDegree(3);
2327 Handle(Geom_BSplineCurve) CE2 =
2328 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2329 if (CE2->Degree()<3)
2330 CE2->IncreaseDegree(3);
2331 Handle(Geom_BSplineCurve) CE3 =
2332 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2333 if (CE3->Degree()<3)
2334 CE3->IncreaseDegree(3);
2335 Handle(Geom_BSplineCurve) CE4 =
2336 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2337 if (CE4->Degree()<3)
2338 CE4->IncreaseDegree(3);
2340 Handle(Geom_Surface) BS;
2342 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2343 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2347 MESSAGE (" can not create BSplineSurface - create Bezier");
2349 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2350 double fp1,lp1,fp2,lp2;
2351 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2352 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2361 // get points from C1
2362 if (P1.Distance(P1C1)<1.e-6) {
2370 double step = (lp-fp)/(NbP-1);
2371 Points.SetValue(1,1,P1);
2373 for (n1=2; n1<NbP; n1++) {
2377 Points.SetValue(1,n1,P);
2379 Points.SetValue(1,NbP,P2);
2380 // get points from C3
2381 if (P4.Distance(P1C3)<1.e-6) {
2389 step = (lp-fp)/(NbP-1);
2390 Points.SetValue(NbP,1,P4);
2392 for (n1=2; n1<NbP; n1++) {
2396 Points.SetValue(NbP,n1,P);
2398 Points.SetValue(NbP,NbP,P3);
2399 // create isolines and get points from them
2400 for (n1=1; n1<=NbP; n1++) {
2401 gp_Pnt PI1 = Points.Value(1,n1);
2402 gp_Pnt PI2 = Points.Value(NbP,n1);
2403 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2404 HAP->SetValue(1,PI1);
2405 HAP->SetValue(2,PI2);
2406 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2407 anInt.Load(aDir1,aDir2);
2409 const Handle(Geom_BSplineCurve) iso = anInt.Curve();
2410 fp = iso->FirstParameter();
2411 lp = iso->LastParameter();
2412 step = (lp-fp)/(NbP-1);
2414 TopoDS_Compound VComp;
2415 B.MakeCompound(VComp);
2416 for (n2=2; n2<NbP; n2++) {
2420 Points.SetValue(n2,n1,P);
2423 // create surface and face
2424 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2425 BS = new Geom_BezierSurface(Points);
2428 BRepBuilderAPI_MakeFace BB(BS,W);
2429 TopoDS_Face NewF = BB.Face();
2430 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2432 sff->FixOrientation();
2433 TopoDS_Face FixedFace = sff->Face();
2434 aNewFs.Append(FixedFace);
2435 VPE.Add(E1,FixedFace);
2437 if (isGenerateGroups) {
2438 if (aBndEdges1.Contains(E1)) {
2439 // This is a boundary face.
2440 aLocalGroups[GROUP_OTHER].Append(FixedFace);
2445 TopoDS_Shell aShell;
2446 B.MakeShell(aShell);
2447 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2448 B.Add(aShell,aNewFs(nf));
2454 if (isGenerateGroups && i == 1) {
2455 aLocalGroups[GROUP_DOWN].Append(F1);
2458 if (isGenerateGroups && i == nbBases - 1) {
2459 aLocalGroups[GROUP_UP].Append(F2);
2462 // make sewing for this shell
2463 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2464 aSewing->SetTolerance(Precision::Confusion());
2465 aSewing->SetFaceMode(Standard_True);
2466 aSewing->SetFloatingEdgesMode(Standard_False);
2467 aSewing->SetNonManifoldMode(Standard_False);
2468 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2469 aSewing->Add(anExp.Current());
2472 MESSAGE (" shell for face "<<nbff<<" is created");
2473 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2474 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2475 aShell = TopoDS::Shell(aSewShape);
2476 GProp_GProps aSystem;
2477 BRepGProp::VolumeProperties(aShell, aSystem);
2478 if (aSystem.Mass()<0) {
2479 //cout<<"aSewShape is reversed"<<endl;
2482 if (BRep_Tool::IsClosed(aShell)) {
2483 TopoDS_Solid aSolid;
2484 B.MakeSolid(aSolid);
2485 B.Add(aSolid,aShell);
2486 B.Add(aComp,aSolid);
2487 MESSAGE (" solid for face "<<nbff<<" is created");
2490 B.Add(aComp,aShell);
2491 MESSAGE (" solid for face "<<nbff<<" is not created");
2495 B.Add(aComp,aShell);
2496 MESSAGE (" solid for face "<<nbff<<" is not created");
2499 if (isGenerateGroups) {
2500 Standard_Integer iGrp;
2502 for (iGrp = 0; iGrp < 5; ++iGrp) {
2505 // For each sub-shape of pipe
2506 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2507 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2509 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2510 // Use the shape modified by sewing.
2511 const TopoDS_Shape &aModifGrpShape =
2512 aSewing->ModifiedSubShape(aGrpShape);
2514 aGroups[iGrp].Append(aModifGrpShape);
2516 // Use the shape as it is.
2517 aGroups[iGrp].Append(aGrpShape);
2525 if (isGenerateGroups) {
2527 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2528 TopTools_IndexedMapOfShape anIndices;
2530 TopExp::MapShapes(aComp, anIndices);
2532 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2533 if (aCI) delete aCI;
2534 Standard_ConstructionError::Raise("Generate groups failure");
2537 StoreGroups(aCI, aGroupIds);
2543 //=======================================================================
2544 //function : CreatePipeBiNormalAlongVector
2545 //purpose : auxilary for Execute()
2546 //=======================================================================
2547 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2548 GEOMImpl_IPipe* aCI)
2550 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2552 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2553 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2554 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2555 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2557 if (aShapeBase.IsNull()) {
2558 if (aCIBN) delete aCIBN;
2559 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2562 // Make copy to prevent modifying of base object: 0021525
2563 BRepBuilderAPI_Copy Copy (aShapeBase);
2565 aShapeBase = Copy.Shape();
2568 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2571 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2572 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2574 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2577 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2578 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2579 aProf = wexp.Current();
2582 Standard_TypeMismatch::Raise
2583 ("MakePipe aborted : invalid type of base");
2585 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2586 PipeBuilder.Add(aProf);
2588 if (aShapeVec.IsNull()) {
2589 if (aCIBN) delete aCIBN;
2590 Standard_NullObject::Raise
2591 ("MakePipe aborted : null vector argument");
2593 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2594 Standard_TypeMismatch::Raise
2595 ("MakePipe aborted: invalid type of vector");
2596 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2597 TopoDS_Vertex V1, V2;
2598 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2599 if (V1.IsNull() || V2.IsNull())
2600 Standard_NullObject::Raise
2601 ("MakePipe aborted: vector is not defined");
2602 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2603 gp_Dir BiNormal(aVec);
2604 PipeBuilder.SetMode(BiNormal);
2606 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2608 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2609 PipeBuilder.MakeSolid();
2612 if (!CreateGroups1(aProf, PipeBuilder, aCIBN)) {
2613 if (aCIBN) delete aCIBN;
2614 Standard_ConstructionError::Raise("Generate groups failure");
2617 return PipeBuilder.Shape();
2620 //=======================================================================
2621 //function : FillGroups
2622 //purpose : auxilary for DoGroups()
2623 //=======================================================================
2624 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
2625 const TopTools_IndexedMapOfShape &theIndices,
2626 Handle(TColStd_HArray1OfInteger) *theGroupIds)
2630 for (i = 0; i < 5; ++i) {
2631 if (!theGroups[i].IsEmpty()) {
2632 const Standard_Integer aNbShapes = theGroups[i].Length();
2635 theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
2637 for (j = 1; j <= aNbShapes; ++j) {
2638 const TopoDS_Shape &aShape = theGroups[i].Value(j);
2639 const Standard_Integer anIndex = theIndices.FindIndex(aShape);
2645 theGroupIds[i]->SetValue(j, anIndex);
2653 //=======================================================================
2654 //function : StoreGroups
2655 //purpose : auxilary for CreateGroups()
2656 //=======================================================================
2657 void StoreGroups(GEOMImpl_IPipe *theCI,
2658 Handle(TColStd_HArray1OfInteger) *theGroups)
2660 if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
2661 theCI->SetGroupDown(theGroups[GROUP_DOWN]);
2664 if (theGroups[GROUP_UP].IsNull() == Standard_False) {
2665 theCI->SetGroupUp(theGroups[GROUP_UP]);
2668 if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
2669 theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
2672 if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
2673 theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
2676 if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
2677 theCI->SetGroupOther(theGroups[GROUP_OTHER]);
2681 //=======================================================================
2682 //function : CreateDownUpGroups
2683 //purpose : auxilary for DoGroups()
2684 //=======================================================================
2685 static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
2686 TopTools_SequenceOfShape *theGroups,
2687 Standard_Boolean &IsDoSides)
2689 const TopoDS_Shape aDownShape = theSweep->FirstShape();
2690 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2691 TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
2693 IsDoSides = Standard_False;
2698 anUpDownType = TopAbs_EDGE;
2700 if (GEOMUtils::IsOpenPath(aDownShape)) {
2701 IsDoSides = Standard_True;
2706 anUpDownType = TopAbs_FACE;
2712 if (anUpDownType == TopAbs_SHAPE) {
2713 // Invalid Up and Down group type.
2717 TopExp_Explorer anExp(aDownShape, anUpDownType);
2718 TopTools_MapOfShape aMapFence;
2720 // Create Down group.
2721 for (; anExp.More(); anExp.Next()) {
2722 const TopoDS_Shape &aShape = anExp.Current();
2724 if (aMapFence.Add(aShape)) {
2725 theGroups[GROUP_DOWN].Append(aShape);
2730 const TopoDS_Shape anUpShape = theSweep->LastShape();
2733 anExp.Init(anUpShape, anUpDownType);
2735 for (; anExp.More(); anExp.Next()) {
2736 const TopoDS_Shape &aShape = anExp.Current();
2738 if (aMapFence.Add(aShape)) {
2739 theGroups[GROUP_UP].Append(aShape);
2746 //=======================================================================
2747 //function : DoGroups1
2748 //purpose : auxilary for CreateGroups1()
2749 //=======================================================================
2750 bool DoGroups1 (const TopoDS_Shape &theProfile,
2751 BRepOffsetAPI_MakePipeShell &theSweep,
2752 TopTools_SequenceOfShape *theGroups)
2754 Standard_Boolean isDoSides = Standard_False;
2756 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2757 // Up and Down groups creation failure
2761 TopoDS_Shape aDownShape = theProfile;
2762 if (aDownShape.IsNull()) aDownShape = theSweep.FirstShape();
2765 // Create Side1 and Side2 groups.
2766 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2767 TopoDS_Vertex aV[2];
2770 if (aType == TopAbs_EDGE) {
2771 TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
2772 } else { // aType == TopAbs_WIRE
2773 TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
2776 for (i = 0; i < 2; ++i) {
2777 if (aV[i].IsNull() == Standard_False) {
2778 const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
2780 if (!aLstSide.IsEmpty()) {
2781 TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
2782 TopTools_MapOfShape aMapFence;
2783 const Standard_Integer anIdSide =
2784 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2786 for (; aSideIt.More(); aSideIt.Next()) {
2787 const TopoDS_Shape &aSideShape = aSideIt.Value();
2789 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2790 if (aMapFence.Add(aSideShape)) {
2791 theGroups[anIdSide].Append(aSideShape);
2793 } else if (aSideShape.ShapeType() == TopAbs_WIRE) {
2794 if (aMapFence.Add(aSideShape)) {
2795 TopExp_Explorer anExpWE (aSideShape, TopAbs_EDGE);
2796 for (; anExpWE.More(); anExpWE.Next()) {
2797 theGroups[anIdSide].Append(anExpWE.Current());
2801 // Only edges can be in Side1 and Side2 groups.
2809 // Create Other group. Get boundary edges of the profile.
2810 TopTools_MapOfShape aMapBndEdges;
2811 TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
2813 for (; anExp.More(); anExp.Next()) {
2814 const TopoDS_Shape &anEdge = anExp.Current();
2816 if (!aMapBndEdges.Add(anEdge)) {
2817 aMapBndEdges.Remove(anEdge);
2821 // Fill the map of faces generated from profile's boundary edges.
2822 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2823 TopTools_MapOfShape aMapFence;
2825 for (; anIter.More(); anIter.Next()) {
2826 const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
2828 if (!aLstOther.IsEmpty()) {
2829 TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
2831 for (; anOtherIt.More(); anOtherIt.Next()) {
2832 const TopoDS_Shape &anOtherShape = anOtherIt.Value();
2834 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2835 if (aMapFence.Add(anOtherShape)) {
2836 theGroups[GROUP_OTHER].Append(anOtherShape);
2838 } else if (anOtherShape.ShapeType() == TopAbs_SHELL) {
2839 if (aMapFence.Add(anOtherShape)) {
2840 TopExp_Explorer anExpSHF (anOtherShape, TopAbs_FACE);
2841 for (; anExpSHF.More(); anExpSHF.Next()) {
2842 theGroups[GROUP_OTHER].Append(anExpSHF.Current());
2846 // Only faces can be in Other group.
2857 //=======================================================================
2858 //function : CreateGroups1
2859 //purpose : auxilary for Execute()
2860 //=======================================================================
2861 bool CreateGroups1 (const TopoDS_Shape &theProfile,
2862 BRepOffsetAPI_MakePipeShell &theSweep,
2863 GEOMImpl_IPipe *theCI)
2865 if (!theCI->GetGenerateGroups()) {
2871 TopTools_SequenceOfShape aGroups[5];
2873 if (!DoGroups1(theProfile, theSweep, aGroups)) {
2878 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2879 TopTools_IndexedMapOfShape anIndices;
2880 const TopoDS_Shape aResult = theSweep.Shape();
2882 TopExp::MapShapes(aResult, anIndices);
2884 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2889 StoreGroups(theCI, aGroupIds);
2894 //=======================================================================
2895 //function : DoGroups2
2896 //purpose : auxilary for CreateGroups()
2897 //=======================================================================
2898 static bool DoGroups2(const TopoDS_Shape &theProfile,
2899 const TopoDS_Shape &thePath,
2900 BRepOffsetAPI_MakePipe &theSweep,
2901 TopTools_SequenceOfShape *theGroups)
2903 Standard_Boolean isDoSides = Standard_False;
2905 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2906 // Up and Down groups creation failure
2911 // Create Side1 and Side2 groups.
2912 const TopAbs_ShapeEnum aType = theProfile.ShapeType();
2913 TopoDS_Vertex aV[2];
2916 if (aType == TopAbs_EDGE) {
2917 TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
2918 } else { // aType == TopAbs_WIRE
2919 TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
2922 for (i = 0; i < 2; ++i) {
2923 if (aV[i].IsNull() == Standard_False) {
2924 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2925 TopTools_MapOfShape aMapFence;
2926 const Standard_Integer anIdSide =
2927 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2929 for (; anExpP.More(); anExpP.Next()) {
2930 const TopoDS_Shape aSideShape =
2931 theSweep.Generated(anExpP.Current(), aV[i]);
2933 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2934 if (aMapFence.Add(aSideShape)) {
2935 theGroups[anIdSide].Append(aSideShape);
2938 // Only edges can be is Side1 and Side2 groups.
2945 // Create Other group. Get boundary edges of the profile.
2946 TopTools_MapOfShape aMapBndEdges;
2947 TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
2949 for (; anExp.More(); anExp.Next()) {
2950 const TopoDS_Shape &anEdge = anExp.Current();
2952 if (!aMapBndEdges.Add(anEdge)) {
2953 aMapBndEdges.Remove(anEdge);
2957 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2958 TopTools_MapOfShape aMapFence;
2960 for (; anExpP.More(); anExpP.Next()) {
2961 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2963 for (; anIter.More(); anIter.Next()) {
2964 const TopoDS_Shape anOtherShape =
2965 theSweep.Generated(anExpP.Current(), anIter.Key());
2967 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2968 if (aMapFence.Add(anOtherShape)) {
2969 theGroups[GROUP_OTHER].Append(anOtherShape);
2972 // Only faces can be in Other group.
2982 //=======================================================================
2983 //function : CreateGroups
2984 //purpose : auxilary for Execute()
2985 //=======================================================================
2986 static bool CreateGroups2(const TopoDS_Shape &theProfile,
2987 const TopoDS_Shape &thePath,
2988 BRepOffsetAPI_MakePipe &theSweep,
2989 GEOMImpl_IPipe *theCI)
2991 if (!theCI->GetGenerateGroups()) {
2997 TopTools_SequenceOfShape aGroups[5];
2999 if (!DoGroups2(theProfile, thePath, theSweep, aGroups)) {
3004 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
3005 TopTools_IndexedMapOfShape anIndices;
3006 const TopoDS_Shape aResult = theSweep.Shape();
3008 TopExp::MapShapes(aResult, anIndices);
3010 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
3015 StoreGroups(theCI, aGroupIds);
3020 //=======================================================================
3021 //function : Execute
3023 //=======================================================================
3024 Standard_Integer GEOMImpl_PipeDriver::Execute(LOGBOOK& log) const
3026 if (Label().IsNull()) return 0;
3027 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
3028 Standard_Integer aType = aFunction->GetType();
3030 GEOMImpl_IPipe* aCI = 0;
3031 if (aType == PIPE_BASE_PATH)
3032 aCI = new GEOMImpl_IPipe (aFunction);
3033 else if (aType == PIPE_DIFFERENT_SECTIONS)
3034 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
3035 else if (aType == PIPE_SHELL_SECTIONS)
3036 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3037 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
3038 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3039 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
3040 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
3044 TopoDS_Wire aWirePath;
3045 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
3046 // working with path
3047 Handle(GEOM_Function) aRefPath = aCI->GetPath();
3048 TopoDS_Shape aShapePath = aRefPath->GetValue();
3050 if (aShapePath.IsNull()) {
3051 MESSAGE ("Driver : path is null");
3052 if (aCI) delete aCI;
3053 Standard_NullObject::Raise("MakePipe aborted : null path argument");
3058 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
3059 TopTools_SequenceOfShape anEdges;
3060 TopExp_Explorer anExp;
3064 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
3065 B.Add(W, anExp.Current());
3071 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
3072 aWirePath = TopoDS::Wire(aShapePath);
3076 if (aShapePath.ShapeType() == TopAbs_EDGE) {
3077 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
3078 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
3083 if (aCI) delete aCI;
3084 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
3087 // Check if it is possible to create groups.
3088 if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
3093 Standard_ConstructionError::Raise
3094 ("Can't create groups if the path is closed");
3098 TopoDS_Shape aShape;
3099 const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
3101 if (aType == PIPE_BASE_PATH) {
3102 Handle(GEOM_Function) aRefBase = aCI->GetBase();
3103 TopoDS_Shape aShapeBase;
3105 // Make copy to prevent modifying of base object 0020766 : EDF 1320
3106 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
3108 aShapeBase = Copy.Shape();
3110 if (aShapeBase.IsNull()) {
3111 if (aCI) delete aCI;
3112 Standard_NullObject::Raise("MakePipe aborted : null base argument");
3116 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
3117 aShapeBase.ShapeType() == TopAbs_WIRE)
3119 TopoDS_Wire aProfile;
3120 if (aShapeBase.ShapeType() == TopAbs_WIRE)
3121 aProfile = TopoDS::Wire(aShapeBase);
3125 BB.MakeWire(aProfile);
3126 BB.Add(aProfile, aShapeBase);
3129 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
3130 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
3131 if (FaceBuilder.IsDone())
3132 Sweep.SetMode(FaceBuilder.Face());
3133 Sweep.Add(aProfile);
3135 Standard_Boolean isDone = BuildPipeShell(Sweep);
3139 if (aCI) delete aCI;
3140 Standard_ConstructionError::Raise("MakePipeShell failed");
3143 aShape = Sweep.Shape(); //result is good
3145 if (!CreateGroups1(aProfile, Sweep, aCI)) {
3146 if (aCI) delete aCI;
3147 Standard_ConstructionError::Raise("Generate groups failure");
3152 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
3153 BRepOffsetAPI_MakePipe aMkPipe
3154 (aWirePath, aShapeBase, theBestMode, Standard_True);
3156 if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) {
3157 aShape = aMkPipe.Shape();
3159 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipe, aCI)) {
3160 if (aCI) delete aCI;
3161 Standard_ConstructionError::Raise("Generate groups failure");
3163 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
3164 // Try to use Descrete Trihedron mode.
3165 BRepOffsetAPI_MakePipe aMkPipeDescrete
3166 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron, Standard_True);
3168 if (aMkPipeDescrete.IsDone()) {
3169 aShape = aMkPipeDescrete.Shape();
3171 if (!CreateGroups2(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
3172 if (aCI) delete aCI;
3173 Standard_ConstructionError::Raise("Generate groups failure");
3180 //building pipe with different sections
3181 else if (aType == PIPE_DIFFERENT_SECTIONS) {
3182 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
3183 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
3184 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
3185 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
3186 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
3187 Standard_Boolean isBySteps = aCIDS->GetIsBySteps();
3194 Standard_Integer nbBases = aBasesObjs->Length();
3195 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
3197 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
3198 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
3201 for (i = 1; i <= nbBases; i++) {
3202 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
3203 if (anItem.IsNull())
3205 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
3206 if (aRefBase.IsNull())
3208 if (aRefBase->GetValue().IsNull())
3211 aHSeqBases->Append(aRefBase->GetValue());
3213 for (i = 1; i <= nbLocs; i++) {
3214 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
3215 if (anItemLoc.IsNull())
3217 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
3218 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
3219 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
3222 aHSeqLocs->Append(aShapeLoc);
3226 Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
3227 Handle(TColStd_HArray1OfInteger) aGroups[5];
3229 if (isGenerateGroups) {
3233 aShape = CreatePipeWithDifferentSections
3234 (aWirePath, aHSeqBases, aHSeqLocs,
3235 aWithContact, aWithCorrect, isBySteps, pGroups);
3237 if (isGenerateGroups) {
3238 // Store created groups.
3239 GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
3241 StoreGroups(&aPipeDS, aGroups);
3245 //building pipe with shell sections
3246 else if (aType == PIPE_SHELL_SECTIONS) {
3247 aShape = CreatePipeForShellSections(aWirePath,aCI);
3250 //building pipe shell sections without path
3251 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
3252 aShape = CreatePipeShellsWithoutPath(aCI);
3255 //building a pipe with constant bi-normal along given vector
3256 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
3257 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
3265 if (aShape.IsNull()) return 0;
3267 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
3268 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
3270 if (aType != PIPE_BASE_PATH &&
3271 aType != PIPE_SHELLS_WITHOUT_PATH) {
3272 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
3273 if (anExpV.More()) {
3274 Standard_Real aVertMaxTol = -RealLast();
3275 for (; anExpV.More(); anExpV.Next()) {
3276 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
3277 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
3278 if (aTol > aVertMaxTol)
3281 aVertMaxTol += Precision::Confusion();
3283 TopTools_DataMapOfShapeListOfShape aMapModif;
3284 TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
3286 if (isGenerateGroups) {
3287 pMapModif = &aMapModif;
3290 TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
3291 (aShape, aVertMaxTol, Standard_True, pMapModif);
3293 if (isGenerateGroups && !aMapModif.IsEmpty()) {
3295 GEOMImpl_IPipe aCI(aFunction);
3296 Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
3297 { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
3298 aCI.GetGroupSide2(), aCI.GetGroupOther() };
3299 TopTools_IndexedMapOfShape anIndices;
3300 TopTools_IndexedMapOfShape aNewIndices;
3301 TopTools_SequenceOfShape aNewShapes[5];
3302 TopTools_MapOfShape aMapReplaced;
3303 TopTools_MapOfShape aMapGlued;
3304 Standard_Integer iGrp;
3307 TopExp::MapShapes(aShape, anIndices);
3308 TopExp::MapShapes(aNewShape, aNewIndices);
3310 for (iGrp = 0; iGrp < 5; ++iGrp) {
3311 if (aGroupIDs[iGrp].IsNull() == Standard_False) {
3312 const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
3313 const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
3315 for (i = aLower; i <= anUpper; ++i) {
3316 const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
3317 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
3319 if (aMapModif.IsBound(aSubShape)) {
3320 const TopTools_ListOfShape &aListModif =
3321 aMapModif.Find(aSubShape);
3322 TopTools_ListIteratorOfListOfShape anIter(aListModif);
3324 for (; anIter.More(); anIter.Next()) {
3325 const TopoDS_Shape &aNewShape = anIter.Value();
3327 if (aMapReplaced.Add(aNewShape)) {
3328 aNewShapes[iGrp].Append(aNewShape);
3330 // This is a glued shape. It means that it is internal
3331 // one and should be removed from groups later.
3332 aMapGlued.Add(aNewShape);
3336 // Shape is not modified.
3337 aNewShapes[iGrp].Append(aSubShape);
3343 if (!aMapGlued.IsEmpty()) {
3344 // Remove glued (internal) shapes from groups.
3345 for (iGrp = 0; iGrp < 5; ++iGrp) {
3346 Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
3348 for (i = 1; i < aNbShapes; ++i) {
3349 const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
3351 if (aMapGlued.Contains(aNewShape)) {
3352 aNewShapes[iGrp].Remove(i);
3360 // Store modified groups.
3361 Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
3363 if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
3364 Standard_ConstructionError::Raise("Generate groups failure");
3367 StoreGroups(&aCI, aNewGroupIDs);
3374 // Note: group indices should not be changed after the next call.
3375 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
3376 aFunction->SetValue(aRes);
3378 #if OCC_VERSION_MAJOR < 7
3379 log.SetTouched(Label());
3381 log->SetTouched(Label());
3386 //================================================================================
3388 * \brief Returns a name of creation operation and names and values of creation parameters
3390 //================================================================================
3392 bool GEOMImpl_PipeDriver::
3393 GetCreationInformation(std::string& theOperationName,
3394 std::vector<GEOM_Param>& theParams)
3396 if (Label().IsNull()) return 0;
3397 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
3398 Standard_Integer aType = function->GetType();
3401 case PIPE_BASE_PATH:
3403 theOperationName = "PIPE";
3404 GEOMImpl_IPipe aCI( function );
3405 AddParam( theParams, "Base Object", aCI.GetBase() );
3406 AddParam( theParams, "Path Object", aCI.GetPath() );
3409 case PIPE_BI_NORMAL_ALONG_VECTOR:
3411 theOperationName = "PIPE";
3412 GEOMImpl_IPipeBiNormal aCI( function );
3413 AddParam( theParams, "Base Object", aCI.GetBase() );
3414 AddParam( theParams, "Path Object", aCI.GetPath() );
3415 AddParam( theParams, "BiNormal", aCI.GetVector() );
3418 case PIPE_DIFFERENT_SECTIONS:
3420 theOperationName = "PIPE";
3421 GEOMImpl_IPipeDiffSect aCI( function );
3422 AddParam( theParams, "Bases", aCI.GetBases() );
3423 AddParam( theParams, "Locations", aCI.GetLocations() );
3424 AddParam( theParams, "Path", aCI.GetPath() );
3426 if (!aCI.GetIsBySteps()) {
3427 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3428 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3431 AddParam( theParams, "Step by step", aCI.GetIsBySteps() );
3434 case PIPE_SHELL_SECTIONS:
3436 theOperationName = "PIPE";
3437 GEOMImpl_IPipeShellSect aCI( function );
3438 AddParam( theParams, "Bases", aCI.GetBases() );
3439 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
3440 AddParam( theParams, "Locations", aCI.GetLocations() );
3441 AddParam( theParams, "Path", aCI.GetPath() );
3442 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3443 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3446 case PIPE_SHELLS_WITHOUT_PATH:
3448 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
3449 GEOMImpl_IPipeShellSect aCI( function );
3450 AddParam( theParams, "Bases", aCI.GetBases() );
3451 AddParam( theParams, "Locations", aCI.GetLocations() );
3461 OCCT_IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);