1 // Copyright (C) 2007-2015 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 static bool DoGroups(BRepOffsetAPI_MakePipeShell &theSweep,
121 TopTools_SequenceOfShape *theGroups);
123 static bool CreateGroups(BRepOffsetAPI_MakePipeShell &theSweep,
124 GEOMImpl_IPipe *theCI);
126 //=======================================================================
129 //=======================================================================
130 const Standard_GUID& GEOMImpl_PipeDriver::GetID()
132 static Standard_GUID aPipeDriver ("FF1BBB19-5D14-4df2-980B-3A668264EA16");
136 //=======================================================================
137 //function : GEOMImpl_PipeDriver
139 //=======================================================================
140 GEOMImpl_PipeDriver::GEOMImpl_PipeDriver()
144 //=======================================================================
145 //function : EvaluateBestSweepMode
146 //purpose : auxilary for right call of MakePipe and MakePipeShell
147 //=======================================================================
148 static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
150 GeomFill_Trihedron theMode = GeomFill_IsFrenet;
152 TopExp_Explorer Explo(Spine, TopAbs_EDGE);
153 for (; Explo.More(); Explo.Next())
155 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
156 Standard_Real fpar, lpar;
157 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
158 GeomAdaptor_Curve GAcurve(aCurve, fpar, lpar);
159 Handle(GeomAdaptor_HCurve) GAHcurve = new GeomAdaptor_HCurve(GAcurve);
161 Handle(GeomFill_CorrectedFrenet) aCorrFrenet = new GeomFill_CorrectedFrenet(Standard_True); //for evaluation
162 aCorrFrenet->SetCurve(GAHcurve);
163 GeomFill_Trihedron aMode = aCorrFrenet->EvaluateBestMode();
164 if (aMode == GeomFill_IsDiscreteTrihedron)
169 if (aMode == GeomFill_IsCorrectedFrenet)
176 //=======================================================================
177 //function : BuildPipeShell
178 //purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
179 // mode. Returns Standard_True if the building is done successfully.
180 //=======================================================================
181 static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
185 Standard_Boolean isDone = theBuilder.IsDone();
188 theBuilder.ErrorOnSurface() > TolPipeSurf) {
189 // Try to use Descrete Trihedron mode.
190 theBuilder.SetDiscreteMode();
192 isDone = theBuilder.IsDone();
198 //=======================================================================
199 //function : FillForOtherEdges
200 //purpose : auxilary for CreatePipeForShellSections()
201 //=======================================================================
202 static bool FillForOtherEdges(const TopoDS_Shape& F1,
203 const TopoDS_Shape& E1,
204 const TopoDS_Shape& V1,
205 TopTools_IndexedDataMapOfShapeShape& FF)
207 //cout<<"FillForOtherEdges"<<endl;
208 // find other pairs for vertexes and edges
209 // creating map of vertex edges for both faces
210 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
211 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
212 if (!FF.Contains(F1))
213 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
214 if (!FF.Contains(E1))
215 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
216 if (!FF.Contains(V1))
217 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
218 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
219 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
220 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
221 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
222 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
224 TopoDS_Edge ES1 = TopoDS::Edge(E1);
225 TopoDS_Edge ES2 = TopoDS::Edge(E2);
226 TopoDS_Shape VS1 = V1;
227 TopoDS_Shape VS2 = V2;
229 ShapeAnalysis_Edge sae;
231 if (!aMapVertEdge1.Contains(VS1))
232 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
233 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
234 //TopoDS_Shape E1next;
235 TopTools_ListIteratorOfListOfShape anIter1(aList1);
236 if (anIter1.Value().IsSame(ES1)) {
239 //E1next = anIter1.Value();
240 if (!aMapVertEdge2.Contains(VS2))
241 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
242 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
243 //TopoDS_Shape E2next;
244 TopTools_ListIteratorOfListOfShape anIter2(aList2);
245 if (anIter2.Value().IsSame(ES2)) {
248 //E2next = anIter2.Value();
249 //ES1 = TopoDS::Edge(E1next);
250 //ES2 = TopoDS::Edge(E2next);
251 ES1 = TopoDS::Edge(anIter1.Value());
252 ES2 = TopoDS::Edge(anIter2.Value());
253 if (!FF.Contains(ES1)) {
256 if (VS1.IsSame(sae.FirstVertex(ES1)))
257 VS1 = sae.LastVertex(ES1);
259 VS1 = sae.FirstVertex(ES1);
260 if (VS2.IsSame(sae.FirstVertex(ES2)))
261 VS2 = sae.LastVertex(ES2);
263 VS2 = sae.FirstVertex(ES2);
266 if (!FF.Contains(VS1)) {
274 //=======================================================================
275 //function : FillCorrespondingEdges
276 //purpose : auxilary for CreatePipeForShellSections()
277 //=======================================================================
278 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
279 const TopoDS_Shape& FS2,
280 const TopoDS_Vertex& aLoc1,
281 const TopoDS_Vertex& aLoc2,
282 const TopoDS_Wire& aWirePath,
283 TopTools_IndexedDataMapOfShapeShape& FF)
285 //cout<<"FillCorrespondingEdges"<<endl;
286 // find corresponding edges
287 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
288 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
289 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
290 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
291 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
292 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
293 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
294 if (theBestMode == GeomFill_IsDiscreteTrihedron)
295 aBuilder.SetDiscreteMode();
296 aBuilder.Add(aWire1, aLoc1);
297 aBuilder.Add(aWire2, aLoc2);
298 if (!aBuilder.IsReady()) {
302 BuildPipeShell(aBuilder);
304 TopoDS_Shape aShape = aBuilder.Shape();
305 ShapeAnalysis_Edge sae;
306 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
307 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
308 TopTools_MapOfShape Vs1,Vs2;
310 exp.Init(FS1, TopAbs_EDGE);
311 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
312 TopoDS_Vertex V11 = sae.FirstVertex(E1);
313 TopoDS_Vertex V21 = sae.LastVertex(E1);
314 gp_Pnt P11 = BRep_Tool::Pnt(V11);
315 gp_Pnt P21 = BRep_Tool::Pnt(V21);
316 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
317 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
318 // find corresponding vertexes from created shape
319 TopoDS_Vertex VN11,VN21;
320 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
321 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
322 gp_Pnt P = BRep_Tool::Pnt(V);
323 if (P.Distance(P11)<tol) {
326 if (P.Distance(P21)<tol) {
330 // find edge contains VN11 and VN21 and corresponding vertexes
331 TopoDS_Vertex VN12,VN22;
332 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
333 TopoDS_Shape F = exp.Current();
334 TopExp_Explorer expe;
336 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
337 TopoDS_Edge E = TopoDS::Edge(expe.Current());
338 TopoDS_Vertex VF = sae.FirstVertex(E);
339 TopoDS_Vertex VL = sae.LastVertex(E);
340 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
346 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
347 TopoDS_Edge E = TopoDS::Edge(expe.Current());
348 TopoDS_Vertex VF = sae.FirstVertex(E);
349 TopoDS_Vertex VL = sae.LastVertex(E);
350 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
352 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
354 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
356 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
362 // find vertexes from FS2 corresponded to VN12 and VN22
363 // and find edge from FS2 contains V12 and V22,
364 // this edge will be corresponded to edge E1
365 TopoDS_Vertex V12,V22;
366 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
367 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
368 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
369 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
371 TopExp_Explorer expe;
372 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
373 TopoDS_Edge E = TopoDS::Edge(expe.Current());
374 TopoDS_Vertex VF = sae.FirstVertex(E);
375 TopoDS_Vertex VL = sae.LastVertex(E);
376 gp_Pnt PF = BRep_Tool::Pnt(VF);
377 gp_Pnt PL = BRep_Tool::Pnt(VL);
378 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
384 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
395 // find other pairs for vertexes and edges
396 // creating map of vertex edges for both faces
397 return FillForOtherEdges(FS1,E1,V21,FF);
402 //=======================================================================
403 //function : FillCorrespondingEdges
404 //purpose : auxilary for CreatePipeShellsWithoutPath()
405 //=======================================================================
406 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
407 const TopoDS_Shape& FS2,
408 const TopoDS_Vertex& aLoc1,
409 const TopoDS_Vertex& aLoc2,
410 TopTools_IndexedDataMapOfShapeShape& FF)
412 //cout<<"FillCorrespondingEdges"<<endl;
414 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
415 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
418 ShapeAnalysis_Edge sae;
419 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
420 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
421 TopTools_MapOfShape Vs1,Vs2;
423 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
426 TopExp_Explorer exp1;
427 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
428 E1 = TopoDS::Edge(exp1.Current());
429 TopoDS_Vertex V1 = sae.FirstVertex(E1);
430 TopoDS_Vertex V2 = sae.LastVertex(E1);
431 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
432 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
433 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
434 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
435 if (P1.Distance(Ptmp1)<tol) {
439 if (P1.Distance(Ptmp2)<tol) {
446 TopoDS_Vertex VE21,VE22;
448 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
449 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
450 TopoDS_Vertex V1 = sae.FirstVertex(E);
451 TopoDS_Vertex V2 = sae.LastVertex(E);
452 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
453 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
454 if (P2.Distance(Ptmp1)<tol) {
466 if (P2.Distance(Ptmp2)<tol) {
480 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
481 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
482 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
483 gp_Vec aDir1(PV21,PE21);
484 gp_Vec aDir2(PV21,PE22);
485 double ang1 = aDir.Angle(aDir1);
486 double ang2 = aDir.Angle(aDir2);
487 if (fabs(ang1)<fabs(ang2)) {
500 // find other pairs for vertexes and edges
501 return FillForOtherEdges(FS1,E1,V21,FF);
504 //=======================================================================
505 //function : FindNextPairOfFaces
506 //purpose : auxilary for CreatePipeForShellSections()
507 //=======================================================================
508 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
509 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
510 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
511 TopTools_IndexedDataMapOfShapeShape& FF,
514 //cout<<"FindNextPairOfFaces"<<endl;
515 TopExp_Explorer anExp;
516 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
517 TopoDS_Shape E1 = anExp.Current();
518 if (!FF.Contains(E1)) {
520 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
522 if (!FF.Contains(E1))
523 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
524 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
525 TopExp_Explorer anExpV;
526 anExpV.Init(E1, TopAbs_VERTEX);
527 TopoDS_Shape V1 = anExpV.Current();
528 if (!FF.Contains(V1)) {
530 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
533 if (!aMapEdgeFaces1.Contains(E1))
534 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
535 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
536 if (aList1.Extent()<2)
538 TopTools_ListIteratorOfListOfShape anIter(aList1);
539 if (anIter.Value().IsEqual(aCurFace)) {
542 TopoDS_Shape F1other = anIter.Value();
543 if (FF.Contains(F1other))
546 if (!FF.Contains(aCurFace))
547 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
548 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
549 if (!aMapEdgeFaces2.Contains(E2))
550 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
551 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
552 if (aList2.Extent()<2) {
554 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
556 TopTools_ListIteratorOfListOfShape anIter2(aList2);
557 if (anIter2.Value().IsEqual(F2)) {
560 TopoDS_Shape F2other = anIter2.Value();
561 FF.Add(F1other,F2other);
563 // add pairs of edges to FF
564 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
567 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
570 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
574 //=======================================================================
575 //function : FindFirstPairFaces
576 //purpose : auxilary for Execute()
577 //=======================================================================
578 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
579 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
580 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
582 //cout<<"FindFirstPairFaces"<<endl;
584 // check if vertexes are sub-shapes of sections
585 gp_Pnt P1 = BRep_Tool::Pnt(V1);
586 gp_Pnt P2 = BRep_Tool::Pnt(V2);
587 TopoDS_Vertex V1new,V2new;
589 double mindist = 1.e10;
590 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
591 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
592 gp_Pnt P = BRep_Tool::Pnt(V);
593 double dist = P1.Distance(P);
600 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
601 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
602 gp_Pnt P = BRep_Tool::Pnt(V);
603 double dist = P2.Distance(P);
610 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
611 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
612 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
613 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
614 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
615 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
617 // replace vertexes if it is needed
618 if (!V1.IsSame(V1new)) {
620 P1 = BRep_Tool::Pnt(V1);
621 MESSAGE (" replace V1");
624 MESSAGE (" not replace V1");
625 if (!V2.IsSame(V2new)) {
627 P2 = BRep_Tool::Pnt(V2);
628 MESSAGE (" replace V2");
631 MESSAGE (" not replace V2");
633 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
634 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
635 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
636 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
638 if (!aMapVertFaces1.Contains(V1))
639 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
640 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
641 TopTools_ListIteratorOfListOfShape anIter1(aList1);
642 FS1 = anIter1.Value();
644 double x1=0., y1=0., z1=0.;
646 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
647 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
648 gp_Pnt P = BRep_Tool::Pnt(V);
654 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
656 TColgp_SequenceOfPnt Ps;
657 TopTools_SequenceOfShape Fs;
658 if (!aMapVertFaces2.Contains(V2))
659 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
660 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
661 TopTools_ListIteratorOfListOfShape anIter2(aList2);
662 for (; anIter2.More(); anIter2.Next()) {
663 TopoDS_Shape F = anIter2.Value();
664 double x2=0., y2=0., z2=0.;
666 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
667 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
668 gp_Pnt P = BRep_Tool::Pnt(V);
674 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
681 double MinAng = M_PI;
683 for (; i<=Fs.Length(); i++) {
684 gp_Vec tmpDir(PM1,Ps(i));
685 double ang = fabs(aDir.Angle(tmpDir));
694 //=======================================================================
695 //function : RemoveFaces
696 //purpose : This function returns theShapeFrom without faces of the shape
697 // theFacesToRm. It returns a shell if theShapeFrom is a solid or
698 // a compound otherwise. Auxilary for CreatePipeWithDifferentSections
700 //=======================================================================
701 static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom,
702 const TopoDS_Shape &theFacesToRm)
704 TopTools_IndexedMapOfShape aMapFaces;
705 TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE);
706 BRep_Builder aBuilder;
707 TopoDS_Shape aResult;
709 if (theShapeFrom.ShapeType() == TopAbs_SOLID) {
711 aBuilder.MakeShell(TopoDS::Shell(aResult));
714 aBuilder.MakeCompound(TopoDS::Compound(aResult));
717 TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces);
719 for (; anExp.More(); anExp.Next()) {
720 const TopoDS_Shape &aFace = anExp.Current();
722 if (!aMapFaces.Contains(aFace)) {
723 aBuilder.Add(aResult, aFace);
730 //=======================================================================
731 //function : CreatePipeWithDifferentSections
733 //=======================================================================
734 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
735 (const TopoDS_Wire &theWirePath,
736 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
737 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
738 const Standard_Boolean theWithContact,
739 const Standard_Boolean theWithCorrect,
740 const Standard_Boolean IsBySteps,
741 Handle(TColStd_HArray1OfInteger) *theGroups)
745 TopoDS_Wire aWirePath = theWirePath;
747 Standard_Integer nbBases = theHSeqBases->Length();
748 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
750 if (nbLocs && nbLocs != nbBases) {
751 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
754 TopTools_SequenceOfShape aSeqBases;
755 TopTools_SequenceOfShape aSeqLocs;
756 TopTools_SequenceOfShape aSeqFaces;
757 Standard_Boolean NeedCreateSolid = Standard_False;
759 Standard_Integer i = 1;
760 for (i = 1; i <= nbBases; i++) {
761 if (theHSeqBases->Value(i).IsNull())
764 // Make copy to prevent modifying of base object 0020766 : EDF 1320
765 TopoDS_Shape aShapeBase;
766 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
768 aShapeBase = Copy.Shape();
770 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
772 //if for section was specified face with a few wires then a few
773 // pipes were build and make solid
774 if (aTypeBase == TopAbs_SHELL) {
775 // create wire as boundary contour if shell is no closed
776 // get free boundary shapes
777 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
778 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
779 TopExp_Explorer anExp;
781 Standard_Integer NbWires = 0;
782 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
784 aWire = anExp.Current();
788 Standard_ConstructionError::Raise("Bad shell is used as section ");
790 NeedCreateSolid = Standard_True;
791 aSeqFaces.Append(aShapeBase);
792 aSeqBases.Append(aWire);
794 else if (aTypeBase == TopAbs_FACE) {
795 NeedCreateSolid = Standard_True;
796 //for case one path should be used other type function
797 aSeqFaces.Append(aShapeBase);
798 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
799 for (; aExpW.More(); aExpW.Next()) {
800 TopoDS_Shape aWireProf = aExpW.Current();
801 aSeqBases.Append(aWireProf);
804 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
805 aSeqBases.Append(aShapeBase);
807 else if (aTypeBase == TopAbs_EDGE) {
808 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
809 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
810 aSeqBases.Append(aWireProf);
813 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
814 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
816 aSeqLocs.Append(aShapeLoc);
820 nbLocs = aSeqLocs.Length();
823 TopTools_SequenceOfShape Edges;
825 // we have to check that each location shape is a vertex from
826 // path and update aSeqLocs if it is needed (and possible)
827 TColgp_SequenceOfPnt PLocs;
828 for (i=1; i<=nbLocs; i++) {
829 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
830 PLocs.Append(BRep_Tool::Pnt(V));
832 //TopTools_SequenceOfShape Edges;
833 TopExp_Explorer anExp;
834 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
835 Edges.Append(anExp.Current());
837 int nbEdges = Edges.Length();
838 ShapeAnalysis_Edge sae;
839 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
840 double tol = BRep_Tool::Tolerance(edge);
841 TopoDS_Vertex VF = sae.FirstVertex(edge);
842 gp_Pnt PF = BRep_Tool::Pnt(VF);
843 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
844 if (PF.Distance(PLocs.First()) > tol) {
845 Standard_ConstructionError::Raise
846 ("First location shapes is not coincided with first vertex of aWirePath");
848 aSeqLocs.ChangeValue(1) = VF;
849 edge = TopoDS::Edge(Edges.Last());
850 tol = BRep_Tool::Tolerance(edge);
851 TopoDS_Vertex VL = sae.LastVertex(edge);
852 gp_Pnt PL = BRep_Tool::Pnt(VL);
853 if (PL.Distance(PLocs.Last()) > tol) {
854 Standard_ConstructionError::Raise
855 ("Last location shapes is not coincided with last vertex of aWirePath");
857 aSeqLocs.ChangeValue(nbLocs) = VL;
859 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
860 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
861 tol = BRep_Tool::Tolerance(edge);
862 TopoDS_Vertex V1 = sae.FirstVertex(E);
863 TopoDS_Vertex V2 = sae.LastVertex(E);
864 gp_Pnt P1 = BRep_Tool::Pnt(V1);
865 gp_Pnt P2 = BRep_Tool::Pnt(V2);
866 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
867 aSeqLocs.ChangeValue(jcurr) = V2;
871 // find distance between E and aLocs(jcurr)
873 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
874 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
875 if (PPCurve.NbPoints()>0 &&
876 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
877 double param = PPCurve.Parameter(1);
880 // split current edge
881 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
882 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
887 if (Pfp.Distance(P1)<tol) {
888 B.MakeEdge(E1,tc1,tol);
890 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
891 B.Add(E1,TopoDS::Vertex(tmpV));
892 B.MakeEdge(E2,tc2,tol);
893 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
894 B.Add(E2,TopoDS::Vertex(tmpV));
898 B.MakeEdge(E1,tc2,tol);
899 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
900 B.Add(E1,TopoDS::Vertex(tmpV));
903 B.MakeEdge(E2,tc1,tol);
905 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
906 B.Add(E2,TopoDS::Vertex(tmpV));
911 Edges.InsertAfter(i-1,E1);
912 Edges.InsertAfter(i,E2);
916 if (nbEdges<Edges.Length()) {
917 // one of edges was splitted => we have to update WirePath
921 for (i=1; i<=Edges.Length(); i++) {
922 B.Add(W,TopoDS::Edge(Edges.Value(i)));
928 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
931 // Fill SplitEdgeNums and SplitLocNums with intermediate location indices
932 // and corresponding edge indices.
933 Standard_Integer i = 1;
938 for (j = 2; j < aSeqLocs.Length(); j++) {
939 SplitLocNums.Append(j);
940 aVert = TopoDS::Vertex(aSeqLocs.Value(j));
941 aP = BRep_Tool::Pnt(aVert);
943 while (i < Edges.Length()) {
946 TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i));
947 Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
948 Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp);
954 if (aP.Distance(aPLast) < aTol) {
955 SplitEdgeNums.Append(i - 1);
961 // check curvature of wire for condition that
962 // max summary angle between directions along
963 // wire path must be < 4*PI. If not - split wire
964 // and seguences of shapes, perform pipe for each
965 // and make sewing after that
970 if ( Edges.Length() > 0 ) {
971 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
974 SumAng = fabs(Vec1.Angle(Vec2));
979 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
980 for (i=2; i<=Edges.Length(); i++) {
981 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
982 double tol = BRep_Tool::Tolerance(edge);
983 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
985 double ang = fabs(Vec1.Angle(Vec2));
989 SplitEdgeNums.Append(i-1);
991 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
992 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
993 gp_Pnt P = BRep_Tool::Pnt(aVert);
994 if (P1.Distance(P) < tol) {
995 SplitLocNums.Append(j);
1006 bool isCreateGroups = (theGroups != NULL);
1008 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
1009 TopTools_SequenceOfShape aSeqRes;
1010 TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
1011 Standard_Integer iGrp;
1012 int nn, num1 = 1, num2 = 1;
1013 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
1014 // create wirepath and sequences of shapes
1018 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
1019 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1021 num1 = SplitEdgeNums.Value(nn) + 1;
1022 TopTools_SequenceOfShape aTmpSeqBases;
1023 TopTools_SequenceOfShape aTmpSeqLocs;
1024 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
1025 aTmpSeqBases.Append(aSeqBases.Value(i));
1026 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1028 num2 = SplitLocNums.Value(nn);
1030 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1031 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1032 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1033 aBuilder.SetDiscreteMode();
1034 Standard_Integer nbShapes = aTmpSeqBases.Length();
1035 for (i=1; i<=nbShapes; i++) {
1036 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1037 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1038 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1040 if (!aBuilder.IsReady()) {
1041 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1044 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1046 if (isDone && NeedCreateSolid && nn == 1) {
1047 // Make solid for the first step.
1048 isDone = aBuilder.MakeSolid();
1052 Standard_ConstructionError::Raise("Pipe construction failure");
1055 TopoDS_Shape resShape = aBuilder.Shape();
1057 if (NeedCreateSolid && nn == 1) {
1058 // Remove top lid from the result.
1059 resShape = RemoveFaces(resShape, aBuilder.LastShape());
1062 aSeqRes.Append(resShape);
1065 if (isCreateGroups) {
1067 TopTools_SequenceOfShape aGroups[5];
1069 if (!DoGroups(aBuilder, aGroups)) {
1070 Standard_ConstructionError::Raise("Generate groups failure");
1073 // Get shapes from all groups.
1074 for (iGrp = 0; iGrp < 5; ++iGrp) {
1075 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1079 // create wirepath and sequences of shapes for last part
1083 for (i=num1; i<=Edges.Length(); i++) {
1084 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1086 TopTools_SequenceOfShape aTmpSeqBases;
1087 TopTools_SequenceOfShape aTmpSeqLocs;
1088 for (i=num2; i<=aSeqLocs.Length(); i++) {
1089 aTmpSeqBases.Append(aSeqBases.Value(i));
1090 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1092 // make pipe for last part
1093 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1094 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1095 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1096 aBuilder.SetDiscreteMode();
1097 Standard_Integer nbShapes = aTmpSeqBases.Length();
1098 for (i=1; i<=nbShapes; i++) {
1099 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1100 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1101 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1103 if (!aBuilder.IsReady()) {
1104 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1107 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1109 if (isDone && NeedCreateSolid) {
1110 isDone = aBuilder.MakeSolid();
1114 Standard_ConstructionError::Raise("Pipe construction failure");
1117 TopoDS_Shape resShape = aBuilder.Shape();
1119 if (NeedCreateSolid) {
1120 // Remove bottom lid from the result.
1121 resShape = RemoveFaces(resShape, aBuilder.FirstShape());
1124 aSeqRes.Append(resShape);
1127 if (isCreateGroups) {
1129 TopTools_SequenceOfShape aGroups[5];
1131 if (!DoGroups(aBuilder, aGroups)) {
1132 Standard_ConstructionError::Raise("Generate groups failure");
1135 // Get shapes from all groups.
1136 for (iGrp = 0; iGrp < 5; ++iGrp) {
1137 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1141 // make sewing for result
1142 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1143 aSewing->SetTolerance(Precision::Confusion());
1144 aSewing->SetFaceMode(Standard_True);
1145 aSewing->SetFloatingEdgesMode(Standard_False);
1146 aSewing->SetNonManifoldMode(Standard_False);
1147 for (i=1; i<=aSeqRes.Length(); i++) {
1148 aSewing->Add(aSeqRes.Value(i));
1151 aShape = aSewing->SewedShape();
1153 if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) {
1155 BRepBuilderAPI_MakeSolid aMkSolid;
1157 aMkSolid.Add(TopoDS::Shell(aShape));
1159 if (!aMkSolid.IsDone()) {
1160 Standard_ConstructionError::Raise("Can't create solid pipe");
1163 TopoDS_Solid aSolid = aMkSolid.Solid();
1164 BRepClass3d_SolidClassifier aSC(aSolid);
1166 aSC.PerformInfinitePoint(Precision::Confusion());
1168 if (aSC.State() == TopAbs_IN) {
1169 aShape = aSolid.Reversed();
1175 if (isCreateGroups) {
1176 // Replase Group shapes by modified ones.
1177 TopTools_SequenceOfShape aSeqGroups[5];
1180 for (iGrp = 0; iGrp < 5; ++iGrp) {
1182 for (i = 1; i <= aSeqRes.Length(); ++i) {
1183 if (iGrp == GROUP_DOWN && i > 1) {
1184 // For DOWN group we use only the first pipe.
1188 if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
1189 // For UP group we use only the last pipe.
1193 const TopTools_SequenceOfShape &aShapes =
1194 aMapResGroups[iGrp].Find(aSeqRes.Value(i));
1197 // For each sub-shape of pipe
1198 for (j = 1; j <= aShapes.Length(); ++j) {
1199 const TopoDS_Shape &aGrpShape = aShapes.Value(j);
1201 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1202 // Use the shape modified by sewing.
1203 const TopoDS_Shape &aModifGrpShape =
1204 aSewing->ModifiedSubShape(aGrpShape);
1206 aSeqGroups[iGrp].Append(aModifGrpShape);
1208 // Use the shape as it is.
1209 aSeqGroups[iGrp].Append(aGrpShape);
1216 TopTools_IndexedMapOfShape anIndices;
1218 TopExp::MapShapes(aShape, anIndices);
1220 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1221 Standard_ConstructionError::Raise("Generate groups failure");
1226 // old implementation without splitting
1227 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1228 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1229 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1230 aBuilder.SetDiscreteMode();
1232 Standard_Integer nbShapes = aSeqBases.Length();
1233 Standard_Integer step = nbShapes/nbBases;
1235 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1236 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1238 Standard_Integer ind =0;
1239 Standard_Real aTolConf = Precision::Confusion();
1240 Standard_Real aTolAng = Precision::Angular();
1242 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1243 TopTools_SequenceOfShape usedBases;
1244 Standard_Integer j = 1;
1245 for (; j <= nbBases; j++) {
1246 ind = i + (j-1)*step;
1247 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1248 usedBases.Append(aWireProf);
1250 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1251 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1252 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1255 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1257 if (!aBuilder.IsReady()) {
1258 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1261 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1263 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1265 if (isDone && NeedCreateSolid) {
1266 isDone = aBuilder.MakeSolid();
1270 Standard_ConstructionError::Raise("Pipe construction failure");
1272 aShape = aBuilder.Shape();
1274 if (isCreateGroups) {
1276 TopTools_SequenceOfShape aSeqGroups[5];
1278 if (!DoGroups(aBuilder, aSeqGroups)) {
1279 Standard_ConstructionError::Raise("Generate groups failure");
1283 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1284 TopTools_IndexedMapOfShape anIndices;
1285 const TopoDS_Shape aResult = aBuilder.Shape();
1287 TopExp::MapShapes(aResult, anIndices);
1289 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1290 Standard_ConstructionError::Raise("Generate groups failure");
1293 aSeqFaces.Append(aShape);
1294 for (j = 1; j <=usedBases.Length(); j++)
1295 aBuilder.Delete(usedBases.Value(j));
1302 //=======================================================================
1303 //function : CreatePipeForShellSections
1304 //purpose : auxilary for Execute()
1305 //=======================================================================
1306 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1307 GEOMImpl_IPipe* aCI)
1312 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1313 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1314 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1315 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1316 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1317 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1318 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1320 Standard_Integer nbBases = aBasesObjs->Length(),
1321 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1322 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1324 if (nbLocs != nbBases) {
1325 if (aCI) delete aCI;
1326 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1328 if (nbSubBases && nbSubBases != nbBases) {
1329 if (aCI) delete aCI;
1330 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1333 TopTools_SequenceOfShape VLocs;
1334 for (i=1; i<=nbBases; i++) {
1335 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1336 if (anItemLoc.IsNull())
1338 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1339 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1340 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1342 VLocs.Append(aShapeLoc);
1344 nbLocs = VLocs.Length();
1345 if (nbLocs != nbBases) {
1346 if (aCI) delete aCI;
1347 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1349 // split wire path by location points
1350 TColgp_SequenceOfPnt PLocs;
1351 for (i=1; i<=nbLocs; i++) {
1352 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1353 PLocs.Append(BRep_Tool::Pnt(V));
1356 TopTools_SequenceOfShape Edges;
1357 TopTools_SequenceOfShape Wires;
1358 ShapeAnalysis_Edge sae;
1361 TopExp_Explorer anExp;
1362 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1363 Edges.Append(anExp.Current());
1365 Standard_Integer Num1 = 0;
1366 Standard_Integer Num2 = 0;
1367 for (i=1; i<=Edges.Length(); i++) {
1368 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1369 double tol = BRep_Tool::Tolerance(E);
1370 TopoDS_Vertex V1 = sae.FirstVertex(E);
1371 TopoDS_Vertex V2 = sae.LastVertex(E);
1372 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1373 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1374 if (P1.Distance(PLocs.First()) < tol) {
1377 if (P2.Distance(PLocs.Last()) < tol) {
1381 if (Num1>0 && Num2>0) {
1384 for (i=Num1; i<=Num2; i++) {
1385 B.Add(W,Edges.Value(i));
1390 Wires.Append(aWirePath);
1394 TopExp_Explorer anExp;
1395 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1396 Edges.Append(anExp.Current());
1398 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1399 double tol = BRep_Tool::Tolerance(edge);
1400 TopoDS_Vertex VF = sae.FirstVertex(edge);
1401 gp_Pnt PF = BRep_Tool::Pnt(VF);
1402 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1403 if (PF.Distance(PLocs.First()) > tol) {
1404 if (aCI) delete aCI;
1405 Standard_ConstructionError::Raise
1406 ("First location shapes is not coincided with first vertex of aWirePath");
1408 VLocs.ChangeValue(1) = VF;
1409 edge = TopoDS::Edge(Edges.Last());
1410 tol = BRep_Tool::Tolerance(edge);
1411 TopoDS_Vertex VL = sae.LastVertex(edge);
1412 gp_Pnt PL = BRep_Tool::Pnt(VL);
1413 if (PL.Distance(PLocs.Last()) > tol) {
1414 if (aCI) delete aCI;
1415 Standard_ConstructionError::Raise
1416 ("Last location shapes is not coincided with last vertex of aWirePath");
1418 VLocs.ChangeValue(nbLocs) = VL;
1420 TopTools_SequenceOfShape tmpEdges;
1421 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1422 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1423 tol = BRep_Tool::Tolerance(E);
1424 TopoDS_Vertex V1 = sae.FirstVertex(E);
1425 TopoDS_Vertex V2 = sae.LastVertex(E);
1426 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1427 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1428 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1429 // make wire from current edge and add created
1433 for (j=1; j<=tmpEdges.Length(); j++)
1434 B.Add(W,tmpEdges.Value(j));
1437 VLocs.ChangeValue(jcurr) = V2;
1442 // find distance between E and aLocs(jcurr)
1444 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1445 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1446 if (PPCurve.NbPoints()>0 &&
1447 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1448 double param = PPCurve.Parameter(1);
1451 // split current edge
1452 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1453 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1457 if (Pfp.Distance(P1)<tol) {
1458 B.MakeEdge(E1,tc1,tol);
1460 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1461 B.Add(E1,TopoDS::Vertex(tmpV));
1462 tmpEdges.Append(E1);
1463 B.MakeEdge(E2,tc2,tol);
1464 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1465 B.Add(E2,TopoDS::Vertex(tmpV));
1469 B.MakeEdge(E1,tc2,tol);
1470 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1471 B.Add(E1,TopoDS::Vertex(tmpV));
1474 tmpEdges.Append(E1);
1475 B.MakeEdge(E2,tc1,tol);
1477 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1478 B.Add(E2,TopoDS::Vertex(tmpV));
1481 // create wire from tmpEdges
1484 for (j=1; j<=tmpEdges.Length(); j++)
1485 B.Add(W,tmpEdges.Value(j));
1490 Edges.InsertAfter(i-1,E1);
1491 Edges.InsertAfter(i,E2);
1498 // create wire from other edges
1501 for (; i<=Edges.Length(); i++)
1502 B.Add(W,Edges.Value(i));
1506 if (Wires.Length() != nbLocs-1) {
1507 if (aCI) delete aCI;
1508 Standard_ConstructionError::Raise
1509 ("One of location shapes is not lied on the path");
1512 TopTools_SequenceOfShape aGroups[5];
1513 TopoDS_Compound aComp;
1514 B.MakeCompound(aComp);
1515 for (i = 1; i < nbBases; i++) {
1516 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1518 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1519 if (anItem1.IsNull())
1521 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1522 if (aRefBase1.IsNull())
1524 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1525 if (aShBase1.IsNull())
1527 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1529 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1530 if (anItem2.IsNull())
1532 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1533 if (aRefBase2.IsNull())
1535 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1536 if (aShBase2.IsNull())
1538 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1540 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1541 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1543 if (aCI) delete aCI;
1544 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1547 bool CreateFewSolids = false;
1549 TopExp_Explorer anExp;
1550 Standard_Integer nbf1 = 0;
1551 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1554 Standard_Integer nbf2 = 0;
1555 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1559 CreateFewSolids = true;
1562 if (!CreateFewSolids) {
1563 // we can create only one solid
1564 TopoDS_Shape aWire1, aWire2;
1566 if (aType1==TopAbs_SHELL) {
1567 // create wire as boundary contour if shell is no closed
1568 // get free boundary shapes
1569 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1570 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1571 //TopExp_Explorer anExp;
1572 Standard_Integer NbWires = 0;
1573 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1575 aWire1 = anExp.Current();
1579 if (aCI) delete aCI;
1580 Standard_ConstructionError::Raise("Bad shell is used as section ");
1583 else { // aType1==TopAbs_FACE
1584 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1585 aWire1 = aExpW.Current();
1588 if (aType2==TopAbs_SHELL) {
1589 // create wire as boundary contour if shell is no closed
1590 // get free boundary shapes
1591 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1592 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1593 //TopExp_Explorer anExp;
1594 Standard_Integer NbWires = 0;
1595 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1597 aWire2 = anExp.Current();
1601 if (aCI) delete aCI;
1602 Standard_ConstructionError::Raise("Bad shell is used as section ");
1605 else { // aType2==TopAbs_FACE
1606 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1607 aWire2 = aExpW.Current();
1609 // make pipe using aWire1 and aWire2
1610 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1611 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1612 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1613 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1614 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1615 aBuilder.SetDiscreteMode();
1616 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1617 aWithContact, aWithCorrect);
1618 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1619 aWithContact, aWithCorrect);
1620 if (!aBuilder.IsReady()) {
1621 if (aCI) delete aCI;
1622 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1625 BuildPipeShell(aBuilder);
1627 TopoDS_Shape aShape = aBuilder.Shape();
1628 TopTools_SequenceOfShape aLocalGroups[5];
1631 if (isGenerateGroups) {
1633 if (!DoGroups(aBuilder, aLocalGroups)) {
1634 if (aCI) delete aCI;
1635 Standard_ConstructionError::Raise("Generate groups failure");
1638 // Clear the groups Down and Up.
1639 aLocalGroups[GROUP_DOWN].Clear();
1640 aLocalGroups[GROUP_UP].Clear();
1643 TopoDS_Shell aShell;
1644 B.MakeShell(aShell);
1645 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1646 B.Add(aShell,anExp.Current());
1648 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1649 B.Add(aShell,anExp.Current());
1651 if (isGenerateGroups && i == 1) {
1652 aLocalGroups[GROUP_DOWN].Append(anExp.Current());
1655 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1656 B.Add(aShell,anExp.Current());
1658 if (isGenerateGroups && i == nbBases - 1) {
1659 aLocalGroups[GROUP_UP].Append(anExp.Current());
1662 // make sewing for this shell
1663 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1664 aSewing->SetTolerance(Precision::Confusion());
1665 aSewing->SetFaceMode(Standard_True);
1666 aSewing->SetFloatingEdgesMode(Standard_False);
1667 aSewing->SetNonManifoldMode(Standard_False);
1668 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1669 aSewing->Add(anExp.Current());
1672 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1673 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1674 aShell = TopoDS::Shell(aSewShape);
1675 GProp_GProps aSystem;
1676 BRepGProp::VolumeProperties(aShell, aSystem);
1677 if (aSystem.Mass()<0) {
1680 if (BRep_Tool::IsClosed(aShell)) {
1681 TopoDS_Solid aSolid;
1682 B.MakeSolid(aSolid);
1683 B.Add(aSolid,aShell);
1684 B.Add(aComp,aSolid);
1687 B.Add(aComp,aShell);
1691 B.Add(aComp,aShell);
1694 if (isGenerateGroups) {
1695 Standard_Integer iGrp;
1697 for (iGrp = 0; iGrp < 5; ++iGrp) {
1700 // For each sub-shape of pipe
1701 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1702 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1704 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1705 // Use the shape modified by sewing.
1706 const TopoDS_Shape &aModifGrpShape =
1707 aSewing->ModifiedSubShape(aGrpShape);
1709 aGroups[iGrp].Append(aModifGrpShape);
1711 // Use the shape as it is.
1712 aGroups[iGrp].Append(aGrpShape);
1720 // main block - creation few solids (for each pair of faces)
1721 TopTools_MapOfShape aFaces1,aFaces2;
1722 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1723 aFaces1.Add(anExp.Current());
1725 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1726 aFaces2.Add(anExp.Current());
1728 // creating map of edge faces
1729 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1730 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1731 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1732 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1734 // constuct map face->face
1735 TopTools_IndexedDataMapOfShapeShape FF;
1736 TopoDS_Shape FS1,FS2;
1737 if (nbSubBases==0) {
1738 // find edge the most distant from location point
1739 // (this edge is not shared by two faces)
1740 double maxdist = 0.;
1742 TopoDS_Vertex V11,V21;
1743 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1744 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1745 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1746 if (aList.Extent()>1)
1748 TopExp_Explorer expv;
1749 expv.Init(tmp, TopAbs_VERTEX);
1750 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1752 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1753 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1754 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1755 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1760 TopTools_ListIteratorOfListOfShape anIter(aList);
1761 FS1 = anIter.Value();
1765 // main direction for comparing
1766 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1767 // find corresponding edge from next section
1768 double minang = M_PI;
1769 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1770 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1772 TopoDS_Vertex V12,V22;
1773 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1774 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1775 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1776 if (aList.Extent()>1)
1778 TopExp_Explorer expv;
1779 expv.Init(tmp, TopAbs_VERTEX);
1780 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1782 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1783 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1784 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1785 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1786 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1787 TopoDS_Vertex V1,V2;
1790 V1 = V2tmp; P1 = P2tmp;
1791 V2 = V1tmp; P2 = P1tmp;
1794 V1 = V1tmp; P1 = P1tmp;
1795 V2 = V2tmp; P2 = P2tmp;
1797 gp_Vec Vec1(P11,P1);
1798 gp_Vec Vec2(P21,P2);
1799 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1804 TopTools_ListIteratorOfListOfShape anIter(aList);
1805 FS2 = anIter.Value();
1809 // put all pairs to map FF
1815 // add pairs of edges to FF
1816 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1818 if (aCI) delete aCI;
1819 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1825 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1826 if (anItem.IsNull()) {
1827 if (aCI) delete aCI;
1828 Standard_ConstructionError::Raise("Invalid subbase shape");
1830 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1831 if (aRefBase.IsNull()) {
1832 if (aCI) delete aCI;
1833 Standard_ConstructionError::Raise("Invalid subbase shape");
1835 TopoDS_Shape aSh = aRefBase->GetValue();
1837 if (aCI) delete aCI;
1838 Standard_ConstructionError::Raise("Invalid subbase shape");
1840 if (aSh.ShapeType()!=TopAbs_FACE) {
1841 if (aCI) delete aCI;
1842 Standard_ConstructionError::Raise("Invalid subbase shape");
1847 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1848 if (anItem.IsNull()) {
1849 if (aCI) delete aCI;
1850 Standard_ConstructionError::Raise("Invalid subbase shape");
1852 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1853 if (aRefBase.IsNull()) {
1854 if (aCI) delete aCI;
1855 Standard_ConstructionError::Raise("Invalid subbase shape");
1857 TopoDS_Shape aSh = aRefBase->GetValue();
1859 if (aCI) delete aCI;
1860 Standard_ConstructionError::Raise("Invalid subbase shape");
1862 if (aSh.ShapeType()!=TopAbs_FACE) {
1863 if (aCI) delete aCI;
1864 Standard_ConstructionError::Raise("Invalid subbase shape");
1869 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1870 if (aCI) delete aCI;
1871 Standard_ConstructionError::Raise("Invalid subbase shape");
1876 // add pairs of edges to FF
1877 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1878 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1880 if (aCI) delete aCI;
1881 Standard_ConstructionError::Raise("Can not create correct pipe");
1885 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1887 // make pipe for each pair of faces
1888 for (j=1; j<=FF.Extent(); j++) {
1889 TopoDS_Shape F1 = FF.FindKey(j);
1890 if (F1.ShapeType() != TopAbs_FACE)
1892 TopoDS_Shape F2 = FF.FindFromIndex(j);
1893 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1894 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1895 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1896 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1897 // make pipe using aWire1 and aWire2
1898 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1899 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1900 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1901 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1902 aBuilder.SetDiscreteMode();
1903 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1904 aWithContact, aWithCorrect);
1905 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1906 aWithContact, aWithCorrect);
1907 if (!aBuilder.IsReady()) {
1908 if (aCI) delete aCI;
1909 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1912 BuildPipeShell(aBuilder);
1914 TopoDS_Shape aShape = aBuilder.Shape();
1915 TopTools_SequenceOfShape aLocalGroups[5];
1918 if (isGenerateGroups) {
1920 if (!DoGroups(aBuilder, aLocalGroups)) {
1921 if (aCI) delete aCI;
1922 Standard_ConstructionError::Raise("Generate groups failure");
1925 // Clear the groups Down and Up.
1926 aLocalGroups[GROUP_DOWN].Clear();
1927 aLocalGroups[GROUP_UP].Clear();
1930 aLocalGroups[GROUP_DOWN].Append(F1);
1933 if (i == nbBases - 1) {
1934 aLocalGroups[GROUP_UP].Append(F2);
1938 TopoDS_Shell aShell;
1939 B.MakeShell(aShell);
1940 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1941 B.Add(aShell,anExp.Current());
1946 // make sewing for this shell
1947 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1948 aSewing->SetTolerance(Precision::Confusion());
1949 aSewing->SetFaceMode(Standard_True);
1950 aSewing->SetFloatingEdgesMode(Standard_False);
1951 aSewing->SetNonManifoldMode(Standard_False);
1952 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1953 aSewing->Add(anExp.Current());
1956 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1957 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1958 aShell = TopoDS::Shell(aSewShape);
1959 GProp_GProps aSystem;
1960 BRepGProp::VolumeProperties(aShell, aSystem);
1961 if (aSystem.Mass()<0) {
1962 //cout<<"aSewShape is reversed"<<endl;
1965 if (BRep_Tool::IsClosed(aShell)) {
1966 TopoDS_Solid aSolid;
1967 B.MakeSolid(aSolid);
1968 B.Add(aSolid,aShell);
1969 B.Add(aComp,aSolid);
1972 B.Add(aComp,aShell);
1976 B.Add(aComp,aShell);
1979 if (isGenerateGroups) {
1980 // Replase Group shapes by modified ones.
1981 Standard_Integer iGrp;
1984 for (iGrp = 0; iGrp < 5; ++iGrp) {
1987 // For each sub-shape of pipe
1988 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1989 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1991 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1992 // Use the shape modified by sewing.
1993 const TopoDS_Shape &aModifGrpShape =
1994 aSewing->ModifiedSubShape(aGrpShape);
1996 aGroups[iGrp].Append(aModifGrpShape);
1998 // Use the shape as it is.
1999 aGroups[iGrp].Append(aGrpShape);
2009 if (isGenerateGroups) {
2011 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2012 TopTools_IndexedMapOfShape anIndices;
2014 TopExp::MapShapes(aComp, anIndices);
2016 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2017 if (aCI) delete aCI;
2018 Standard_ConstructionError::Raise("Generate groups failure");
2021 StoreGroups(aCI, aGroupIds);
2027 //=======================================================================
2028 //function : CreatePipeShellsWithoutPath
2029 //purpose : auxilary for Execute()
2030 //=======================================================================
2031 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
2033 //cout<<"CreatePipeShellsWithoutPath"<<endl;
2037 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
2039 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
2040 // vertex for recognition
2041 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
2042 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
2044 Standard_Integer nbBases = aBasesObjs->Length(),
2045 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
2047 if (nbv != nbBases) {
2048 if (aCI) delete aCI;
2049 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
2052 TopTools_SequenceOfShape aGroups[5];
2053 TopTools_SequenceOfShape SecVs,Bases;
2054 for (i=1; i<=nbBases; i++) {
2056 Handle(Standard_Transient) anItem = VObjs->Value(i);
2057 if (anItem.IsNull())
2059 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
2060 TopoDS_Shape V = aRef->GetValue();
2061 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
2065 anItem = aBasesObjs->Value(i);
2066 if (anItem.IsNull())
2068 aRef = Handle(GEOM_Function)::DownCast(anItem);
2069 TopoDS_Shape aSh = aRef->GetValue();
2074 nbv = SecVs.Length();
2075 nbBases = Bases.Length();
2076 if (nbv != nbBases) {
2077 if (aCI) delete aCI;
2078 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
2081 TopoDS_Compound aComp;
2082 B.MakeCompound(aComp);
2084 for (i = 1; i < nbBases; i++) {
2085 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
2086 TopoDS_Shape aShBase1 = Bases.Value(i);
2087 TopoDS_Shape aShBase2 = Bases.Value(i+1);
2088 TopExp_Explorer anExp;
2089 Standard_Integer nbf1 = 0;
2090 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2093 Standard_Integer nbf2 = 0;
2094 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2097 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
2099 if (aCI) delete aCI;
2100 Standard_ConstructionError::Raise("Different number of faces in the sections");
2103 TopTools_MapOfShape aFaces1,aFaces2;
2104 TopTools_MapOfShape aBndEdges1;
2106 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2107 const TopoDS_Shape &aBaseFace1 = anExp.Current();
2109 if (aFaces1.Add(aBaseFace1)) {
2110 // Get boundary edges.
2111 TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
2113 for (; anExpE.More(); anExpE.Next()) {
2114 const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
2116 if (!aBndEdges1.Add(aBaseEdge1)) {
2117 aBndEdges1.Remove(aBaseEdge1);
2122 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2123 aFaces2.Add(anExp.Current());
2126 // creating map of edge faces
2127 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
2128 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
2129 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
2130 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
2132 // constuct map face->face (and sub-shapes)
2133 TopTools_IndexedDataMapOfShapeShape FF;
2134 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
2135 TopoDS_Shape FS1, FS2;
2136 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
2137 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
2138 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
2141 MESSAGE (" first pair of corresponding faces is found");
2143 // add pairs of edges and vertexes to FF
2144 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
2146 if (aCI) delete aCI;
2147 Standard_ConstructionError::Raise("Can not create correct pipe");
2149 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
2151 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2152 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
2154 // make pipe for each pair of faces
2155 // auxilary map vertex->edge for created pipe edges
2156 TopTools_IndexedDataMapOfShapeShape VPE;
2157 ShapeAnalysis_Edge sae;
2158 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
2160 for (j=1; j<=FF.Extent(); j++) {
2161 TopoDS_Shape F1 = FF.FindKey(j);
2162 if (F1.ShapeType() != TopAbs_FACE)
2164 TopoDS_Shape F2 = FF.FindFromIndex(j);
2167 //if (nbff!=3) continue;
2169 MESSAGE (" make pipe for "<<nbff<<" face");
2171 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
2172 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2173 Handle(Geom_RectangularTrimmedSurface) RTS =
2174 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
2175 S1 = RTS->BasisSurface();
2177 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
2178 if (Pln1.IsNull()) {
2179 if (aCI) delete aCI;
2180 Standard_ConstructionError::Raise("Surface from face is not plane");
2182 gp_Vec aDir1(Pln1->Axis().Direction());
2184 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
2185 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2186 Handle(Geom_RectangularTrimmedSurface) RTS =
2187 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
2188 S2 = RTS->BasisSurface();
2190 Handle(Geom_Plane) Pln2 =
2191 Handle(Geom_Plane)::DownCast(S2);
2192 if (Pln2.IsNull()) {
2193 if (aCI) delete aCI;
2194 Standard_ConstructionError::Raise("Surface from face is not plane");
2196 gp_Vec aDir2(Pln2->Axis().Direction());
2198 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
2199 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
2201 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
2203 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
2206 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
2207 TopTools_SequenceOfShape aNewFs;
2208 TopTools_SequenceOfShape aLocalGroups[5];
2211 for (; anExpE.More(); anExpE.Next()) {
2212 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2214 if (!FF.Contains(E1))
2215 MESSAGE ("map FF not contains key E1");
2217 if (VPE.Contains(E1)) {
2218 aNewFs.Append(VPE.FindFromKey(E1));
2220 MESSAGE (" using existed face");
2225 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2226 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2227 TopoDS_Vertex V2 = sae.LastVertex(E1);
2228 if (!FF.Contains(V1))
2229 MESSAGE ("map FF not contains key V1");
2230 if (!FF.Contains(V2))
2231 MESSAGE ("map FF not contains key V2");
2232 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2233 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2234 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2235 if (Vtmp.IsSame(V4))
2237 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2238 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2239 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2240 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2243 Handle(Geom_BSplineCurve) C2;
2244 if (VPE.Contains(V2)) {
2245 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2247 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2250 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2251 HAP->SetValue(1,P2);
2252 HAP->SetValue(2,P3);
2253 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2254 anInt.Load(aDir1,aDir2);
2257 B.MakeEdge(E2,C2,1.e-7);
2258 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2259 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2264 Handle(Geom_BSplineCurve) C4;
2265 if (VPE.Contains(V1)) {
2266 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2268 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2271 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2272 HAP->SetValue(1,P1);
2273 HAP->SetValue(2,P4);
2274 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2275 anInt.Load(aDir1,aDir2);
2278 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2279 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2280 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2289 B.Add(W,E4.Reversed());
2294 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2295 //bool IsConicC1 = false;
2296 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2297 // IsConicC1 = true;
2298 // cout<<"C1 - Geom_Conic"<<endl;
2300 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2301 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2304 // double tol = BRep_Tool::Tolerance(E1);
2305 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2306 // C1 = ApxC1.Curve();
2308 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2309 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2310 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2315 Handle(Geom_BSplineCurve) CE1 =
2316 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2317 if (CE1->Degree()<3)
2318 CE1->IncreaseDegree(3);
2319 Handle(Geom_BSplineCurve) CE2 =
2320 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2321 if (CE2->Degree()<3)
2322 CE2->IncreaseDegree(3);
2323 Handle(Geom_BSplineCurve) CE3 =
2324 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2325 if (CE3->Degree()<3)
2326 CE3->IncreaseDegree(3);
2327 Handle(Geom_BSplineCurve) CE4 =
2328 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2329 if (CE4->Degree()<3)
2330 CE4->IncreaseDegree(3);
2332 Handle(Geom_Surface) BS;
2334 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2335 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2339 MESSAGE (" can not create BSplineSurface - create Bezier");
2341 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2342 double fp1,lp1,fp2,lp2;
2343 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2344 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2353 // get points from C1
2354 if (P1.Distance(P1C1)<1.e-6) {
2362 double step = (lp-fp)/(NbP-1);
2363 Points.SetValue(1,1,P1);
2365 for (n1=2; n1<NbP; n1++) {
2369 Points.SetValue(1,n1,P);
2371 Points.SetValue(1,NbP,P2);
2372 // get points from C3
2373 if (P4.Distance(P1C3)<1.e-6) {
2381 step = (lp-fp)/(NbP-1);
2382 Points.SetValue(NbP,1,P4);
2384 for (n1=2; n1<NbP; n1++) {
2388 Points.SetValue(NbP,n1,P);
2390 Points.SetValue(NbP,NbP,P3);
2391 // create isolines and get points from them
2392 for (n1=1; n1<=NbP; n1++) {
2393 gp_Pnt PI1 = Points.Value(1,n1);
2394 gp_Pnt PI2 = Points.Value(NbP,n1);
2395 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2396 HAP->SetValue(1,PI1);
2397 HAP->SetValue(2,PI2);
2398 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2399 anInt.Load(aDir1,aDir2);
2401 Handle(Geom_Curve) iso = anInt.Curve();
2402 fp = iso->FirstParameter();
2403 lp = iso->LastParameter();
2404 step = (lp-fp)/(NbP-1);
2406 TopoDS_Compound VComp;
2407 B.MakeCompound(VComp);
2408 for (n2=2; n2<NbP; n2++) {
2412 Points.SetValue(n2,n1,P);
2415 // create surface and face
2416 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2417 BS = new Geom_BezierSurface(Points);
2420 BRepBuilderAPI_MakeFace BB(BS,W);
2421 TopoDS_Face NewF = BB.Face();
2422 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2424 sff->FixOrientation();
2425 TopoDS_Face FixedFace = sff->Face();
2426 aNewFs.Append(FixedFace);
2427 VPE.Add(E1,FixedFace);
2429 if (isGenerateGroups) {
2430 if (aBndEdges1.Contains(E1)) {
2431 // This is a boundary face.
2432 aLocalGroups[GROUP_OTHER].Append(FixedFace);
2437 TopoDS_Shell aShell;
2438 B.MakeShell(aShell);
2439 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2440 B.Add(aShell,aNewFs(nf));
2446 if (isGenerateGroups && i == 1) {
2447 aLocalGroups[GROUP_DOWN].Append(F1);
2450 if (isGenerateGroups && i == nbBases - 1) {
2451 aLocalGroups[GROUP_UP].Append(F2);
2454 // make sewing for this shell
2455 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2456 aSewing->SetTolerance(Precision::Confusion());
2457 aSewing->SetFaceMode(Standard_True);
2458 aSewing->SetFloatingEdgesMode(Standard_False);
2459 aSewing->SetNonManifoldMode(Standard_False);
2460 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2461 aSewing->Add(anExp.Current());
2464 MESSAGE (" shell for face "<<nbff<<" is created");
2465 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2466 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2467 aShell = TopoDS::Shell(aSewShape);
2468 GProp_GProps aSystem;
2469 BRepGProp::VolumeProperties(aShell, aSystem);
2470 if (aSystem.Mass()<0) {
2471 //cout<<"aSewShape is reversed"<<endl;
2474 if (BRep_Tool::IsClosed(aShell)) {
2475 TopoDS_Solid aSolid;
2476 B.MakeSolid(aSolid);
2477 B.Add(aSolid,aShell);
2478 B.Add(aComp,aSolid);
2479 MESSAGE (" solid for face "<<nbff<<" is created");
2482 B.Add(aComp,aShell);
2483 MESSAGE (" solid for face "<<nbff<<" is not created");
2487 B.Add(aComp,aShell);
2488 MESSAGE (" solid for face "<<nbff<<" is not created");
2491 if (isGenerateGroups) {
2492 Standard_Integer iGrp;
2494 for (iGrp = 0; iGrp < 5; ++iGrp) {
2497 // For each sub-shape of pipe
2498 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2499 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2501 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2502 // Use the shape modified by sewing.
2503 const TopoDS_Shape &aModifGrpShape =
2504 aSewing->ModifiedSubShape(aGrpShape);
2506 aGroups[iGrp].Append(aModifGrpShape);
2508 // Use the shape as it is.
2509 aGroups[iGrp].Append(aGrpShape);
2517 if (isGenerateGroups) {
2519 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2520 TopTools_IndexedMapOfShape anIndices;
2522 TopExp::MapShapes(aComp, anIndices);
2524 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2525 if (aCI) delete aCI;
2526 Standard_ConstructionError::Raise("Generate groups failure");
2529 StoreGroups(aCI, aGroupIds);
2535 //=======================================================================
2536 //function : CreatePipeBiNormalAlongVector
2537 //purpose : auxilary for Execute()
2538 //=======================================================================
2539 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2540 GEOMImpl_IPipe* aCI)
2542 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2544 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2545 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2546 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2547 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2549 if (aShapeBase.IsNull()) {
2550 if (aCIBN) delete aCIBN;
2551 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2554 // Make copy to prevent modifying of base object: 0021525
2555 BRepBuilderAPI_Copy Copy (aShapeBase);
2557 aShapeBase = Copy.Shape();
2560 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2563 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2564 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2566 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2569 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2570 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2571 aProf = wexp.Current();
2574 Standard_TypeMismatch::Raise
2575 ("MakePipe aborted : invalid type of base");
2577 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2578 PipeBuilder.Add(aProf);
2580 if (aShapeVec.IsNull()) {
2581 if (aCIBN) delete aCIBN;
2582 Standard_NullObject::Raise
2583 ("MakePipe aborted : null vector argument");
2585 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2586 Standard_TypeMismatch::Raise
2587 ("MakePipe aborted: invalid type of vector");
2588 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2589 TopoDS_Vertex V1, V2;
2590 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2591 if (V1.IsNull() || V2.IsNull())
2592 Standard_NullObject::Raise
2593 ("MakePipe aborted: vector is not defined");
2594 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2595 gp_Dir BiNormal(aVec);
2596 PipeBuilder.SetMode(BiNormal);
2598 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2600 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2601 PipeBuilder.MakeSolid();
2604 if (!CreateGroups(PipeBuilder, aCIBN)) {
2605 if (aCIBN) delete aCIBN;
2606 Standard_ConstructionError::Raise("Generate groups failure");
2609 return PipeBuilder.Shape();
2612 //=======================================================================
2613 //function : FillGroups
2614 //purpose : auxilary for DoGroups()
2615 //=======================================================================
2616 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
2617 const TopTools_IndexedMapOfShape &theIndices,
2618 Handle(TColStd_HArray1OfInteger) *theGroupIds)
2622 for (i = 0; i < 5; ++i) {
2623 if (!theGroups[i].IsEmpty()) {
2624 const Standard_Integer aNbShapes = theGroups[i].Length();
2627 theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
2629 for (j = 1; j <= aNbShapes; ++j) {
2630 const TopoDS_Shape &aShape = theGroups[i].Value(j);
2631 const Standard_Integer anIndex = theIndices.FindIndex(aShape);
2637 theGroupIds[i]->SetValue(j, anIndex);
2645 //=======================================================================
2646 //function : StoreGroups
2647 //purpose : auxilary for CreateGroups()
2648 //=======================================================================
2649 void StoreGroups(GEOMImpl_IPipe *theCI,
2650 Handle(TColStd_HArray1OfInteger) *theGroups)
2652 if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
2653 theCI->SetGroupDown(theGroups[GROUP_DOWN]);
2656 if (theGroups[GROUP_UP].IsNull() == Standard_False) {
2657 theCI->SetGroupUp(theGroups[GROUP_UP]);
2660 if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
2661 theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
2664 if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
2665 theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
2668 if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
2669 theCI->SetGroupOther(theGroups[GROUP_OTHER]);
2673 //=======================================================================
2674 //function : CreateDownUpGroups
2675 //purpose : auxilary for DoGroups()
2676 //=======================================================================
2677 static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
2678 TopTools_SequenceOfShape *theGroups,
2679 Standard_Boolean &IsDoSides)
2681 const TopoDS_Shape aDownShape = theSweep->FirstShape();
2682 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2683 TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
2685 IsDoSides = Standard_False;
2690 anUpDownType = TopAbs_EDGE;
2692 if (GEOMUtils::IsOpenPath(aDownShape)) {
2693 IsDoSides = Standard_True;
2698 anUpDownType = TopAbs_FACE;
2704 if (anUpDownType == TopAbs_SHAPE) {
2705 // Invalid Up and Down group type.
2709 TopExp_Explorer anExp(aDownShape, anUpDownType);
2710 TopTools_MapOfShape aMapFence;
2712 // Create Down group.
2713 for (; anExp.More(); anExp.Next()) {
2714 const TopoDS_Shape &aShape = anExp.Current();
2716 if (aMapFence.Add(aShape)) {
2717 theGroups[GROUP_DOWN].Append(aShape);
2722 const TopoDS_Shape anUpShape = theSweep->LastShape();
2725 anExp.Init(anUpShape, anUpDownType);
2727 for (; anExp.More(); anExp.Next()) {
2728 const TopoDS_Shape &aShape = anExp.Current();
2730 if (aMapFence.Add(aShape)) {
2731 theGroups[GROUP_UP].Append(aShape);
2738 //=======================================================================
2739 //function : DoGroups
2740 //purpose : auxilary for CreateGroups()
2741 //=======================================================================
2742 bool DoGroups(BRepOffsetAPI_MakePipeShell &theSweep,
2743 TopTools_SequenceOfShape *theGroups)
2745 Standard_Boolean isDoSides = Standard_False;
2747 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2748 // Up and Down groups creation failure
2752 const TopoDS_Shape aDownShape = theSweep.FirstShape();
2755 // Create Side1 and Side2 groups.
2756 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2757 TopoDS_Vertex aV[2];
2760 if (aType == TopAbs_EDGE) {
2761 TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
2762 } else { // aType == TopAbs_WIRE
2763 TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
2766 for (i = 0; i < 2; ++i) {
2767 if (aV[i].IsNull() == Standard_False) {
2768 const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
2770 if (!aLstSide.IsEmpty()) {
2771 TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
2772 TopTools_MapOfShape aMapFence;
2773 const Standard_Integer anIdSide =
2774 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2776 for (; aSideIt.More(); aSideIt.Next()) {
2777 const TopoDS_Shape &aSideShape = aSideIt.Value();
2779 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2780 if (aMapFence.Add(aSideShape)) {
2781 theGroups[anIdSide].Append(aSideShape);
2784 // Only edges can be is Side1 and Side2 groups.
2792 // Create Other group. Get boudnary edges of the profile.
2793 TopTools_MapOfShape aMapBndEdges;
2794 TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
2796 for (; anExp.More(); anExp.Next()) {
2797 const TopoDS_Shape &anEdge = anExp.Current();
2799 if (!aMapBndEdges.Add(anEdge)) {
2800 aMapBndEdges.Remove(anEdge);
2804 // Fill the map of faces generated from profile's boundary edges.
2805 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2806 TopTools_MapOfShape aMapFence;
2808 for (; anIter.More(); anIter.Next()) {
2809 const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
2811 if (!aLstOther.IsEmpty()) {
2812 TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
2814 for (; anOtherIt.More(); anOtherIt.Next()) {
2815 const TopoDS_Shape &anOtherShape = anOtherIt.Value();
2817 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2818 if (aMapFence.Add(anOtherShape)) {
2819 theGroups[GROUP_OTHER].Append(anOtherShape);
2822 // Only faces can be in Other group.
2833 //=======================================================================
2834 //function : CreateGroups
2835 //purpose : auxilary for Execute()
2836 //=======================================================================
2837 bool CreateGroups(BRepOffsetAPI_MakePipeShell &theSweep,
2838 GEOMImpl_IPipe *theCI)
2840 if (!theCI->GetGenerateGroups()) {
2846 TopTools_SequenceOfShape aGroups[5];
2848 if (!DoGroups(theSweep, aGroups)) {
2853 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2854 TopTools_IndexedMapOfShape anIndices;
2855 const TopoDS_Shape aResult = theSweep.Shape();
2857 TopExp::MapShapes(aResult, anIndices);
2859 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2864 StoreGroups(theCI, aGroupIds);
2869 //=======================================================================
2870 //function : DoGroups
2871 //purpose : auxilary for CreateGroups()
2872 //=======================================================================
2873 static bool DoGroups(const TopoDS_Shape &theProfile,
2874 const TopoDS_Shape &thePath,
2875 BRepOffsetAPI_MakePipe &theSweep,
2876 TopTools_SequenceOfShape *theGroups)
2878 Standard_Boolean isDoSides = Standard_False;
2880 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2881 // Up and Down groups creation failure
2886 // Create Side1 and Side2 groups.
2887 const TopAbs_ShapeEnum aType = theProfile.ShapeType();
2888 TopoDS_Vertex aV[2];
2891 if (aType == TopAbs_EDGE) {
2892 TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
2893 } else { // aType == TopAbs_WIRE
2894 TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
2897 for (i = 0; i < 2; ++i) {
2898 if (aV[i].IsNull() == Standard_False) {
2899 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2900 TopTools_MapOfShape aMapFence;
2901 const Standard_Integer anIdSide =
2902 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2904 for (; anExpP.More(); anExpP.Next()) {
2905 const TopoDS_Shape aSideShape =
2906 theSweep.Generated(anExpP.Current(), aV[i]);
2908 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2909 if (aMapFence.Add(aSideShape)) {
2910 theGroups[anIdSide].Append(aSideShape);
2913 // Only edges can be is Side1 and Side2 groups.
2920 // Create Other group. Get boudnary edges of the profile.
2921 TopTools_MapOfShape aMapBndEdges;
2922 TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
2924 for (; anExp.More(); anExp.Next()) {
2925 const TopoDS_Shape &anEdge = anExp.Current();
2927 if (!aMapBndEdges.Add(anEdge)) {
2928 aMapBndEdges.Remove(anEdge);
2932 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2933 TopTools_MapOfShape aMapFence;
2935 for (; anExpP.More(); anExpP.Next()) {
2936 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2938 for (; anIter.More(); anIter.Next()) {
2939 const TopoDS_Shape anOtherShape =
2940 theSweep.Generated(anExpP.Current(), anIter.Key());
2942 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2943 if (aMapFence.Add(anOtherShape)) {
2944 theGroups[GROUP_OTHER].Append(anOtherShape);
2947 // Only faces can be in Other group.
2957 //=======================================================================
2958 //function : CreateGroups
2959 //purpose : auxilary for Execute()
2960 //=======================================================================
2961 static bool CreateGroups(const TopoDS_Shape &theProfile,
2962 const TopoDS_Shape &thePath,
2963 BRepOffsetAPI_MakePipe &theSweep,
2964 GEOMImpl_IPipe *theCI)
2966 if (!theCI->GetGenerateGroups()) {
2972 TopTools_SequenceOfShape aGroups[5];
2974 if (!DoGroups(theProfile, thePath, theSweep, aGroups)) {
2979 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2980 TopTools_IndexedMapOfShape anIndices;
2981 const TopoDS_Shape aResult = theSweep.Shape();
2983 TopExp::MapShapes(aResult, anIndices);
2985 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2990 StoreGroups(theCI, aGroupIds);
2995 //=======================================================================
2996 //function : Execute
2998 //=======================================================================
2999 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
3001 if (Label().IsNull()) return 0;
3002 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
3003 Standard_Integer aType = aFunction->GetType();
3005 GEOMImpl_IPipe* aCI = 0;
3006 if (aType == PIPE_BASE_PATH)
3007 aCI = new GEOMImpl_IPipe (aFunction);
3008 else if (aType == PIPE_DIFFERENT_SECTIONS)
3009 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
3010 else if (aType == PIPE_SHELL_SECTIONS)
3011 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3012 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
3013 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3014 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
3015 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
3019 TopoDS_Wire aWirePath;
3020 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
3021 // working with path
3022 Handle(GEOM_Function) aRefPath = aCI->GetPath();
3023 TopoDS_Shape aShapePath = aRefPath->GetValue();
3025 if (aShapePath.IsNull()) {
3026 MESSAGE ("Driver : path is null");
3027 if (aCI) delete aCI;
3028 Standard_NullObject::Raise("MakePipe aborted : null path argument");
3033 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
3034 TopTools_SequenceOfShape anEdges;
3035 TopExp_Explorer anExp;
3039 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
3040 B.Add(W, anExp.Current());
3046 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
3047 aWirePath = TopoDS::Wire(aShapePath);
3051 if (aShapePath.ShapeType() == TopAbs_EDGE) {
3052 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
3053 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
3058 if (aCI) delete aCI;
3059 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
3062 // Check if it is possible to create groups.
3063 if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
3068 Standard_ConstructionError::Raise
3069 ("Can't create groups if the path is closed");
3073 TopoDS_Shape aShape;
3074 const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
3076 if (aType == PIPE_BASE_PATH) {
3077 Handle(GEOM_Function) aRefBase = aCI->GetBase();
3078 TopoDS_Shape aShapeBase;
3080 // Make copy to prevent modifying of base object 0020766 : EDF 1320
3081 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
3083 aShapeBase = Copy.Shape();
3085 if (aShapeBase.IsNull()) {
3086 if (aCI) delete aCI;
3087 Standard_NullObject::Raise("MakePipe aborted : null base argument");
3091 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
3092 aShapeBase.ShapeType() == TopAbs_WIRE)
3094 TopoDS_Wire Profile;
3095 if (aShapeBase.ShapeType() == TopAbs_WIRE)
3096 Profile = TopoDS::Wire(aShapeBase);
3100 BB.MakeWire(Profile);
3101 BB.Add(Profile, aShapeBase);
3104 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
3105 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
3106 if (FaceBuilder.IsDone())
3107 Sweep.SetMode(FaceBuilder.Face());
3110 Standard_Boolean isDone = BuildPipeShell(Sweep);
3114 if (aCI) delete aCI;
3115 Standard_ConstructionError::Raise("MakePipeShell failed");
3118 aShape = Sweep.Shape(); //result is good
3120 if (!CreateGroups(Sweep, aCI)) {
3121 if (aCI) delete aCI;
3122 Standard_ConstructionError::Raise("Generate groups failure");
3127 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
3128 BRepOffsetAPI_MakePipe aMkPipe(aWirePath, aShapeBase, theBestMode);
3130 if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) {
3131 aShape = aMkPipe.Shape();
3133 if (!CreateGroups(aShapeBase, aWirePath, aMkPipe, aCI)) {
3134 if (aCI) delete aCI;
3135 Standard_ConstructionError::Raise("Generate groups failure");
3137 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
3138 // Try to use Descrete Trihedron mode.
3139 BRepOffsetAPI_MakePipe aMkPipeDescrete
3140 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron);
3142 if (aMkPipeDescrete.IsDone()) {
3143 aShape = aMkPipeDescrete.Shape();
3145 if (!CreateGroups(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
3146 if (aCI) delete aCI;
3147 Standard_ConstructionError::Raise("Generate groups failure");
3154 //building pipe with different sections
3155 else if (aType == PIPE_DIFFERENT_SECTIONS) {
3156 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
3157 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
3158 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
3159 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
3160 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
3161 Standard_Boolean isBySteps = aCIDS->GetIsBySteps();
3168 Standard_Integer nbBases = aBasesObjs->Length();
3169 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
3171 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
3172 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
3175 for (i = 1; i <= nbBases; i++) {
3176 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
3177 if (anItem.IsNull())
3179 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
3180 if (aRefBase.IsNull())
3182 if (aRefBase->GetValue().IsNull())
3185 aHSeqBases->Append(aRefBase->GetValue());
3187 for (i = 1; i <= nbLocs; i++) {
3188 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
3189 if (anItemLoc.IsNull())
3191 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
3192 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
3193 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
3196 aHSeqLocs->Append(aShapeLoc);
3200 Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
3201 Handle(TColStd_HArray1OfInteger) aGroups[5];
3203 if (isGenerateGroups) {
3207 aShape = CreatePipeWithDifferentSections
3208 (aWirePath, aHSeqBases, aHSeqLocs,
3209 aWithContact, aWithCorrect, isBySteps, pGroups);
3211 if (isGenerateGroups) {
3212 // Store created groups.
3213 GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
3215 StoreGroups(&aPipeDS, aGroups);
3219 //building pipe with shell sections
3220 else if (aType == PIPE_SHELL_SECTIONS) {
3221 aShape = CreatePipeForShellSections(aWirePath,aCI);
3224 //building pipe shell sections without path
3225 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
3226 aShape = CreatePipeShellsWithoutPath(aCI);
3229 //building a pipe with constant bi-normal along given vector
3230 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
3231 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
3239 if (aShape.IsNull()) return 0;
3241 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
3242 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
3244 if (aType != PIPE_BASE_PATH &&
3245 aType != PIPE_SHELLS_WITHOUT_PATH) {
3246 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
3247 if (anExpV.More()) {
3248 Standard_Real aVertMaxTol = -RealLast();
3249 for (; anExpV.More(); anExpV.Next()) {
3250 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
3251 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
3252 if (aTol > aVertMaxTol)
3255 aVertMaxTol += Precision::Confusion();
3257 TopTools_DataMapOfShapeListOfShape aMapModif;
3258 TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
3260 if (isGenerateGroups) {
3261 pMapModif = &aMapModif;
3264 TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
3265 (aShape, aVertMaxTol, Standard_True, pMapModif);
3267 if (isGenerateGroups && !aMapModif.IsEmpty()) {
3269 GEOMImpl_IPipe aCI(aFunction);
3270 Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
3271 { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
3272 aCI.GetGroupSide2(), aCI.GetGroupOther() };
3273 TopTools_IndexedMapOfShape anIndices;
3274 TopTools_IndexedMapOfShape aNewIndices;
3275 TopTools_SequenceOfShape aNewShapes[5];
3276 TopTools_MapOfShape aMapReplaced;
3277 TopTools_MapOfShape aMapGlued;
3278 Standard_Integer iGrp;
3281 TopExp::MapShapes(aShape, anIndices);
3282 TopExp::MapShapes(aNewShape, aNewIndices);
3284 for (iGrp = 0; iGrp < 5; ++iGrp) {
3285 if (aGroupIDs[iGrp].IsNull() == Standard_False) {
3286 const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
3287 const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
3289 for (i = aLower; i <= anUpper; ++i) {
3290 const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
3291 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
3293 if (aMapModif.IsBound(aSubShape)) {
3294 const TopTools_ListOfShape &aListModif =
3295 aMapModif.Find(aSubShape);
3296 TopTools_ListIteratorOfListOfShape anIter(aListModif);
3298 for (; anIter.More(); anIter.Next()) {
3299 const TopoDS_Shape &aNewShape = anIter.Value();
3301 if (aMapReplaced.Add(aNewShape)) {
3302 aNewShapes[iGrp].Append(aNewShape);
3304 // This is a glued shape. It means that it is internal
3305 // one and should be removed from groups later.
3306 aMapGlued.Add(aNewShape);
3310 // Shape is not modified.
3311 aNewShapes[iGrp].Append(aSubShape);
3317 if (!aMapGlued.IsEmpty()) {
3318 // Remove glued (internal) shapes from groups.
3319 for (iGrp = 0; iGrp < 5; ++iGrp) {
3320 Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
3322 for (i = 1; i < aNbShapes; ++i) {
3323 const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
3325 if (aMapGlued.Contains(aNewShape)) {
3326 aNewShapes[iGrp].Remove(i);
3334 // Store modified groups.
3335 Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
3337 if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
3338 Standard_ConstructionError::Raise("Generate groups failure");
3341 StoreGroups(&aCI, aNewGroupIDs);
3348 // Note: group indices should not be changed after the next call.
3349 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
3350 aFunction->SetValue(aRes);
3352 log.SetTouched(Label());
3356 //================================================================================
3358 * \brief Returns a name of creation operation and names and values of creation parameters
3360 //================================================================================
3362 bool GEOMImpl_PipeDriver::
3363 GetCreationInformation(std::string& theOperationName,
3364 std::vector<GEOM_Param>& theParams)
3366 if (Label().IsNull()) return 0;
3367 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
3368 Standard_Integer aType = function->GetType();
3371 case PIPE_BASE_PATH:
3373 theOperationName = "PIPE";
3374 GEOMImpl_IPipe aCI( function );
3375 AddParam( theParams, "Base Object", aCI.GetBase() );
3376 AddParam( theParams, "Path Object", aCI.GetPath() );
3379 case PIPE_BI_NORMAL_ALONG_VECTOR:
3381 theOperationName = "PIPE";
3382 GEOMImpl_IPipeBiNormal aCI( function );
3383 AddParam( theParams, "Base Object", aCI.GetBase() );
3384 AddParam( theParams, "Path Object", aCI.GetPath() );
3385 AddParam( theParams, "BiNormal", aCI.GetVector() );
3388 case PIPE_DIFFERENT_SECTIONS:
3390 theOperationName = "PIPE";
3391 GEOMImpl_IPipeDiffSect aCI( function );
3392 AddParam( theParams, "Bases", aCI.GetBases() );
3393 AddParam( theParams, "Locations", aCI.GetLocations() );
3394 AddParam( theParams, "Path", aCI.GetPath() );
3396 if (!aCI.GetIsBySteps()) {
3397 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3398 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3401 AddParam( theParams, "Step by step", aCI.GetIsBySteps() );
3404 case PIPE_SHELL_SECTIONS:
3406 theOperationName = "PIPE";
3407 GEOMImpl_IPipeShellSect aCI( function );
3408 AddParam( theParams, "Bases", aCI.GetBases() );
3409 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
3410 AddParam( theParams, "Locations", aCI.GetLocations() );
3411 AddParam( theParams, "Path", aCI.GetPath() );
3412 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3413 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3416 case PIPE_SHELLS_WITHOUT_PATH:
3418 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
3419 GEOMImpl_IPipeShellSect aCI( function );
3420 AddParam( theParams, "Bases", aCI.GetBases() );
3421 AddParam( theParams, "Locations", aCI.GetLocations() );
3431 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
3432 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);