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)
183 theBuilder.SetForceApproxC1(Standard_True);
187 Standard_Boolean isDone = theBuilder.IsDone();
190 theBuilder.ErrorOnSurface() > TolPipeSurf) {
191 // Try to use Descrete Trihedron mode.
192 theBuilder.SetDiscreteMode();
194 isDone = theBuilder.IsDone();
200 //=======================================================================
201 //function : FillForOtherEdges
202 //purpose : auxilary for CreatePipeForShellSections()
203 //=======================================================================
204 static bool FillForOtherEdges(const TopoDS_Shape& F1,
205 const TopoDS_Shape& E1,
206 const TopoDS_Shape& V1,
207 TopTools_IndexedDataMapOfShapeShape& FF)
209 //cout<<"FillForOtherEdges"<<endl;
210 // find other pairs for vertexes and edges
211 // creating map of vertex edges for both faces
212 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
213 TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
214 if (!FF.Contains(F1))
215 MESSAGE(" FillForOtherEdges: map FF not contains key F1");
216 if (!FF.Contains(E1))
217 MESSAGE(" FillForOtherEdges: map FF not contains key E1");
218 if (!FF.Contains(V1))
219 MESSAGE(" FillForOtherEdges: map FF not contains key V1");
220 const TopoDS_Shape& F2 = FF.FindFromKey(F1);
221 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
222 const TopoDS_Shape& V2 = FF.FindFromKey(V1);
223 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge2;
224 TopExp::MapShapesAndAncestors(F2, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge2);
226 TopoDS_Edge ES1 = TopoDS::Edge(E1);
227 TopoDS_Edge ES2 = TopoDS::Edge(E2);
228 TopoDS_Shape VS1 = V1;
229 TopoDS_Shape VS2 = V2;
231 ShapeAnalysis_Edge sae;
233 if (!aMapVertEdge1.Contains(VS1))
234 MESSAGE (" FillForOtherEdges: map aMapVertEdge1 not contains key VS1");
235 const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
236 //TopoDS_Shape E1next;
237 TopTools_ListIteratorOfListOfShape anIter1(aList1);
238 if (anIter1.Value().IsSame(ES1)) {
241 //E1next = anIter1.Value();
242 if (!aMapVertEdge2.Contains(VS2))
243 MESSAGE (" FillForOtherEdges: map aMapVertEdge2 not contains key VS2");
244 const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
245 //TopoDS_Shape E2next;
246 TopTools_ListIteratorOfListOfShape anIter2(aList2);
247 if (anIter2.Value().IsSame(ES2)) {
250 //E2next = anIter2.Value();
251 //ES1 = TopoDS::Edge(E1next);
252 //ES2 = TopoDS::Edge(E2next);
253 ES1 = TopoDS::Edge(anIter1.Value());
254 ES2 = TopoDS::Edge(anIter2.Value());
255 if (!FF.Contains(ES1)) {
258 if (VS1.IsSame(sae.FirstVertex(ES1)))
259 VS1 = sae.LastVertex(ES1);
261 VS1 = sae.FirstVertex(ES1);
262 if (VS2.IsSame(sae.FirstVertex(ES2)))
263 VS2 = sae.LastVertex(ES2);
265 VS2 = sae.FirstVertex(ES2);
268 if (!FF.Contains(VS1)) {
276 //=======================================================================
277 //function : FillCorrespondingEdges
278 //purpose : auxilary for CreatePipeForShellSections()
279 //=======================================================================
280 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
281 const TopoDS_Shape& FS2,
282 const TopoDS_Vertex& aLoc1,
283 const TopoDS_Vertex& aLoc2,
284 const TopoDS_Wire& aWirePath,
285 TopTools_IndexedDataMapOfShapeShape& FF)
287 //cout<<"FillCorrespondingEdges"<<endl;
288 // find corresponding edges
289 TopExp_Explorer expw1(FS1,TopAbs_WIRE);
290 TopoDS_Wire aWire1 = TopoDS::Wire(expw1.Current());
291 //exp = TopExp_Explorer(FS2,TopAbs_WIRE);
292 TopExp_Explorer expw2(FS2,TopAbs_WIRE);
293 TopoDS_Wire aWire2 = TopoDS::Wire(expw2.Current());
294 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
295 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
296 if (theBestMode == GeomFill_IsDiscreteTrihedron)
297 aBuilder.SetDiscreteMode();
298 aBuilder.Add(aWire1, aLoc1);
299 aBuilder.Add(aWire2, aLoc2);
300 if (!aBuilder.IsReady()) {
304 BuildPipeShell(aBuilder);
306 TopoDS_Shape aShape = aBuilder.Shape();
307 ShapeAnalysis_Edge sae;
308 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
309 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
310 TopTools_MapOfShape Vs1,Vs2;
312 exp.Init(FS1, TopAbs_EDGE);
313 TopoDS_Edge E1 = TopoDS::Edge(exp.Current());
314 TopoDS_Vertex V11 = sae.FirstVertex(E1);
315 TopoDS_Vertex V21 = sae.LastVertex(E1);
316 gp_Pnt P11 = BRep_Tool::Pnt(V11);
317 gp_Pnt P21 = BRep_Tool::Pnt(V21);
318 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
319 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
320 // find corresponding vertexes from created shape
321 TopoDS_Vertex VN11,VN21;
322 for (exp.Init(aShape, TopAbs_VERTEX); exp.More(); exp.Next()) {
323 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
324 gp_Pnt P = BRep_Tool::Pnt(V);
325 if (P.Distance(P11)<tol) {
328 if (P.Distance(P21)<tol) {
332 // find edge contains VN11 and VN21 and corresponding vertexes
333 TopoDS_Vertex VN12,VN22;
334 for (exp.Init(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
335 TopoDS_Shape F = exp.Current();
336 TopExp_Explorer expe;
338 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
339 TopoDS_Edge E = TopoDS::Edge(expe.Current());
340 TopoDS_Vertex VF = sae.FirstVertex(E);
341 TopoDS_Vertex VL = sae.LastVertex(E);
342 if ((VF.IsSame(VN11) && VL.IsSame(VN21)) || (VF.IsSame(VN21) && VL.IsSame(VN11))) {
348 for (expe.Init(F, TopAbs_EDGE); expe.More(); expe.Next()) {
349 TopoDS_Edge E = TopoDS::Edge(expe.Current());
350 TopoDS_Vertex VF = sae.FirstVertex(E);
351 TopoDS_Vertex VL = sae.LastVertex(E);
352 if (VF.IsSame(VN11) && !VL.IsSame(VN21))
354 if (VL.IsSame(VN11) && !VF.IsSame(VN21))
356 if (VF.IsSame(VN21) && !VL.IsSame(VN11))
358 if (VL.IsSame(VN21) && !VF.IsSame(VN11))
364 // find vertexes from FS2 corresponded to VN12 and VN22
365 // and find edge from FS2 contains V12 and V22,
366 // this edge will be corresponded to edge E1
367 TopoDS_Vertex V12,V22;
368 gp_Pnt PN12 = BRep_Tool::Pnt(VN12);
369 gp_Pnt PN22 = BRep_Tool::Pnt(VN22);
370 //cout<<"PN12("<<PN12.X()<<","<<PN12.Y()<<","<<PN12.Z()<<")"<<endl;
371 //cout<<"PN22("<<PN22.X()<<","<<PN22.Y()<<","<<PN22.Z()<<")"<<endl;
373 TopExp_Explorer expe;
374 for (expe.Init(FS2, TopAbs_EDGE); expe.More(); expe.Next()) {
375 TopoDS_Edge E = TopoDS::Edge(expe.Current());
376 TopoDS_Vertex VF = sae.FirstVertex(E);
377 TopoDS_Vertex VL = sae.LastVertex(E);
378 gp_Pnt PF = BRep_Tool::Pnt(VF);
379 gp_Pnt PL = BRep_Tool::Pnt(VL);
380 if (PF.Distance(PN12)<tol && PL.Distance(PN22)<tol) {
386 if (PF.Distance(PN22)<tol && PL.Distance(PN12)<tol) {
397 // find other pairs for vertexes and edges
398 // creating map of vertex edges for both faces
399 return FillForOtherEdges(FS1,E1,V21,FF);
404 //=======================================================================
405 //function : FillCorrespondingEdges
406 //purpose : auxilary for CreatePipeShellsWithoutPath()
407 //=======================================================================
408 static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
409 const TopoDS_Shape& FS2,
410 const TopoDS_Vertex& aLoc1,
411 const TopoDS_Vertex& aLoc2,
412 TopTools_IndexedDataMapOfShapeShape& FF)
414 //cout<<"FillCorrespondingEdges"<<endl;
416 gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
417 gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
420 ShapeAnalysis_Edge sae;
421 double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
422 BRep_Tool::Tolerance(TopoDS::Face(FS2)));
423 TopTools_MapOfShape Vs1,Vs2;
425 TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
428 TopExp_Explorer exp1;
429 for (exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next()) {
430 E1 = TopoDS::Edge(exp1.Current());
431 TopoDS_Vertex V1 = sae.FirstVertex(E1);
432 TopoDS_Vertex V2 = sae.LastVertex(E1);
433 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
434 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
435 //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
436 //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
437 if (P1.Distance(Ptmp1)<tol) {
441 if (P1.Distance(Ptmp2)<tol) {
448 TopoDS_Vertex VE21,VE22;
450 for (exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next()) {
451 TopoDS_Edge E = TopoDS::Edge(exp1.Current());
452 TopoDS_Vertex V1 = sae.FirstVertex(E);
453 TopoDS_Vertex V2 = sae.LastVertex(E);
454 gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
455 gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
456 if (P2.Distance(Ptmp1)<tol) {
468 if (P2.Distance(Ptmp2)<tol) {
482 gp_Pnt PV21 = BRep_Tool::Pnt(V21);
483 gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
484 gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
485 gp_Vec aDir1(PV21,PE21);
486 gp_Vec aDir2(PV21,PE22);
487 double ang1 = aDir.Angle(aDir1);
488 double ang2 = aDir.Angle(aDir2);
489 if (fabs(ang1)<fabs(ang2)) {
502 // find other pairs for vertexes and edges
503 return FillForOtherEdges(FS1,E1,V21,FF);
506 //=======================================================================
507 //function : FindNextPairOfFaces
508 //purpose : auxilary for CreatePipeForShellSections()
509 //=======================================================================
510 static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
511 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
512 TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces2,
513 TopTools_IndexedDataMapOfShapeShape& FF,
516 //cout<<"FindNextPairOfFaces"<<endl;
517 TopExp_Explorer anExp;
518 for (anExp.Init(aCurFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
519 TopoDS_Shape E1 = anExp.Current();
520 if (!FF.Contains(E1)) {
522 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
524 if (!FF.Contains(E1))
525 MESSAGE (" FindNextPairOfFaces: map FF not contains key E1");
526 const TopoDS_Shape& E2 = FF.FindFromKey(E1);
527 TopExp_Explorer anExpV;
528 anExpV.Init(E1, TopAbs_VERTEX);
529 TopoDS_Shape V1 = anExpV.Current();
530 if (!FF.Contains(V1)) {
532 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
535 if (!aMapEdgeFaces1.Contains(E1))
536 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1");
537 const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
538 if (aList1.Extent()<2)
540 TopTools_ListIteratorOfListOfShape anIter(aList1);
541 if (anIter.Value().IsEqual(aCurFace)) {
544 TopoDS_Shape F1other = anIter.Value();
545 if (FF.Contains(F1other))
548 if (!FF.Contains(aCurFace))
549 MESSAGE (" FindNextPairOfFaces: map FF not contains key aCurFace");
550 const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
551 if (!aMapEdgeFaces2.Contains(E2))
552 MESSAGE (" FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2");
553 const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
554 if (aList2.Extent()<2) {
556 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find corresponding face");
558 TopTools_ListIteratorOfListOfShape anIter2(aList2);
559 if (anIter2.Value().IsEqual(F2)) {
562 TopoDS_Shape F2other = anIter2.Value();
563 FF.Add(F1other,F2other);
565 // add pairs of edges to FF
566 bool stat = FillForOtherEdges(F1other,E1,V1,FF);
569 Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
572 FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
576 //=======================================================================
577 //function : FindFirstPairFaces
578 //purpose : auxilary for Execute()
579 //=======================================================================
580 static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
581 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
582 TopoDS_Shape& FS1, TopoDS_Shape& FS2)
584 //cout<<"FindFirstPairFaces"<<endl;
586 // check if vertexes are sub-shapes of sections
587 gp_Pnt P1 = BRep_Tool::Pnt(V1);
588 gp_Pnt P2 = BRep_Tool::Pnt(V2);
589 TopoDS_Vertex V1new,V2new;
591 double mindist = 1.e10;
592 for (exp.Init(S1, TopAbs_VERTEX); exp.More(); exp.Next()) {
593 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
594 gp_Pnt P = BRep_Tool::Pnt(V);
595 double dist = P1.Distance(P);
602 for (exp.Init(S2, TopAbs_VERTEX); exp.More(); exp.Next()) {
603 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
604 gp_Pnt P = BRep_Tool::Pnt(V);
605 double dist = P2.Distance(P);
612 //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
613 //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
614 //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
615 //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
616 //cout<<" P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
617 //cout<<" P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
619 // replace vertexes if it is needed
620 if (!V1.IsSame(V1new)) {
622 P1 = BRep_Tool::Pnt(V1);
623 MESSAGE (" replace V1");
626 MESSAGE (" not replace V1");
627 if (!V2.IsSame(V2new)) {
629 P2 = BRep_Tool::Pnt(V2);
630 MESSAGE (" replace V2");
633 MESSAGE (" not replace V2");
635 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
636 TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
637 TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
638 TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
640 if (!aMapVertFaces1.Contains(V1))
641 MESSAGE (" FindFirstPairFaces: map aMapVertFaces1 not contains key V1");
642 const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
643 TopTools_ListIteratorOfListOfShape anIter1(aList1);
644 FS1 = anIter1.Value();
646 double x1=0., y1=0., z1=0.;
648 for (exp.Init(FS1, TopAbs_VERTEX); exp.More(); exp.Next()) {
649 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
650 gp_Pnt P = BRep_Tool::Pnt(V);
656 gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
658 TColgp_SequenceOfPnt Ps;
659 TopTools_SequenceOfShape Fs;
660 if (!aMapVertFaces2.Contains(V2))
661 MESSAGE (" FindFirstPairFaces: map aMapVertFaces2 not contains key V2");
662 const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
663 TopTools_ListIteratorOfListOfShape anIter2(aList2);
664 for (; anIter2.More(); anIter2.Next()) {
665 TopoDS_Shape F = anIter2.Value();
666 double x2=0., y2=0., z2=0.;
668 for (exp.Init(F, TopAbs_VERTEX); exp.More(); exp.Next()) {
669 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
670 gp_Pnt P = BRep_Tool::Pnt(V);
676 gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
683 double MinAng = M_PI;
685 for (; i<=Fs.Length(); i++) {
686 gp_Vec tmpDir(PM1,Ps(i));
687 double ang = fabs(aDir.Angle(tmpDir));
696 //=======================================================================
697 //function : RemoveFaces
698 //purpose : This function returns theShapeFrom without faces of the shape
699 // theFacesToRm. It returns a shell if theShapeFrom is a solid or
700 // a compound otherwise. Auxilary for CreatePipeWithDifferentSections
702 //=======================================================================
703 static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom,
704 const TopoDS_Shape &theFacesToRm)
706 TopTools_IndexedMapOfShape aMapFaces;
707 TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE);
708 BRep_Builder aBuilder;
709 TopoDS_Shape aResult;
711 if (theShapeFrom.ShapeType() == TopAbs_SOLID) {
713 aBuilder.MakeShell(TopoDS::Shell(aResult));
716 aBuilder.MakeCompound(TopoDS::Compound(aResult));
719 TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces);
721 for (; anExp.More(); anExp.Next()) {
722 const TopoDS_Shape &aFace = anExp.Current();
724 if (!aMapFaces.Contains(aFace)) {
725 aBuilder.Add(aResult, aFace);
732 //=======================================================================
733 //function : CreatePipeWithDifferentSections
735 //=======================================================================
736 TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
737 (const TopoDS_Wire &theWirePath,
738 const Handle(TopTools_HSequenceOfShape) theHSeqBases,
739 const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
740 const Standard_Boolean theWithContact,
741 const Standard_Boolean theWithCorrect,
742 const Standard_Boolean IsBySteps,
743 Handle(TColStd_HArray1OfInteger) *theGroups)
747 TopoDS_Wire aWirePath = theWirePath;
749 Standard_Integer nbBases = theHSeqBases->Length();
750 Standard_Integer nbLocs = (theHSeqLocs.IsNull() ? 0 : theHSeqLocs->Length());
752 if (nbLocs && nbLocs != nbBases) {
753 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
756 TopTools_SequenceOfShape aSeqBases;
757 TopTools_SequenceOfShape aSeqLocs;
758 TopTools_SequenceOfShape aSeqFaces;
759 Standard_Boolean NeedCreateSolid = Standard_False;
761 Standard_Integer i = 1;
762 for (i = 1; i <= nbBases; i++) {
763 if (theHSeqBases->Value(i).IsNull())
766 // Make copy to prevent modifying of base object 0020766 : EDF 1320
767 TopoDS_Shape aShapeBase;
768 BRepBuilderAPI_Copy Copy (theHSeqBases->Value(i));
770 aShapeBase = Copy.Shape();
772 TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
774 //if for section was specified face with a few wires then a few
775 // pipes were build and make solid
776 if (aTypeBase == TopAbs_SHELL) {
777 // create wire as boundary contour if shell is no closed
778 // get free boundary shapes
779 ShapeAnalysis_FreeBounds anAnalizer(aShapeBase);
780 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
781 TopExp_Explorer anExp;
783 Standard_Integer NbWires = 0;
784 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
786 aWire = anExp.Current();
790 Standard_ConstructionError::Raise("Bad shell is used as section ");
792 NeedCreateSolid = Standard_True;
793 aSeqFaces.Append(aShapeBase);
794 aSeqBases.Append(aWire);
796 else if (aTypeBase == TopAbs_FACE) {
797 NeedCreateSolid = Standard_True;
798 //for case one path should be used other type function
799 aSeqFaces.Append(aShapeBase);
800 TopExp_Explorer aExpW(aShapeBase,TopAbs_WIRE);
801 for (; aExpW.More(); aExpW.Next()) {
802 TopoDS_Shape aWireProf = aExpW.Current();
803 aSeqBases.Append(aWireProf);
806 else if (aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
807 aSeqBases.Append(aShapeBase);
809 else if (aTypeBase == TopAbs_EDGE) {
810 TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
811 TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
812 aSeqBases.Append(aWireProf);
815 TopoDS_Shape aShapeLoc = theHSeqLocs->Value(i);
816 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
818 aSeqLocs.Append(aShapeLoc);
822 nbLocs = aSeqLocs.Length();
825 TopTools_SequenceOfShape Edges;
827 // we have to check that each location shape is a vertex from
828 // path and update aSeqLocs if it is needed (and possible)
829 TColgp_SequenceOfPnt PLocs;
830 for (i=1; i<=nbLocs; i++) {
831 TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
832 PLocs.Append(BRep_Tool::Pnt(V));
834 //TopTools_SequenceOfShape Edges;
835 TopExp_Explorer anExp;
836 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
837 Edges.Append(anExp.Current());
839 int nbEdges = Edges.Length();
840 ShapeAnalysis_Edge sae;
841 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
842 double tol = BRep_Tool::Tolerance(edge);
843 TopoDS_Vertex VF = sae.FirstVertex(edge);
844 gp_Pnt PF = BRep_Tool::Pnt(VF);
845 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
846 if (PF.Distance(PLocs.First()) > tol) {
847 Standard_ConstructionError::Raise
848 ("First location shapes is not coincided with first vertex of aWirePath");
850 aSeqLocs.ChangeValue(1) = VF;
851 edge = TopoDS::Edge(Edges.Last());
852 tol = BRep_Tool::Tolerance(edge);
853 TopoDS_Vertex VL = sae.LastVertex(edge);
854 gp_Pnt PL = BRep_Tool::Pnt(VL);
855 if (PL.Distance(PLocs.Last()) > tol) {
856 Standard_ConstructionError::Raise
857 ("Last location shapes is not coincided with last vertex of aWirePath");
859 aSeqLocs.ChangeValue(nbLocs) = VL;
861 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
862 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
863 tol = BRep_Tool::Tolerance(edge);
864 TopoDS_Vertex V1 = sae.FirstVertex(E);
865 TopoDS_Vertex V2 = sae.LastVertex(E);
866 gp_Pnt P1 = BRep_Tool::Pnt(V1);
867 gp_Pnt P2 = BRep_Tool::Pnt(V2);
868 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
869 aSeqLocs.ChangeValue(jcurr) = V2;
873 // find distance between E and aLocs(jcurr)
875 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
876 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
877 if (PPCurve.NbPoints()>0 &&
878 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
879 double param = PPCurve.Parameter(1);
882 // split current edge
883 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
884 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
889 if (Pfp.Distance(P1)<tol) {
890 B.MakeEdge(E1,tc1,tol);
892 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
893 B.Add(E1,TopoDS::Vertex(tmpV));
894 B.MakeEdge(E2,tc2,tol);
895 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
896 B.Add(E2,TopoDS::Vertex(tmpV));
900 B.MakeEdge(E1,tc2,tol);
901 TopoDS_Shape tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
902 B.Add(E1,TopoDS::Vertex(tmpV));
905 B.MakeEdge(E2,tc1,tol);
907 tmpV = aSeqLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
908 B.Add(E2,TopoDS::Vertex(tmpV));
913 Edges.InsertAfter(i-1,E1);
914 Edges.InsertAfter(i,E2);
918 if (nbEdges<Edges.Length()) {
919 // one of edges was splitted => we have to update WirePath
923 for (i=1; i<=Edges.Length(); i++) {
924 B.Add(W,TopoDS::Edge(Edges.Value(i)));
930 TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
933 // Fill SplitEdgeNums and SplitLocNums with intermediate location indices
934 // and corresponding edge indices.
935 Standard_Integer i = 1;
940 for (j = 2; j < aSeqLocs.Length(); j++) {
941 SplitLocNums.Append(j);
942 aVert = TopoDS::Vertex(aSeqLocs.Value(j));
943 aP = BRep_Tool::Pnt(aVert);
945 while (i < Edges.Length()) {
948 TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i));
949 Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
950 Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp);
956 if (aP.Distance(aPLast) < aTol) {
957 SplitEdgeNums.Append(i - 1);
963 // check curvature of wire for condition that
964 // max summary angle between directions along
965 // wire path must be < 4*PI. If not - split wire
966 // and seguences of shapes, perform pipe for each
967 // and make sewing after that
972 if ( Edges.Length() > 0 ) {
973 Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
976 SumAng = fabs(Vec1.Angle(Vec2));
981 //cout<<"Edges.Length()="<<Edges.Length()<<endl;
982 for (i=2; i<=Edges.Length(); i++) {
983 TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
984 double tol = BRep_Tool::Tolerance(edge);
985 Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
987 double ang = fabs(Vec1.Angle(Vec2));
991 SplitEdgeNums.Append(i-1);
993 for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
994 TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
995 gp_Pnt P = BRep_Tool::Pnt(aVert);
996 if (P1.Distance(P) < tol) {
997 SplitLocNums.Append(j);
1008 bool isCreateGroups = (theGroups != NULL);
1010 if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
1011 TopTools_SequenceOfShape aSeqRes;
1012 TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
1013 Standard_Integer iGrp;
1014 int nn, num1 = 1, num2 = 1;
1015 for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
1016 // create wirepath and sequences of shapes
1020 for (i=num1; i<=SplitEdgeNums.Value(nn); i++) {
1021 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1023 num1 = SplitEdgeNums.Value(nn) + 1;
1024 TopTools_SequenceOfShape aTmpSeqBases;
1025 TopTools_SequenceOfShape aTmpSeqLocs;
1026 for (i=num2; i<=SplitLocNums.Value(nn); i++) {
1027 aTmpSeqBases.Append(aSeqBases.Value(i));
1028 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1030 num2 = SplitLocNums.Value(nn);
1032 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1033 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1034 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1035 aBuilder.SetDiscreteMode();
1036 Standard_Integer nbShapes = aTmpSeqBases.Length();
1037 for (i=1; i<=nbShapes; i++) {
1038 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1039 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1040 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1042 if (!aBuilder.IsReady()) {
1043 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1046 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1048 if (isDone && NeedCreateSolid && nn == 1) {
1049 // Make solid for the first step.
1050 isDone = aBuilder.MakeSolid();
1054 Standard_ConstructionError::Raise("Pipe construction failure");
1057 TopoDS_Shape resShape = aBuilder.Shape();
1059 if (NeedCreateSolid && nn == 1) {
1060 // Remove top lid from the result.
1061 resShape = RemoveFaces(resShape, aBuilder.LastShape());
1064 aSeqRes.Append(resShape);
1067 if (isCreateGroups) {
1069 TopTools_SequenceOfShape aGroups[5];
1071 if (!DoGroups(aBuilder, aGroups)) {
1072 Standard_ConstructionError::Raise("Generate groups failure");
1075 // Get shapes from all groups.
1076 for (iGrp = 0; iGrp < 5; ++iGrp) {
1077 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1081 // create wirepath and sequences of shapes for last part
1085 for (i=num1; i<=Edges.Length(); i++) {
1086 B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
1088 TopTools_SequenceOfShape aTmpSeqBases;
1089 TopTools_SequenceOfShape aTmpSeqLocs;
1090 for (i=num2; i<=aSeqLocs.Length(); i++) {
1091 aTmpSeqBases.Append(aSeqBases.Value(i));
1092 aTmpSeqLocs.Append(aSeqLocs.Value(i));
1094 // make pipe for last part
1095 BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
1096 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(tmpW);
1097 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1098 aBuilder.SetDiscreteMode();
1099 Standard_Integer nbShapes = aTmpSeqBases.Length();
1100 for (i=1; i<=nbShapes; i++) {
1101 TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
1102 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1103 aBuilder.Add(aTmpSeqBases.Value(i), aVert, theWithContact, theWithCorrect);
1105 if (!aBuilder.IsReady()) {
1106 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1109 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1111 if (isDone && NeedCreateSolid) {
1112 isDone = aBuilder.MakeSolid();
1116 Standard_ConstructionError::Raise("Pipe construction failure");
1119 TopoDS_Shape resShape = aBuilder.Shape();
1121 if (NeedCreateSolid) {
1122 // Remove bottom lid from the result.
1123 resShape = RemoveFaces(resShape, aBuilder.FirstShape());
1126 aSeqRes.Append(resShape);
1129 if (isCreateGroups) {
1131 TopTools_SequenceOfShape aGroups[5];
1133 if (!DoGroups(aBuilder, aGroups)) {
1134 Standard_ConstructionError::Raise("Generate groups failure");
1137 // Get shapes from all groups.
1138 for (iGrp = 0; iGrp < 5; ++iGrp) {
1139 aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
1143 // make sewing for result
1144 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1145 aSewing->SetTolerance(Precision::Confusion());
1146 aSewing->SetFaceMode(Standard_True);
1147 aSewing->SetFloatingEdgesMode(Standard_False);
1148 aSewing->SetNonManifoldMode(Standard_False);
1149 for (i=1; i<=aSeqRes.Length(); i++) {
1150 aSewing->Add(aSeqRes.Value(i));
1153 aShape = aSewing->SewedShape();
1155 if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) {
1157 BRepBuilderAPI_MakeSolid aMkSolid;
1159 aMkSolid.Add(TopoDS::Shell(aShape));
1161 if (!aMkSolid.IsDone()) {
1162 Standard_ConstructionError::Raise("Can't create solid pipe");
1165 TopoDS_Solid aSolid = aMkSolid.Solid();
1166 BRepClass3d_SolidClassifier aSC(aSolid);
1168 aSC.PerformInfinitePoint(Precision::Confusion());
1170 if (aSC.State() == TopAbs_IN) {
1171 aShape = aSolid.Reversed();
1177 if (isCreateGroups) {
1178 // Replase Group shapes by modified ones.
1179 TopTools_SequenceOfShape aSeqGroups[5];
1182 for (iGrp = 0; iGrp < 5; ++iGrp) {
1184 for (i = 1; i <= aSeqRes.Length(); ++i) {
1185 if (iGrp == GROUP_DOWN && i > 1) {
1186 // For DOWN group we use only the first pipe.
1190 if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
1191 // For UP group we use only the last pipe.
1195 const TopTools_SequenceOfShape &aShapes =
1196 aMapResGroups[iGrp].Find(aSeqRes.Value(i));
1199 // For each sub-shape of pipe
1200 for (j = 1; j <= aShapes.Length(); ++j) {
1201 const TopoDS_Shape &aGrpShape = aShapes.Value(j);
1203 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1204 // Use the shape modified by sewing.
1205 const TopoDS_Shape &aModifGrpShape =
1206 aSewing->ModifiedSubShape(aGrpShape);
1208 aSeqGroups[iGrp].Append(aModifGrpShape);
1210 // Use the shape as it is.
1211 aSeqGroups[iGrp].Append(aGrpShape);
1218 TopTools_IndexedMapOfShape anIndices;
1220 TopExp::MapShapes(aShape, anIndices);
1222 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1223 Standard_ConstructionError::Raise("Generate groups failure");
1228 // old implementation without splitting
1229 BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1230 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
1231 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1232 aBuilder.SetDiscreteMode();
1234 Standard_Integer nbShapes = aSeqBases.Length();
1235 Standard_Integer step = nbShapes/nbBases;
1237 if (nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
1238 Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
1240 Standard_Integer ind =0;
1241 Standard_Real aTolConf = Precision::Confusion();
1242 Standard_Real aTolAng = Precision::Angular();
1244 for (i = 1; i <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
1245 TopTools_SequenceOfShape usedBases;
1246 Standard_Integer j = 1;
1247 for (; j <= nbBases; j++) {
1248 ind = i + (j-1)*step;
1249 TopoDS_Shape aWireProf = aSeqBases.Value(ind);
1250 usedBases.Append(aWireProf);
1252 TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
1253 TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
1254 aBuilder.Add(aWireProf, aVert, theWithContact, theWithCorrect);
1257 aBuilder.Add(aWireProf, theWithContact, theWithCorrect);
1259 if (!aBuilder.IsReady()) {
1260 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1263 aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
1265 Standard_Boolean isDone = BuildPipeShell(aBuilder);
1267 if (isDone && NeedCreateSolid) {
1268 isDone = aBuilder.MakeSolid();
1272 Standard_ConstructionError::Raise("Pipe construction failure");
1274 aShape = aBuilder.Shape();
1276 if (isCreateGroups) {
1278 TopTools_SequenceOfShape aSeqGroups[5];
1280 if (!DoGroups(aBuilder, aSeqGroups)) {
1281 Standard_ConstructionError::Raise("Generate groups failure");
1285 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
1286 TopTools_IndexedMapOfShape anIndices;
1287 const TopoDS_Shape aResult = aBuilder.Shape();
1289 TopExp::MapShapes(aResult, anIndices);
1291 if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
1292 Standard_ConstructionError::Raise("Generate groups failure");
1295 aSeqFaces.Append(aShape);
1296 for (j = 1; j <=usedBases.Length(); j++)
1297 aBuilder.Delete(usedBases.Value(j));
1304 //=======================================================================
1305 //function : CreatePipeForShellSections
1306 //purpose : auxilary for Execute()
1307 //=======================================================================
1308 static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
1309 GEOMImpl_IPipe* aCI)
1314 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
1315 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
1316 Handle(TColStd_HSequenceOfTransient) aSubBasesObjs = aCIDS->GetSubBases();
1317 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
1318 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
1319 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
1320 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
1322 Standard_Integer nbBases = aBasesObjs->Length(),
1323 nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
1324 nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
1326 if (nbLocs != nbBases) {
1327 if (aCI) delete aCI;
1328 Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
1330 if (nbSubBases && nbSubBases != nbBases) {
1331 if (aCI) delete aCI;
1332 Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
1335 TopTools_SequenceOfShape VLocs;
1336 for (i=1; i<=nbBases; i++) {
1337 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
1338 if (anItemLoc.IsNull())
1340 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
1341 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
1342 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
1344 VLocs.Append(aShapeLoc);
1346 nbLocs = VLocs.Length();
1347 if (nbLocs != nbBases) {
1348 if (aCI) delete aCI;
1349 Standard_ConstructionError::Raise("One of location shapes is not a vertex");
1351 // split wire path by location points
1352 TColgp_SequenceOfPnt PLocs;
1353 for (i=1; i<=nbLocs; i++) {
1354 TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
1355 PLocs.Append(BRep_Tool::Pnt(V));
1358 TopTools_SequenceOfShape Edges;
1359 TopTools_SequenceOfShape Wires;
1360 ShapeAnalysis_Edge sae;
1363 TopExp_Explorer anExp;
1364 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1365 Edges.Append(anExp.Current());
1367 Standard_Integer Num1 = 0;
1368 Standard_Integer Num2 = 0;
1369 for (i=1; i<=Edges.Length(); i++) {
1370 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1371 double tol = BRep_Tool::Tolerance(E);
1372 TopoDS_Vertex V1 = sae.FirstVertex(E);
1373 TopoDS_Vertex V2 = sae.LastVertex(E);
1374 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1375 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1376 if (P1.Distance(PLocs.First()) < tol) {
1379 if (P2.Distance(PLocs.Last()) < tol) {
1383 if (Num1>0 && Num2>0) {
1386 for (i=Num1; i<=Num2; i++) {
1387 B.Add(W,Edges.Value(i));
1392 Wires.Append(aWirePath);
1396 TopExp_Explorer anExp;
1397 for (anExp.Init(aWirePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1398 Edges.Append(anExp.Current());
1400 TopoDS_Edge edge = TopoDS::Edge(Edges.First());
1401 double tol = BRep_Tool::Tolerance(edge);
1402 TopoDS_Vertex VF = sae.FirstVertex(edge);
1403 gp_Pnt PF = BRep_Tool::Pnt(VF);
1404 //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
1405 if (PF.Distance(PLocs.First()) > tol) {
1406 if (aCI) delete aCI;
1407 Standard_ConstructionError::Raise
1408 ("First location shapes is not coincided with first vertex of aWirePath");
1410 VLocs.ChangeValue(1) = VF;
1411 edge = TopoDS::Edge(Edges.Last());
1412 tol = BRep_Tool::Tolerance(edge);
1413 TopoDS_Vertex VL = sae.LastVertex(edge);
1414 gp_Pnt PL = BRep_Tool::Pnt(VL);
1415 if (PL.Distance(PLocs.Last()) > tol) {
1416 if (aCI) delete aCI;
1417 Standard_ConstructionError::Raise
1418 ("Last location shapes is not coincided with last vertex of aWirePath");
1420 VLocs.ChangeValue(nbLocs) = VL;
1422 TopTools_SequenceOfShape tmpEdges;
1423 for (i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
1424 TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
1425 tol = BRep_Tool::Tolerance(E);
1426 TopoDS_Vertex V1 = sae.FirstVertex(E);
1427 TopoDS_Vertex V2 = sae.LastVertex(E);
1428 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1429 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1430 if (P2.Distance(PLocs.Value(jcurr)) < tol) {
1431 // make wire from current edge and add created
1435 for (j=1; j<=tmpEdges.Length(); j++)
1436 B.Add(W,tmpEdges.Value(j));
1439 VLocs.ChangeValue(jcurr) = V2;
1444 // find distance between E and aLocs(jcurr)
1446 Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
1447 GeomAPI_ProjectPointOnCurve PPCurve (PLocs.Value(jcurr),C);
1448 if (PPCurve.NbPoints()>0 &&
1449 PLocs.Value(jcurr).Distance(PPCurve.Point(1)) < tol) {
1450 double param = PPCurve.Parameter(1);
1453 // split current edge
1454 Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
1455 Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
1459 if (Pfp.Distance(P1)<tol) {
1460 B.MakeEdge(E1,tc1,tol);
1462 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1463 B.Add(E1,TopoDS::Vertex(tmpV));
1464 tmpEdges.Append(E1);
1465 B.MakeEdge(E2,tc2,tol);
1466 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1467 B.Add(E2,TopoDS::Vertex(tmpV));
1471 B.MakeEdge(E1,tc2,tol);
1472 TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
1473 B.Add(E1,TopoDS::Vertex(tmpV));
1476 tmpEdges.Append(E1);
1477 B.MakeEdge(E2,tc1,tol);
1479 tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
1480 B.Add(E2,TopoDS::Vertex(tmpV));
1483 // create wire from tmpEdges
1486 for (j=1; j<=tmpEdges.Length(); j++)
1487 B.Add(W,tmpEdges.Value(j));
1492 Edges.InsertAfter(i-1,E1);
1493 Edges.InsertAfter(i,E2);
1500 // create wire from other edges
1503 for (; i<=Edges.Length(); i++)
1504 B.Add(W,Edges.Value(i));
1508 if (Wires.Length() != nbLocs-1) {
1509 if (aCI) delete aCI;
1510 Standard_ConstructionError::Raise
1511 ("One of location shapes is not lied on the path");
1514 TopTools_SequenceOfShape aGroups[5];
1515 TopoDS_Compound aComp;
1516 B.MakeCompound(aComp);
1517 for (i = 1; i < nbBases; i++) {
1518 TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
1520 Handle(Standard_Transient) anItem1 = aBasesObjs->Value(i);
1521 if (anItem1.IsNull())
1523 Handle(GEOM_Function) aRefBase1 = Handle(GEOM_Function)::DownCast(anItem1);
1524 if (aRefBase1.IsNull())
1526 TopoDS_Shape aShBase1 = aRefBase1->GetValue();
1527 if (aShBase1.IsNull())
1529 TopAbs_ShapeEnum aType1 = aShBase1.ShapeType();
1531 Handle(Standard_Transient) anItem2 = aBasesObjs->Value(i+1);
1532 if (anItem2.IsNull())
1534 Handle(GEOM_Function) aRefBase2 = Handle(GEOM_Function)::DownCast(anItem2);
1535 if (aRefBase2.IsNull())
1537 TopoDS_Shape aShBase2 = aRefBase2->GetValue();
1538 if (aShBase2.IsNull())
1540 TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
1542 bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
1543 (aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
1545 if (aCI) delete aCI;
1546 Standard_ConstructionError::Raise("One of section shapes has invalid type");
1549 bool CreateFewSolids = false;
1551 TopExp_Explorer anExp;
1552 Standard_Integer nbf1 = 0;
1553 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1556 Standard_Integer nbf2 = 0;
1557 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1561 CreateFewSolids = true;
1564 if (!CreateFewSolids) {
1565 // we can create only one solid
1566 TopoDS_Shape aWire1, aWire2;
1568 if (aType1==TopAbs_SHELL) {
1569 // create wire as boundary contour if shell is no closed
1570 // get free boundary shapes
1571 ShapeAnalysis_FreeBounds anAnalizer(aShBase1);
1572 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1573 //TopExp_Explorer anExp;
1574 Standard_Integer NbWires = 0;
1575 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1577 aWire1 = anExp.Current();
1581 if (aCI) delete aCI;
1582 Standard_ConstructionError::Raise("Bad shell is used as section ");
1585 else { // aType1==TopAbs_FACE
1586 TopExp_Explorer aExpW(aShBase1,TopAbs_WIRE);
1587 aWire1 = aExpW.Current();
1590 if (aType2==TopAbs_SHELL) {
1591 // create wire as boundary contour if shell is no closed
1592 // get free boundary shapes
1593 ShapeAnalysis_FreeBounds anAnalizer(aShBase2);
1594 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
1595 //TopExp_Explorer anExp;
1596 Standard_Integer NbWires = 0;
1597 for (anExp.Init(aClosed, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1599 aWire2 = anExp.Current();
1603 if (aCI) delete aCI;
1604 Standard_ConstructionError::Raise("Bad shell is used as section ");
1607 else { // aType2==TopAbs_FACE
1608 TopExp_Explorer aExpW(aShBase2,TopAbs_WIRE);
1609 aWire2 = aExpW.Current();
1611 // make pipe using aWire1 and aWire2
1612 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1613 //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
1614 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1615 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1616 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1617 aBuilder.SetDiscreteMode();
1618 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1619 aWithContact, aWithCorrect);
1620 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1621 aWithContact, aWithCorrect);
1622 if (!aBuilder.IsReady()) {
1623 if (aCI) delete aCI;
1624 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1627 BuildPipeShell(aBuilder);
1629 TopoDS_Shape aShape = aBuilder.Shape();
1630 TopTools_SequenceOfShape aLocalGroups[5];
1633 if (isGenerateGroups) {
1635 if (!DoGroups(aBuilder, aLocalGroups)) {
1636 if (aCI) delete aCI;
1637 Standard_ConstructionError::Raise("Generate groups failure");
1640 // Clear the groups Down and Up.
1641 aLocalGroups[GROUP_DOWN].Clear();
1642 aLocalGroups[GROUP_UP].Clear();
1645 TopoDS_Shell aShell;
1646 B.MakeShell(aShell);
1647 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1648 B.Add(aShell,anExp.Current());
1650 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1651 B.Add(aShell,anExp.Current());
1653 if (isGenerateGroups && i == 1) {
1654 aLocalGroups[GROUP_DOWN].Append(anExp.Current());
1657 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1658 B.Add(aShell,anExp.Current());
1660 if (isGenerateGroups && i == nbBases - 1) {
1661 aLocalGroups[GROUP_UP].Append(anExp.Current());
1664 // make sewing for this shell
1665 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1666 aSewing->SetTolerance(Precision::Confusion());
1667 aSewing->SetFaceMode(Standard_True);
1668 aSewing->SetFloatingEdgesMode(Standard_False);
1669 aSewing->SetNonManifoldMode(Standard_False);
1670 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1671 aSewing->Add(anExp.Current());
1674 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1675 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1676 aShell = TopoDS::Shell(aSewShape);
1677 GProp_GProps aSystem;
1678 BRepGProp::VolumeProperties(aShell, aSystem);
1679 if (aSystem.Mass()<0) {
1682 if (BRep_Tool::IsClosed(aShell)) {
1683 TopoDS_Solid aSolid;
1684 B.MakeSolid(aSolid);
1685 B.Add(aSolid,aShell);
1686 B.Add(aComp,aSolid);
1689 B.Add(aComp,aShell);
1693 B.Add(aComp,aShell);
1696 if (isGenerateGroups) {
1697 Standard_Integer iGrp;
1699 for (iGrp = 0; iGrp < 5; ++iGrp) {
1702 // For each sub-shape of pipe
1703 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1704 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1706 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1707 // Use the shape modified by sewing.
1708 const TopoDS_Shape &aModifGrpShape =
1709 aSewing->ModifiedSubShape(aGrpShape);
1711 aGroups[iGrp].Append(aModifGrpShape);
1713 // Use the shape as it is.
1714 aGroups[iGrp].Append(aGrpShape);
1722 // main block - creation few solids (for each pair of faces)
1723 TopTools_MapOfShape aFaces1,aFaces2;
1724 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
1725 aFaces1.Add(anExp.Current());
1727 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
1728 aFaces2.Add(anExp.Current());
1730 // creating map of edge faces
1731 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
1732 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
1733 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
1734 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
1736 // constuct map face->face
1737 TopTools_IndexedDataMapOfShapeShape FF;
1738 TopoDS_Shape FS1,FS2;
1739 if (nbSubBases==0) {
1740 // find edge the most distant from location point
1741 // (this edge is not shared by two faces)
1742 double maxdist = 0.;
1744 TopoDS_Vertex V11,V21;
1745 for (j=1; j<=aMapEdgeFaces1.Extent(); j++) {
1746 TopoDS_Shape tmp = aMapEdgeFaces1.FindKey(j);
1747 const TopTools_ListOfShape& aList = aMapEdgeFaces1.FindFromKey(tmp);
1748 if (aList.Extent()>1)
1750 TopExp_Explorer expv;
1751 expv.Init(tmp, TopAbs_VERTEX);
1752 TopoDS_Vertex V1 = TopoDS::Vertex(expv.Current());
1754 TopoDS_Vertex V2 = TopoDS::Vertex(expv.Current());
1755 gp_Pnt P1 = BRep_Tool::Pnt(V1);
1756 gp_Pnt P2 = BRep_Tool::Pnt(V2);
1757 double dist = PLocs.Value(i).Distance(P1) + PLocs.Value(i).Distance(P2);
1762 TopTools_ListIteratorOfListOfShape anIter(aList);
1763 FS1 = anIter.Value();
1767 // main direction for comparing
1768 gp_Vec VM(PLocs.Value(i),PLocs.Value(i+1));
1769 // find corresponding edge from next section
1770 double minang = M_PI;
1771 gp_Pnt P11 = BRep_Tool::Pnt(V11);
1772 gp_Pnt P21 = BRep_Tool::Pnt(V21);
1774 TopoDS_Vertex V12,V22;
1775 for (j=1; j<=aMapEdgeFaces2.Extent(); j++) {
1776 TopoDS_Shape tmp = aMapEdgeFaces2.FindKey(j);
1777 const TopTools_ListOfShape& aList = aMapEdgeFaces2.FindFromKey(tmp);
1778 if (aList.Extent()>1)
1780 TopExp_Explorer expv;
1781 expv.Init(tmp, TopAbs_VERTEX);
1782 TopoDS_Vertex V1tmp = TopoDS::Vertex(expv.Current());
1784 TopoDS_Vertex V2tmp = TopoDS::Vertex(expv.Current());
1785 gp_Pnt P1tmp = BRep_Tool::Pnt(V1tmp);
1786 gp_Pnt P2tmp = BRep_Tool::Pnt(V2tmp);
1787 double d1 = P1tmp.Distance(P11) + P2tmp.Distance(P21);
1788 double d2 = P1tmp.Distance(P21) + P2tmp.Distance(P11);
1789 TopoDS_Vertex V1,V2;
1792 V1 = V2tmp; P1 = P2tmp;
1793 V2 = V1tmp; P2 = P1tmp;
1796 V1 = V1tmp; P1 = P1tmp;
1797 V2 = V2tmp; P2 = P2tmp;
1799 gp_Vec Vec1(P11,P1);
1800 gp_Vec Vec2(P21,P2);
1801 double ang = fabs(Vec1.Angle(VM)) + fabs(Vec2.Angle(VM));
1806 TopTools_ListIteratorOfListOfShape anIter(aList);
1807 FS2 = anIter.Value();
1811 // put all pairs to map FF
1817 // add pairs of edges to FF
1818 bool stat = FillForOtherEdges(FS1,E1,V11,FF);
1820 if (aCI) delete aCI;
1821 Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
1827 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i);
1828 if (anItem.IsNull()) {
1829 if (aCI) delete aCI;
1830 Standard_ConstructionError::Raise("Invalid subbase shape");
1832 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1833 if (aRefBase.IsNull()) {
1834 if (aCI) delete aCI;
1835 Standard_ConstructionError::Raise("Invalid subbase shape");
1837 TopoDS_Shape aSh = aRefBase->GetValue();
1839 if (aCI) delete aCI;
1840 Standard_ConstructionError::Raise("Invalid subbase shape");
1842 if (aSh.ShapeType()!=TopAbs_FACE) {
1843 if (aCI) delete aCI;
1844 Standard_ConstructionError::Raise("Invalid subbase shape");
1849 Handle(Standard_Transient) anItem = aSubBasesObjs->Value(i+1);
1850 if (anItem.IsNull()) {
1851 if (aCI) delete aCI;
1852 Standard_ConstructionError::Raise("Invalid subbase shape");
1854 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
1855 if (aRefBase.IsNull()) {
1856 if (aCI) delete aCI;
1857 Standard_ConstructionError::Raise("Invalid subbase shape");
1859 TopoDS_Shape aSh = aRefBase->GetValue();
1861 if (aCI) delete aCI;
1862 Standard_ConstructionError::Raise("Invalid subbase shape");
1864 if (aSh.ShapeType()!=TopAbs_FACE) {
1865 if (aCI) delete aCI;
1866 Standard_ConstructionError::Raise("Invalid subbase shape");
1871 if (!aFaces1.Contains(FS1) || !aFaces2.Contains(FS2)) {
1872 if (aCI) delete aCI;
1873 Standard_ConstructionError::Raise("Invalid subbase shape");
1878 // add pairs of edges to FF
1879 bool stat = FillCorrespondingEdges(FS1, FS2, TopoDS::Vertex(VLocs(i)),
1880 TopoDS::Vertex(VLocs(i+1)), WPath, FF);
1882 if (aCI) delete aCI;
1883 Standard_ConstructionError::Raise("Can not create correct pipe");
1887 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
1889 // make pipe for each pair of faces
1890 for (j=1; j<=FF.Extent(); j++) {
1891 TopoDS_Shape F1 = FF.FindKey(j);
1892 if (F1.ShapeType() != TopAbs_FACE)
1894 TopoDS_Shape F2 = FF.FindFromIndex(j);
1895 TopExp_Explorer aExpW1(F1,TopAbs_WIRE);
1896 TopoDS_Wire aWire1 = TopoDS::Wire(aExpW1.Current());
1897 TopExp_Explorer aExpW2(F2,TopAbs_WIRE);
1898 TopoDS_Wire aWire2 = TopoDS::Wire(aExpW2.Current());
1899 // make pipe using aWire1 and aWire2
1900 if (!aWire1.IsNull() && !aWire2.IsNull()) {
1901 BRepOffsetAPI_MakePipeShell aBuilder(WPath);
1902 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(WPath);
1903 if (theBestMode == GeomFill_IsDiscreteTrihedron)
1904 aBuilder.SetDiscreteMode();
1905 aBuilder.Add(aWire1, TopoDS::Vertex(VLocs(i)),
1906 aWithContact, aWithCorrect);
1907 aBuilder.Add(aWire2, TopoDS::Vertex(VLocs(i+1)),
1908 aWithContact, aWithCorrect);
1909 if (!aBuilder.IsReady()) {
1910 if (aCI) delete aCI;
1911 Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
1914 BuildPipeShell(aBuilder);
1916 TopoDS_Shape aShape = aBuilder.Shape();
1917 TopTools_SequenceOfShape aLocalGroups[5];
1920 if (isGenerateGroups) {
1922 if (!DoGroups(aBuilder, aLocalGroups)) {
1923 if (aCI) delete aCI;
1924 Standard_ConstructionError::Raise("Generate groups failure");
1927 // Clear the groups Down and Up.
1928 aLocalGroups[GROUP_DOWN].Clear();
1929 aLocalGroups[GROUP_UP].Clear();
1932 aLocalGroups[GROUP_DOWN].Append(F1);
1935 if (i == nbBases - 1) {
1936 aLocalGroups[GROUP_UP].Append(F2);
1940 TopoDS_Shell aShell;
1941 B.MakeShell(aShell);
1942 for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
1943 B.Add(aShell,anExp.Current());
1948 // make sewing for this shell
1949 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
1950 aSewing->SetTolerance(Precision::Confusion());
1951 aSewing->SetFaceMode(Standard_True);
1952 aSewing->SetFloatingEdgesMode(Standard_False);
1953 aSewing->SetNonManifoldMode(Standard_False);
1954 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
1955 aSewing->Add(anExp.Current());
1958 const TopoDS_Shape aSewShape = aSewing->SewedShape();
1959 if (aSewShape.ShapeType() == TopAbs_SHELL) {
1960 aShell = TopoDS::Shell(aSewShape);
1961 GProp_GProps aSystem;
1962 BRepGProp::VolumeProperties(aShell, aSystem);
1963 if (aSystem.Mass()<0) {
1964 //cout<<"aSewShape is reversed"<<endl;
1967 if (BRep_Tool::IsClosed(aShell)) {
1968 TopoDS_Solid aSolid;
1969 B.MakeSolid(aSolid);
1970 B.Add(aSolid,aShell);
1971 B.Add(aComp,aSolid);
1974 B.Add(aComp,aShell);
1978 B.Add(aComp,aShell);
1981 if (isGenerateGroups) {
1982 // Replase Group shapes by modified ones.
1983 Standard_Integer iGrp;
1986 for (iGrp = 0; iGrp < 5; ++iGrp) {
1989 // For each sub-shape of pipe
1990 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
1991 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
1993 if (aSewing->IsModifiedSubShape(aGrpShape)) {
1994 // Use the shape modified by sewing.
1995 const TopoDS_Shape &aModifGrpShape =
1996 aSewing->ModifiedSubShape(aGrpShape);
1998 aGroups[iGrp].Append(aModifGrpShape);
2000 // Use the shape as it is.
2001 aGroups[iGrp].Append(aGrpShape);
2011 if (isGenerateGroups) {
2013 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2014 TopTools_IndexedMapOfShape anIndices;
2016 TopExp::MapShapes(aComp, anIndices);
2018 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2019 if (aCI) delete aCI;
2020 Standard_ConstructionError::Raise("Generate groups failure");
2023 StoreGroups(aCI, aGroupIds);
2029 //=======================================================================
2030 //function : CreatePipeShellsWithoutPath
2031 //purpose : auxilary for Execute()
2032 //=======================================================================
2033 static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
2035 //cout<<"CreatePipeShellsWithoutPath"<<endl;
2039 GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
2041 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
2042 // vertex for recognition
2043 Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
2044 Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
2046 Standard_Integer nbBases = aBasesObjs->Length(),
2047 nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
2049 if (nbv != nbBases) {
2050 if (aCI) delete aCI;
2051 Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
2054 TopTools_SequenceOfShape aGroups[5];
2055 TopTools_SequenceOfShape SecVs,Bases;
2056 for (i=1; i<=nbBases; i++) {
2058 Handle(Standard_Transient) anItem = VObjs->Value(i);
2059 if (anItem.IsNull())
2061 Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
2062 TopoDS_Shape V = aRef->GetValue();
2063 if (V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
2067 anItem = aBasesObjs->Value(i);
2068 if (anItem.IsNull())
2070 aRef = Handle(GEOM_Function)::DownCast(anItem);
2071 TopoDS_Shape aSh = aRef->GetValue();
2076 nbv = SecVs.Length();
2077 nbBases = Bases.Length();
2078 if (nbv != nbBases) {
2079 if (aCI) delete aCI;
2080 Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
2083 TopoDS_Compound aComp;
2084 B.MakeCompound(aComp);
2086 for (i = 1; i < nbBases; i++) {
2087 MESSAGE ("Make pipe between sections "<<i<<" and "<<i+1);
2088 TopoDS_Shape aShBase1 = Bases.Value(i);
2089 TopoDS_Shape aShBase2 = Bases.Value(i+1);
2090 TopExp_Explorer anExp;
2091 Standard_Integer nbf1 = 0;
2092 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2095 Standard_Integer nbf2 = 0;
2096 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2099 //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
2101 if (aCI) delete aCI;
2102 Standard_ConstructionError::Raise("Different number of faces in the sections");
2105 TopTools_MapOfShape aFaces1,aFaces2;
2106 TopTools_MapOfShape aBndEdges1;
2108 for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
2109 const TopoDS_Shape &aBaseFace1 = anExp.Current();
2111 if (aFaces1.Add(aBaseFace1)) {
2112 // Get boundary edges.
2113 TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
2115 for (; anExpE.More(); anExpE.Next()) {
2116 const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
2118 if (!aBndEdges1.Add(aBaseEdge1)) {
2119 aBndEdges1.Remove(aBaseEdge1);
2124 for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
2125 aFaces2.Add(anExp.Current());
2128 // creating map of edge faces
2129 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
2130 TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
2131 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
2132 TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
2134 // constuct map face->face (and sub-shapes)
2135 TopTools_IndexedDataMapOfShapeShape FF;
2136 //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
2137 TopoDS_Shape FS1, FS2;
2138 TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
2139 TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
2140 FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
2143 MESSAGE (" first pair of corresponding faces is found");
2145 // add pairs of edges and vertexes to FF
2146 bool stat = FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
2148 if (aCI) delete aCI;
2149 Standard_ConstructionError::Raise("Can not create correct pipe");
2151 MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
2153 FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
2154 MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
2156 // make pipe for each pair of faces
2157 // auxilary map vertex->edge for created pipe edges
2158 TopTools_IndexedDataMapOfShapeShape VPE;
2159 ShapeAnalysis_Edge sae;
2160 //cout<<"FF.Extent()="<<FF.Extent()<<endl;
2162 for (j=1; j<=FF.Extent(); j++) {
2163 TopoDS_Shape F1 = FF.FindKey(j);
2164 if (F1.ShapeType() != TopAbs_FACE)
2166 TopoDS_Shape F2 = FF.FindFromIndex(j);
2169 //if (nbff!=3) continue;
2171 MESSAGE (" make pipe for "<<nbff<<" face");
2173 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
2174 if (S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2175 Handle(Geom_RectangularTrimmedSurface) RTS =
2176 Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
2177 S1 = RTS->BasisSurface();
2179 Handle(Geom_Plane) Pln1 = Handle(Geom_Plane)::DownCast(S1);
2180 if (Pln1.IsNull()) {
2181 if (aCI) delete aCI;
2182 Standard_ConstructionError::Raise("Surface from face is not plane");
2184 gp_Vec aDir1(Pln1->Axis().Direction());
2186 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
2187 if (S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2188 Handle(Geom_RectangularTrimmedSurface) RTS =
2189 Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
2190 S2 = RTS->BasisSurface();
2192 Handle(Geom_Plane) Pln2 =
2193 Handle(Geom_Plane)::DownCast(S2);
2194 if (Pln2.IsNull()) {
2195 if (aCI) delete aCI;
2196 Standard_ConstructionError::Raise("Surface from face is not plane");
2198 gp_Vec aDir2(Pln2->Axis().Direction());
2200 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
2201 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
2203 if (fabs(aDir.Angle(aDir1)) > M_PI/2.)
2205 if (fabs(aDir.Angle(aDir2)) > M_PI/2.)
2208 TopExp_Explorer anExpE(F1,TopAbs_EDGE);
2209 TopTools_SequenceOfShape aNewFs;
2210 TopTools_SequenceOfShape aLocalGroups[5];
2213 for (; anExpE.More(); anExpE.Next()) {
2214 TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
2216 if (!FF.Contains(E1))
2217 MESSAGE ("map FF not contains key E1");
2219 if (VPE.Contains(E1)) {
2220 aNewFs.Append(VPE.FindFromKey(E1));
2222 MESSAGE (" using existed face");
2227 TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
2228 TopoDS_Vertex V1 = sae.FirstVertex(E1);
2229 TopoDS_Vertex V2 = sae.LastVertex(E1);
2230 if (!FF.Contains(V1))
2231 MESSAGE ("map FF not contains key V1");
2232 if (!FF.Contains(V2))
2233 MESSAGE ("map FF not contains key V2");
2234 TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
2235 TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
2236 TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
2237 if (Vtmp.IsSame(V4))
2239 gp_Pnt P1 = BRep_Tool::Pnt(V1);
2240 gp_Pnt P2 = BRep_Tool::Pnt(V2);
2241 gp_Pnt P3 = BRep_Tool::Pnt(V3);
2242 gp_Pnt P4 = BRep_Tool::Pnt(V4);
2245 Handle(Geom_BSplineCurve) C2;
2246 if (VPE.Contains(V2)) {
2247 E2 = TopoDS::Edge(VPE.FindFromKey(V2));
2249 C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
2252 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2253 HAP->SetValue(1,P2);
2254 HAP->SetValue(2,P3);
2255 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2256 anInt.Load(aDir1,aDir2);
2259 B.MakeEdge(E2,C2,1.e-7);
2260 B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
2261 B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
2266 Handle(Geom_BSplineCurve) C4;
2267 if (VPE.Contains(V1)) {
2268 E4 = TopoDS::Edge(VPE.FindFromKey(V1));
2270 C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
2273 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2274 HAP->SetValue(1,P1);
2275 HAP->SetValue(2,P4);
2276 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2277 anInt.Load(aDir1,aDir2);
2280 B.MakeEdge(E4,anInt.Curve(),1.e-7);
2281 B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
2282 B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
2291 B.Add(W,E4.Reversed());
2296 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2297 //bool IsConicC1 = false;
2298 //if (C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2299 // IsConicC1 = true;
2300 // cout<<"C1 - Geom_Conic"<<endl;
2302 if (C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic))) {
2303 C1 = new Geom_TrimmedCurve(C1,fp,lp);
2306 // double tol = BRep_Tool::Tolerance(E1);
2307 // GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
2308 // C1 = ApxC1.Curve();
2310 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
2311 if (C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic))) {
2312 C3 = new Geom_TrimmedCurve(C3,fp,lp);
2317 Handle(Geom_BSplineCurve) CE1 =
2318 GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
2319 if (CE1->Degree()<3)
2320 CE1->IncreaseDegree(3);
2321 Handle(Geom_BSplineCurve) CE2 =
2322 GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
2323 if (CE2->Degree()<3)
2324 CE2->IncreaseDegree(3);
2325 Handle(Geom_BSplineCurve) CE3 =
2326 GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
2327 if (CE3->Degree()<3)
2328 CE3->IncreaseDegree(3);
2329 Handle(Geom_BSplineCurve) CE4 =
2330 GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
2331 if (CE4->Degree()<3)
2332 CE4->IncreaseDegree(3);
2334 Handle(Geom_Surface) BS;
2336 GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
2337 //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
2341 MESSAGE (" can not create BSplineSurface - create Bezier");
2343 TColgp_Array2OfPnt Points(1,NbP,1,NbP);
2344 double fp1,lp1,fp2,lp2;
2345 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
2346 Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
2355 // get points from C1
2356 if (P1.Distance(P1C1)<1.e-6) {
2364 double step = (lp-fp)/(NbP-1);
2365 Points.SetValue(1,1,P1);
2367 for (n1=2; n1<NbP; n1++) {
2371 Points.SetValue(1,n1,P);
2373 Points.SetValue(1,NbP,P2);
2374 // get points from C3
2375 if (P4.Distance(P1C3)<1.e-6) {
2383 step = (lp-fp)/(NbP-1);
2384 Points.SetValue(NbP,1,P4);
2386 for (n1=2; n1<NbP; n1++) {
2390 Points.SetValue(NbP,n1,P);
2392 Points.SetValue(NbP,NbP,P3);
2393 // create isolines and get points from them
2394 for (n1=1; n1<=NbP; n1++) {
2395 gp_Pnt PI1 = Points.Value(1,n1);
2396 gp_Pnt PI2 = Points.Value(NbP,n1);
2397 Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
2398 HAP->SetValue(1,PI1);
2399 HAP->SetValue(2,PI2);
2400 GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
2401 anInt.Load(aDir1,aDir2);
2403 Handle(Geom_Curve) iso = anInt.Curve();
2404 fp = iso->FirstParameter();
2405 lp = iso->LastParameter();
2406 step = (lp-fp)/(NbP-1);
2408 TopoDS_Compound VComp;
2409 B.MakeCompound(VComp);
2410 for (n2=2; n2<NbP; n2++) {
2414 Points.SetValue(n2,n1,P);
2417 // create surface and face
2418 //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
2419 BS = new Geom_BezierSurface(Points);
2422 BRepBuilderAPI_MakeFace BB(BS,W);
2423 TopoDS_Face NewF = BB.Face();
2424 Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
2426 sff->FixOrientation();
2427 TopoDS_Face FixedFace = sff->Face();
2428 aNewFs.Append(FixedFace);
2429 VPE.Add(E1,FixedFace);
2431 if (isGenerateGroups) {
2432 if (aBndEdges1.Contains(E1)) {
2433 // This is a boundary face.
2434 aLocalGroups[GROUP_OTHER].Append(FixedFace);
2439 TopoDS_Shell aShell;
2440 B.MakeShell(aShell);
2441 for (int nf=1; nf<=aNewFs.Length(); nf++) {
2442 B.Add(aShell,aNewFs(nf));
2448 if (isGenerateGroups && i == 1) {
2449 aLocalGroups[GROUP_DOWN].Append(F1);
2452 if (isGenerateGroups && i == nbBases - 1) {
2453 aLocalGroups[GROUP_UP].Append(F2);
2456 // make sewing for this shell
2457 Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
2458 aSewing->SetTolerance(Precision::Confusion());
2459 aSewing->SetFaceMode(Standard_True);
2460 aSewing->SetFloatingEdgesMode(Standard_False);
2461 aSewing->SetNonManifoldMode(Standard_False);
2462 for (anExp.Init(aShell, TopAbs_FACE); anExp.More(); anExp.Next()) {
2463 aSewing->Add(anExp.Current());
2466 MESSAGE (" shell for face "<<nbff<<" is created");
2467 const TopoDS_Shape aSewShape = aSewing->SewedShape();
2468 if (aSewShape.ShapeType() == TopAbs_SHELL) {
2469 aShell = TopoDS::Shell(aSewShape);
2470 GProp_GProps aSystem;
2471 BRepGProp::VolumeProperties(aShell, aSystem);
2472 if (aSystem.Mass()<0) {
2473 //cout<<"aSewShape is reversed"<<endl;
2476 if (BRep_Tool::IsClosed(aShell)) {
2477 TopoDS_Solid aSolid;
2478 B.MakeSolid(aSolid);
2479 B.Add(aSolid,aShell);
2480 B.Add(aComp,aSolid);
2481 MESSAGE (" solid for face "<<nbff<<" is created");
2484 B.Add(aComp,aShell);
2485 MESSAGE (" solid for face "<<nbff<<" is not created");
2489 B.Add(aComp,aShell);
2490 MESSAGE (" solid for face "<<nbff<<" is not created");
2493 if (isGenerateGroups) {
2494 Standard_Integer iGrp;
2496 for (iGrp = 0; iGrp < 5; ++iGrp) {
2499 // For each sub-shape of pipe
2500 for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
2501 const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
2503 if (aSewing->IsModifiedSubShape(aGrpShape)) {
2504 // Use the shape modified by sewing.
2505 const TopoDS_Shape &aModifGrpShape =
2506 aSewing->ModifiedSubShape(aGrpShape);
2508 aGroups[iGrp].Append(aModifGrpShape);
2510 // Use the shape as it is.
2511 aGroups[iGrp].Append(aGrpShape);
2519 if (isGenerateGroups) {
2521 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2522 TopTools_IndexedMapOfShape anIndices;
2524 TopExp::MapShapes(aComp, anIndices);
2526 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2527 if (aCI) delete aCI;
2528 Standard_ConstructionError::Raise("Generate groups failure");
2531 StoreGroups(aCI, aGroupIds);
2537 //=======================================================================
2538 //function : CreatePipeBiNormalAlongVector
2539 //purpose : auxilary for Execute()
2540 //=======================================================================
2541 static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
2542 GEOMImpl_IPipe* aCI)
2544 GEOMImpl_IPipeBiNormal* aCIBN = (GEOMImpl_IPipeBiNormal*)aCI;
2546 Handle(GEOM_Function) aRefBase = aCIBN->GetBase();
2547 Handle(GEOM_Function) aRefVec = aCIBN->GetVector();
2548 TopoDS_Shape aShapeBase = aRefBase->GetValue();
2549 TopoDS_Shape aShapeVec = aRefVec->GetValue();
2551 if (aShapeBase.IsNull()) {
2552 if (aCIBN) delete aCIBN;
2553 Standard_NullObject::Raise("MakePipe aborted : null base argument");
2556 // Make copy to prevent modifying of base object: 0021525
2557 BRepBuilderAPI_Copy Copy (aShapeBase);
2559 aShapeBase = Copy.Shape();
2562 if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
2565 else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
2566 aProf = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase)).Shape();
2568 else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
2571 else if (aShapeBase.ShapeType() == TopAbs_FACE) {
2572 TopExp_Explorer wexp (aShapeBase,TopAbs_WIRE);
2573 aProf = wexp.Current();
2576 Standard_TypeMismatch::Raise
2577 ("MakePipe aborted : invalid type of base");
2579 BRepOffsetAPI_MakePipeShell PipeBuilder (aWirePath);
2580 PipeBuilder.Add(aProf);
2582 if (aShapeVec.IsNull()) {
2583 if (aCIBN) delete aCIBN;
2584 Standard_NullObject::Raise
2585 ("MakePipe aborted : null vector argument");
2587 if (aShapeVec.ShapeType() != TopAbs_EDGE)
2588 Standard_TypeMismatch::Raise
2589 ("MakePipe aborted: invalid type of vector");
2590 TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
2591 TopoDS_Vertex V1, V2;
2592 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2593 if (V1.IsNull() || V2.IsNull())
2594 Standard_NullObject::Raise
2595 ("MakePipe aborted: vector is not defined");
2596 gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
2597 gp_Dir BiNormal(aVec);
2598 PipeBuilder.SetMode(BiNormal);
2600 Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
2602 if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
2603 PipeBuilder.MakeSolid();
2606 if (!CreateGroups(PipeBuilder, aCIBN)) {
2607 if (aCIBN) delete aCIBN;
2608 Standard_ConstructionError::Raise("Generate groups failure");
2611 return PipeBuilder.Shape();
2614 //=======================================================================
2615 //function : FillGroups
2616 //purpose : auxilary for DoGroups()
2617 //=======================================================================
2618 bool FillGroups(const TopTools_SequenceOfShape *theGroups,
2619 const TopTools_IndexedMapOfShape &theIndices,
2620 Handle(TColStd_HArray1OfInteger) *theGroupIds)
2624 for (i = 0; i < 5; ++i) {
2625 if (!theGroups[i].IsEmpty()) {
2626 const Standard_Integer aNbShapes = theGroups[i].Length();
2629 theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
2631 for (j = 1; j <= aNbShapes; ++j) {
2632 const TopoDS_Shape &aShape = theGroups[i].Value(j);
2633 const Standard_Integer anIndex = theIndices.FindIndex(aShape);
2639 theGroupIds[i]->SetValue(j, anIndex);
2647 //=======================================================================
2648 //function : StoreGroups
2649 //purpose : auxilary for CreateGroups()
2650 //=======================================================================
2651 void StoreGroups(GEOMImpl_IPipe *theCI,
2652 Handle(TColStd_HArray1OfInteger) *theGroups)
2654 if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
2655 theCI->SetGroupDown(theGroups[GROUP_DOWN]);
2658 if (theGroups[GROUP_UP].IsNull() == Standard_False) {
2659 theCI->SetGroupUp(theGroups[GROUP_UP]);
2662 if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
2663 theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
2666 if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
2667 theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
2670 if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
2671 theCI->SetGroupOther(theGroups[GROUP_OTHER]);
2675 //=======================================================================
2676 //function : CreateDownUpGroups
2677 //purpose : auxilary for DoGroups()
2678 //=======================================================================
2679 static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
2680 TopTools_SequenceOfShape *theGroups,
2681 Standard_Boolean &IsDoSides)
2683 const TopoDS_Shape aDownShape = theSweep->FirstShape();
2684 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2685 TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
2687 IsDoSides = Standard_False;
2692 anUpDownType = TopAbs_EDGE;
2694 if (GEOMUtils::IsOpenPath(aDownShape)) {
2695 IsDoSides = Standard_True;
2700 anUpDownType = TopAbs_FACE;
2706 if (anUpDownType == TopAbs_SHAPE) {
2707 // Invalid Up and Down group type.
2711 TopExp_Explorer anExp(aDownShape, anUpDownType);
2712 TopTools_MapOfShape aMapFence;
2714 // Create Down group.
2715 for (; anExp.More(); anExp.Next()) {
2716 const TopoDS_Shape &aShape = anExp.Current();
2718 if (aMapFence.Add(aShape)) {
2719 theGroups[GROUP_DOWN].Append(aShape);
2724 const TopoDS_Shape anUpShape = theSweep->LastShape();
2727 anExp.Init(anUpShape, anUpDownType);
2729 for (; anExp.More(); anExp.Next()) {
2730 const TopoDS_Shape &aShape = anExp.Current();
2732 if (aMapFence.Add(aShape)) {
2733 theGroups[GROUP_UP].Append(aShape);
2740 //=======================================================================
2741 //function : DoGroups
2742 //purpose : auxilary for CreateGroups()
2743 //=======================================================================
2744 bool DoGroups(BRepOffsetAPI_MakePipeShell &theSweep,
2745 TopTools_SequenceOfShape *theGroups)
2747 Standard_Boolean isDoSides = Standard_False;
2749 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2750 // Up and Down groups creation failure
2754 const TopoDS_Shape aDownShape = theSweep.FirstShape();
2757 // Create Side1 and Side2 groups.
2758 const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
2759 TopoDS_Vertex aV[2];
2762 if (aType == TopAbs_EDGE) {
2763 TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
2764 } else { // aType == TopAbs_WIRE
2765 TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
2768 for (i = 0; i < 2; ++i) {
2769 if (aV[i].IsNull() == Standard_False) {
2770 const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
2772 if (!aLstSide.IsEmpty()) {
2773 TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
2774 TopTools_MapOfShape aMapFence;
2775 const Standard_Integer anIdSide =
2776 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2778 for (; aSideIt.More(); aSideIt.Next()) {
2779 const TopoDS_Shape &aSideShape = aSideIt.Value();
2781 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2782 if (aMapFence.Add(aSideShape)) {
2783 theGroups[anIdSide].Append(aSideShape);
2786 // Only edges can be is Side1 and Side2 groups.
2794 // Create Other group. Get boudnary edges of the profile.
2795 TopTools_MapOfShape aMapBndEdges;
2796 TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
2798 for (; anExp.More(); anExp.Next()) {
2799 const TopoDS_Shape &anEdge = anExp.Current();
2801 if (!aMapBndEdges.Add(anEdge)) {
2802 aMapBndEdges.Remove(anEdge);
2806 // Fill the map of faces generated from profile's boundary edges.
2807 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2808 TopTools_MapOfShape aMapFence;
2810 for (; anIter.More(); anIter.Next()) {
2811 const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
2813 if (!aLstOther.IsEmpty()) {
2814 TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
2816 for (; anOtherIt.More(); anOtherIt.Next()) {
2817 const TopoDS_Shape &anOtherShape = anOtherIt.Value();
2819 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2820 if (aMapFence.Add(anOtherShape)) {
2821 theGroups[GROUP_OTHER].Append(anOtherShape);
2824 // Only faces can be in Other group.
2835 //=======================================================================
2836 //function : CreateGroups
2837 //purpose : auxilary for Execute()
2838 //=======================================================================
2839 bool CreateGroups(BRepOffsetAPI_MakePipeShell &theSweep,
2840 GEOMImpl_IPipe *theCI)
2842 if (!theCI->GetGenerateGroups()) {
2848 TopTools_SequenceOfShape aGroups[5];
2850 if (!DoGroups(theSweep, aGroups)) {
2855 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2856 TopTools_IndexedMapOfShape anIndices;
2857 const TopoDS_Shape aResult = theSweep.Shape();
2859 TopExp::MapShapes(aResult, anIndices);
2861 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2866 StoreGroups(theCI, aGroupIds);
2871 //=======================================================================
2872 //function : DoGroups
2873 //purpose : auxilary for CreateGroups()
2874 //=======================================================================
2875 static bool DoGroups(const TopoDS_Shape &theProfile,
2876 const TopoDS_Shape &thePath,
2877 BRepOffsetAPI_MakePipe &theSweep,
2878 TopTools_SequenceOfShape *theGroups)
2880 Standard_Boolean isDoSides = Standard_False;
2882 if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
2883 // Up and Down groups creation failure
2888 // Create Side1 and Side2 groups.
2889 const TopAbs_ShapeEnum aType = theProfile.ShapeType();
2890 TopoDS_Vertex aV[2];
2893 if (aType == TopAbs_EDGE) {
2894 TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
2895 } else { // aType == TopAbs_WIRE
2896 TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
2899 for (i = 0; i < 2; ++i) {
2900 if (aV[i].IsNull() == Standard_False) {
2901 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2902 TopTools_MapOfShape aMapFence;
2903 const Standard_Integer anIdSide =
2904 (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
2906 for (; anExpP.More(); anExpP.Next()) {
2907 const TopoDS_Shape aSideShape =
2908 theSweep.Generated(anExpP.Current(), aV[i]);
2910 if (aSideShape.ShapeType() == TopAbs_EDGE) {
2911 if (aMapFence.Add(aSideShape)) {
2912 theGroups[anIdSide].Append(aSideShape);
2915 // Only edges can be is Side1 and Side2 groups.
2922 // Create Other group. Get boudnary edges of the profile.
2923 TopTools_MapOfShape aMapBndEdges;
2924 TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
2926 for (; anExp.More(); anExp.Next()) {
2927 const TopoDS_Shape &anEdge = anExp.Current();
2929 if (!aMapBndEdges.Add(anEdge)) {
2930 aMapBndEdges.Remove(anEdge);
2934 TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
2935 TopTools_MapOfShape aMapFence;
2937 for (; anExpP.More(); anExpP.Next()) {
2938 TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
2940 for (; anIter.More(); anIter.Next()) {
2941 const TopoDS_Shape anOtherShape =
2942 theSweep.Generated(anExpP.Current(), anIter.Key());
2944 if (anOtherShape.ShapeType() == TopAbs_FACE) {
2945 if (aMapFence.Add(anOtherShape)) {
2946 theGroups[GROUP_OTHER].Append(anOtherShape);
2949 // Only faces can be in Other group.
2959 //=======================================================================
2960 //function : CreateGroups
2961 //purpose : auxilary for Execute()
2962 //=======================================================================
2963 static bool CreateGroups(const TopoDS_Shape &theProfile,
2964 const TopoDS_Shape &thePath,
2965 BRepOffsetAPI_MakePipe &theSweep,
2966 GEOMImpl_IPipe *theCI)
2968 if (!theCI->GetGenerateGroups()) {
2974 TopTools_SequenceOfShape aGroups[5];
2976 if (!DoGroups(theProfile, thePath, theSweep, aGroups)) {
2981 Handle(TColStd_HArray1OfInteger) aGroupIds[5];
2982 TopTools_IndexedMapOfShape anIndices;
2983 const TopoDS_Shape aResult = theSweep.Shape();
2985 TopExp::MapShapes(aResult, anIndices);
2987 if (!FillGroups(aGroups, anIndices, aGroupIds)) {
2992 StoreGroups(theCI, aGroupIds);
2997 //=======================================================================
2998 //function : Execute
3000 //=======================================================================
3001 Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
3003 if (Label().IsNull()) return 0;
3004 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
3005 Standard_Integer aType = aFunction->GetType();
3007 GEOMImpl_IPipe* aCI = 0;
3008 if (aType == PIPE_BASE_PATH)
3009 aCI = new GEOMImpl_IPipe (aFunction);
3010 else if (aType == PIPE_DIFFERENT_SECTIONS)
3011 aCI = new GEOMImpl_IPipeDiffSect (aFunction);
3012 else if (aType == PIPE_SHELL_SECTIONS)
3013 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3014 else if (aType == PIPE_SHELLS_WITHOUT_PATH)
3015 aCI = new GEOMImpl_IPipeShellSect (aFunction);
3016 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR)
3017 aCI = new GEOMImpl_IPipeBiNormal (aFunction);
3021 TopoDS_Wire aWirePath;
3022 if (aType != PIPE_SHELLS_WITHOUT_PATH) {
3023 // working with path
3024 Handle(GEOM_Function) aRefPath = aCI->GetPath();
3025 TopoDS_Shape aShapePath = aRefPath->GetValue();
3027 if (aShapePath.IsNull()) {
3028 MESSAGE ("Driver : path is null");
3029 if (aCI) delete aCI;
3030 Standard_NullObject::Raise("MakePipe aborted : null path argument");
3035 if (aShapePath.ShapeType() == TopAbs_COMPOUND) {
3036 TopTools_SequenceOfShape anEdges;
3037 TopExp_Explorer anExp;
3041 for (anExp.Init(aShapePath, TopAbs_EDGE); anExp.More(); anExp.Next()) {
3042 B.Add(W, anExp.Current());
3048 else if (aShapePath.ShapeType() == TopAbs_WIRE) {
3049 aWirePath = TopoDS::Wire(aShapePath);
3053 if (aShapePath.ShapeType() == TopAbs_EDGE) {
3054 TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
3055 aWirePath = BRepBuilderAPI_MakeWire(anEdge);
3060 if (aCI) delete aCI;
3061 Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
3064 // Check if it is possible to create groups.
3065 if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
3070 Standard_ConstructionError::Raise
3071 ("Can't create groups if the path is closed");
3075 TopoDS_Shape aShape;
3076 const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
3078 if (aType == PIPE_BASE_PATH) {
3079 Handle(GEOM_Function) aRefBase = aCI->GetBase();
3080 TopoDS_Shape aShapeBase;
3082 // Make copy to prevent modifying of base object 0020766 : EDF 1320
3083 BRepBuilderAPI_Copy Copy(aRefBase->GetValue());
3085 aShapeBase = Copy.Shape();
3087 if (aShapeBase.IsNull()) {
3088 if (aCI) delete aCI;
3089 Standard_NullObject::Raise("MakePipe aborted : null base argument");
3093 if (aShapeBase.ShapeType() == TopAbs_EDGE ||
3094 aShapeBase.ShapeType() == TopAbs_WIRE)
3096 TopoDS_Wire Profile;
3097 if (aShapeBase.ShapeType() == TopAbs_WIRE)
3098 Profile = TopoDS::Wire(aShapeBase);
3102 BB.MakeWire(Profile);
3103 BB.Add(Profile, aShapeBase);
3106 BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
3107 BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
3108 if (FaceBuilder.IsDone())
3109 Sweep.SetMode(FaceBuilder.Face());
3112 Standard_Boolean isDone = BuildPipeShell(Sweep);
3116 if (aCI) delete aCI;
3117 Standard_ConstructionError::Raise("MakePipeShell failed");
3120 aShape = Sweep.Shape(); //result is good
3122 if (!CreateGroups(Sweep, aCI)) {
3123 if (aCI) delete aCI;
3124 Standard_ConstructionError::Raise("Generate groups failure");
3129 GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
3130 BRepOffsetAPI_MakePipe aMkPipe
3131 (aWirePath, aShapeBase, theBestMode, Standard_True);
3133 if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) {
3134 aShape = aMkPipe.Shape();
3136 if (!CreateGroups(aShapeBase, aWirePath, aMkPipe, aCI)) {
3137 if (aCI) delete aCI;
3138 Standard_ConstructionError::Raise("Generate groups failure");
3140 } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
3141 // Try to use Descrete Trihedron mode.
3142 BRepOffsetAPI_MakePipe aMkPipeDescrete
3143 (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron, Standard_True);
3145 if (aMkPipeDescrete.IsDone()) {
3146 aShape = aMkPipeDescrete.Shape();
3148 if (!CreateGroups(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
3149 if (aCI) delete aCI;
3150 Standard_ConstructionError::Raise("Generate groups failure");
3157 //building pipe with different sections
3158 else if (aType == PIPE_DIFFERENT_SECTIONS) {
3159 GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
3160 Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases ();
3161 Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
3162 Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
3163 Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
3164 Standard_Boolean isBySteps = aCIDS->GetIsBySteps();
3171 Standard_Integer nbBases = aBasesObjs->Length();
3172 Standard_Integer nbLocs = (aLocObjs.IsNull() ? 0 : aLocObjs->Length());
3174 Handle(TopTools_HSequenceOfShape) aHSeqBases = new TopTools_HSequenceOfShape;
3175 Handle(TopTools_HSequenceOfShape) aHSeqLocs = new TopTools_HSequenceOfShape;
3178 for (i = 1; i <= nbBases; i++) {
3179 Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
3180 if (anItem.IsNull())
3182 Handle(GEOM_Function) aRefBase = Handle(GEOM_Function)::DownCast(anItem);
3183 if (aRefBase.IsNull())
3185 if (aRefBase->GetValue().IsNull())
3188 aHSeqBases->Append(aRefBase->GetValue());
3190 for (i = 1; i <= nbLocs; i++) {
3191 Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
3192 if (anItemLoc.IsNull())
3194 Handle(GEOM_Function) aRefLoc = Handle(GEOM_Function)::DownCast(anItemLoc);
3195 TopoDS_Shape aShapeLoc = aRefLoc->GetValue();
3196 if (aShapeLoc.IsNull() || aShapeLoc.ShapeType() != TopAbs_VERTEX)
3199 aHSeqLocs->Append(aShapeLoc);
3203 Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
3204 Handle(TColStd_HArray1OfInteger) aGroups[5];
3206 if (isGenerateGroups) {
3210 aShape = CreatePipeWithDifferentSections
3211 (aWirePath, aHSeqBases, aHSeqLocs,
3212 aWithContact, aWithCorrect, isBySteps, pGroups);
3214 if (isGenerateGroups) {
3215 // Store created groups.
3216 GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
3218 StoreGroups(&aPipeDS, aGroups);
3222 //building pipe with shell sections
3223 else if (aType == PIPE_SHELL_SECTIONS) {
3224 aShape = CreatePipeForShellSections(aWirePath,aCI);
3227 //building pipe shell sections without path
3228 else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
3229 aShape = CreatePipeShellsWithoutPath(aCI);
3232 //building a pipe with constant bi-normal along given vector
3233 else if (aType == PIPE_BI_NORMAL_ALONG_VECTOR) {
3234 aShape = CreatePipeBiNormalAlongVector(aWirePath, aCI);
3242 if (aShape.IsNull()) return 0;
3244 if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
3245 Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
3247 if (aType != PIPE_BASE_PATH &&
3248 aType != PIPE_SHELLS_WITHOUT_PATH) {
3249 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX);
3250 if (anExpV.More()) {
3251 Standard_Real aVertMaxTol = -RealLast();
3252 for (; anExpV.More(); anExpV.Next()) {
3253 TopoDS_Vertex aVertex = TopoDS::Vertex(anExpV.Current());
3254 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
3255 if (aTol > aVertMaxTol)
3258 aVertMaxTol += Precision::Confusion();
3260 TopTools_DataMapOfShapeListOfShape aMapModif;
3261 TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
3263 if (isGenerateGroups) {
3264 pMapModif = &aMapModif;
3267 TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
3268 (aShape, aVertMaxTol, Standard_True, pMapModif);
3270 if (isGenerateGroups && !aMapModif.IsEmpty()) {
3272 GEOMImpl_IPipe aCI(aFunction);
3273 Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
3274 { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
3275 aCI.GetGroupSide2(), aCI.GetGroupOther() };
3276 TopTools_IndexedMapOfShape anIndices;
3277 TopTools_IndexedMapOfShape aNewIndices;
3278 TopTools_SequenceOfShape aNewShapes[5];
3279 TopTools_MapOfShape aMapReplaced;
3280 TopTools_MapOfShape aMapGlued;
3281 Standard_Integer iGrp;
3284 TopExp::MapShapes(aShape, anIndices);
3285 TopExp::MapShapes(aNewShape, aNewIndices);
3287 for (iGrp = 0; iGrp < 5; ++iGrp) {
3288 if (aGroupIDs[iGrp].IsNull() == Standard_False) {
3289 const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
3290 const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
3292 for (i = aLower; i <= anUpper; ++i) {
3293 const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
3294 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
3296 if (aMapModif.IsBound(aSubShape)) {
3297 const TopTools_ListOfShape &aListModif =
3298 aMapModif.Find(aSubShape);
3299 TopTools_ListIteratorOfListOfShape anIter(aListModif);
3301 for (; anIter.More(); anIter.Next()) {
3302 const TopoDS_Shape &aNewShape = anIter.Value();
3304 if (aMapReplaced.Add(aNewShape)) {
3305 aNewShapes[iGrp].Append(aNewShape);
3307 // This is a glued shape. It means that it is internal
3308 // one and should be removed from groups later.
3309 aMapGlued.Add(aNewShape);
3313 // Shape is not modified.
3314 aNewShapes[iGrp].Append(aSubShape);
3320 if (!aMapGlued.IsEmpty()) {
3321 // Remove glued (internal) shapes from groups.
3322 for (iGrp = 0; iGrp < 5; ++iGrp) {
3323 Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
3325 for (i = 1; i < aNbShapes; ++i) {
3326 const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
3328 if (aMapGlued.Contains(aNewShape)) {
3329 aNewShapes[iGrp].Remove(i);
3337 // Store modified groups.
3338 Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
3340 if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
3341 Standard_ConstructionError::Raise("Generate groups failure");
3344 StoreGroups(&aCI, aNewGroupIDs);
3351 // Note: group indices should not be changed after the next call.
3352 TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
3353 aFunction->SetValue(aRes);
3355 log.SetTouched(Label());
3359 //================================================================================
3361 * \brief Returns a name of creation operation and names and values of creation parameters
3363 //================================================================================
3365 bool GEOMImpl_PipeDriver::
3366 GetCreationInformation(std::string& theOperationName,
3367 std::vector<GEOM_Param>& theParams)
3369 if (Label().IsNull()) return 0;
3370 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
3371 Standard_Integer aType = function->GetType();
3374 case PIPE_BASE_PATH:
3376 theOperationName = "PIPE";
3377 GEOMImpl_IPipe aCI( function );
3378 AddParam( theParams, "Base Object", aCI.GetBase() );
3379 AddParam( theParams, "Path Object", aCI.GetPath() );
3382 case PIPE_BI_NORMAL_ALONG_VECTOR:
3384 theOperationName = "PIPE";
3385 GEOMImpl_IPipeBiNormal aCI( function );
3386 AddParam( theParams, "Base Object", aCI.GetBase() );
3387 AddParam( theParams, "Path Object", aCI.GetPath() );
3388 AddParam( theParams, "BiNormal", aCI.GetVector() );
3391 case PIPE_DIFFERENT_SECTIONS:
3393 theOperationName = "PIPE";
3394 GEOMImpl_IPipeDiffSect aCI( function );
3395 AddParam( theParams, "Bases", aCI.GetBases() );
3396 AddParam( theParams, "Locations", aCI.GetLocations() );
3397 AddParam( theParams, "Path", aCI.GetPath() );
3399 if (!aCI.GetIsBySteps()) {
3400 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3401 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3404 AddParam( theParams, "Step by step", aCI.GetIsBySteps() );
3407 case PIPE_SHELL_SECTIONS:
3409 theOperationName = "PIPE";
3410 GEOMImpl_IPipeShellSect aCI( function );
3411 AddParam( theParams, "Bases", aCI.GetBases() );
3412 AddParam( theParams, "Sub-Bases", aCI.GetSubBases() );
3413 AddParam( theParams, "Locations", aCI.GetLocations() );
3414 AddParam( theParams, "Path", aCI.GetPath() );
3415 AddParam( theParams, "With contact", aCI.GetWithContactMode() );
3416 AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
3419 case PIPE_SHELLS_WITHOUT_PATH:
3421 theOperationName = "PIPE"; // MakePipeShellsWithoutPath
3422 GEOMImpl_IPipeShellSect aCI( function );
3423 AddParam( theParams, "Bases", aCI.GetBases() );
3424 AddParam( theParams, "Locations", aCI.GetLocations() );
3434 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
3435 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);